github.com/whyrusleeping/gx@v0.14.3/gxutil/repo.go (about) 1 package gxutil 2 3 import ( 4 "encoding/json" 5 "errors" 6 "os" 7 "path/filepath" 8 "strings" 9 10 hd "github.com/mitchellh/go-homedir" 11 . "github.com/whyrusleeping/stump" 12 ) 13 14 func (pm *PM) FetchRepo(rpath string, usecache bool) (map[string]string, error) { 15 if strings.HasPrefix(rpath, "/ipns/") { 16 p, err := pm.ResolveRepoName(rpath, usecache) 17 if err != nil { 18 return nil, err 19 } 20 21 rpath = p 22 } 23 links, err := pm.Shell().List(rpath) 24 if err != nil { 25 return nil, err 26 } 27 28 out := make(map[string]string) 29 for _, l := range links { 30 out[l.Name] = l.Hash 31 } 32 33 return out, nil 34 } 35 36 var ErrNotFound = errors.New("cache miss") 37 38 // TODO: once on ipfs 0.4.0, use the files api 39 func (pm *PM) ResolveRepoName(name string, usecache bool) (string, error) { 40 if usecache { 41 cache, ok, err := CheckCacheFile(name) 42 if err != nil { 43 return "", err 44 } 45 46 if ok { 47 return cache, nil 48 } 49 } 50 51 out, err := pm.Shell().ResolvePath(name) 52 if err != nil { 53 Error("error from resolve path", name) 54 return "", err 55 } 56 57 err = pm.cacheSet(name, out) 58 if err != nil { 59 return "", err 60 } 61 62 return out, nil 63 } 64 65 func CheckCacheFile(name string) (string, bool, error) { 66 home, err := hd.Dir() 67 if err != nil { 68 return "", false, err 69 } 70 p := filepath.Join(home, ".gxcache") 71 72 fi, err := os.Open(p) 73 if err != nil { 74 if !os.IsNotExist(err) { 75 return "", false, err 76 } 77 } 78 defer fi.Close() 79 80 cache := make(map[string]string) 81 err = json.NewDecoder(fi).Decode(&cache) 82 if err != nil { 83 return "", false, err 84 } 85 86 v, ok := cache[name] 87 if ok { 88 return v, true, nil 89 } 90 return "", false, nil 91 } 92 93 // TODO: think about moving gx global files into a .config/local type thing 94 func (pm *PM) cacheSet(name, resolved string) error { 95 home, err := hd.Dir() 96 if err != nil { 97 return err 98 } 99 p := filepath.Join(home, ".gxcache") 100 101 _, err = os.Stat(p) 102 if err != nil { 103 if !os.IsNotExist(err) { 104 return err 105 } 106 } 107 108 cache := make(map[string]string) 109 if err == nil { // if the file already exists 110 fi, err := os.Open(p) 111 if err != nil { 112 return err 113 } 114 115 err = json.NewDecoder(fi).Decode(&cache) 116 if err != nil { 117 return err 118 } 119 120 fi.Close() 121 } 122 123 cache[name] = resolved 124 125 fi, err := os.Create(p) 126 if err != nil { 127 return err 128 } 129 130 err = json.NewEncoder(fi).Encode(cache) 131 if err != nil { 132 return err 133 } 134 135 return fi.Close() 136 } 137 138 func (pm *PM) QueryRepos(query string) (map[string]string, error) { 139 out := make(map[string]string) 140 for name, rpath := range pm.cfg.GetRepos() { 141 repo, err := pm.FetchRepo(rpath, true) 142 if err != nil { 143 return nil, err 144 } 145 146 if val, ok := repo[query]; ok { 147 out[name] = val 148 } 149 } 150 151 return out, nil 152 }