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  }