From d8dfaf29e6bec228f299cb8b8d14c6cd7726418d Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 15 Jun 2019 18:29:19 -0400 Subject: [PATCH] recently used skill --- dir.go | 56 ++++++++++++++++++++++------------ info_map.go | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ module.go | 10 +++--- 3 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 info_map.go diff --git a/dir.go b/dir.go index 5578363..777af73 100644 --- a/dir.go +++ b/dir.go @@ -2,43 +2,59 @@ package here import ( "encoding/json" + "fmt" "os" "path/filepath" ) +var dirCache = &infoMap{} + // Dir attempts to gather info for the requested directory. func Dir(p string) (Info, error) { - i := newInfo() + var err error + i, ok := dirCache.LoadOr(p, func(m *infoMap) (Info, bool) { + i := newInfo() - fi, err := os.Stat(p) - if err != nil { - return i, err - } + fi, err := os.Stat(p) + if err != nil { + return i, false + } - if !fi.IsDir() { - p = filepath.Dir(p) - } + if !fi.IsDir() { + p = filepath.Dir(p) + } - pwd, err := os.Getwd() - if err != nil { - return i, err - } + pwd, err := os.Getwd() + if err != nil { + return i, false + } + + defer os.Chdir(pwd) + + os.Chdir(p) + + b, err := run("go", "list", "-json") + if err != nil { + return i, false + } - defer os.Chdir(pwd) + if err := json.Unmarshal(b, &i); err != nil { + return i, false + } - os.Chdir(p) + if err := setEnv(&i); err != nil { + return i, false + } + return i, true + }) - b, err := run("go", "list", "-json") if err != nil { return i, err } - if err := json.Unmarshal(b, &i); err != nil { - return i, err + if !ok { + return i, fmt.Errorf("an error occurred %s", p) } - if err := setEnv(&i); err != nil { - return i, err - } return i, nil } diff --git a/info_map.go b/info_map.go new file mode 100644 index 0000000..b3f2ef6 --- /dev/null +++ b/info_map.go @@ -0,0 +1,87 @@ +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package here + +import ( + "sort" + "sync" +) + +// infoMap wraps sync.Map and uses the following types: +// key: string +// value: Info +type infoMap struct { + data sync.Map +} + +// Delete the key from the map +func (m *infoMap) Delete(key string) { + m.data.Delete(key) +} + +// Load the key from the map. +// Returns Info or bool. +// A false return indicates either the key was not found +// or the value is not of type Info +func (m *infoMap) Load(key string) (Info, bool) { + i, ok := m.data.Load(key) + if !ok { + return Info{}, false + } + s, ok := i.(Info) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *infoMap) LoadOrStore(key string, value Info) (Info, bool) { + i, _ := m.data.LoadOrStore(key, value) + s, ok := i.(Info) + return s, ok +} + +// LoadOr will return an existing key or +// run the function and store the results +func (m *infoMap) LoadOr(key string, fn func(*infoMap) (Info, bool)) (Info, bool) { + i, ok := m.Load(key) + if ok { + return i, ok + } + i, ok = fn(m) + if ok { + m.Store(key, i) + return i, ok + } + return i, false +} + +// Range over the Info values in the map +func (m *infoMap) Range(f func(key string, value Info) bool) { + m.data.Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(Info) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a Info in the map +func (m *infoMap) Store(key string, value Info) { + m.data.Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *infoMap) Keys() []string { + var keys []string + m.Range(func(key string, value Info) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/module.go b/module.go index 7e70365..50be1eb 100644 --- a/module.go +++ b/module.go @@ -3,11 +3,11 @@ package here import "encoding/json" type Module struct { - Path string `json:"Path"` - Main bool `json:"Main"` - Dir string `json:"Dir"` - GoMod string `json:"GoMod"` - GoVersion string `json:"GoVersion"` + Path string `json:"Path"` + Main bool `json:"Main"` + Dir string `json:"Dir"` + GoMod string `json:"GoMod"` + GoVersion string `json:"GoVersion"` } func (i Module) String() string {