github.com/whyrusleeping/gx@v0.14.3/repo.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"sort"
     8  	"text/tabwriter"
     9  
    10  	hd "github.com/mitchellh/go-homedir"
    11  	cli "github.com/urfave/cli"
    12  	gx "github.com/whyrusleeping/gx/gxutil"
    13  	. "github.com/whyrusleeping/stump"
    14  )
    15  
    16  func cfgPath(global bool) (string, error) {
    17  	if global {
    18  		home, err := hd.Dir()
    19  		if err != nil {
    20  			return "", fmt.Errorf("$HOME not set, cannot find global .gxrc")
    21  		}
    22  		return filepath.Join(home, gx.CfgFileName), nil
    23  	}
    24  
    25  	cwd, err := os.Getwd()
    26  	if err != nil {
    27  		return "", err
    28  	}
    29  	return filepath.Join(cwd, gx.CfgFileName), nil
    30  }
    31  
    32  var RepoCommand = cli.Command{
    33  	Name:  "repo",
    34  	Usage: "manage set of tracked repositories",
    35  	Subcommands: []cli.Command{
    36  		RepoAddCommand,
    37  		RepoRmCommand,
    38  		RepoListCommand,
    39  		RepoQueryCommand,
    40  		RepoUpdateCommand,
    41  	},
    42  }
    43  
    44  var RepoAddCommand = cli.Command{
    45  	Name:  "add",
    46  	Usage: "add a naming repository",
    47  	Flags: []cli.Flag{
    48  		cli.BoolFlag{
    49  			Name:  "global",
    50  			Usage: "add repository to global set",
    51  		},
    52  	},
    53  	Action: func(c *cli.Context) error {
    54  		global := c.Bool("global")
    55  		cfp, err := cfgPath(global)
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		cfg, err := gx.LoadConfigFrom(cfp)
    61  		if err != nil {
    62  			return err
    63  		}
    64  
    65  		if len(c.Args()) != 2 {
    66  			Fatal("Must specify name and repo-path")
    67  		}
    68  		name := c.Args()[0]
    69  		rpath := c.Args()[1]
    70  
    71  		// make sure we can fetch it
    72  		_, err = pm.FetchRepo(rpath, false)
    73  		if err != nil {
    74  			return fmt.Errorf("finding repo: %s", err)
    75  		}
    76  
    77  		if global {
    78  			cfg.Repos[name] = rpath
    79  		} else {
    80  			cfg.ExtraRepos[name] = rpath
    81  		}
    82  
    83  		return gx.WriteConfig(cfg, cfp)
    84  	},
    85  }
    86  
    87  var RepoRmCommand = cli.Command{
    88  	Name:  "rm",
    89  	Usage: "remove a repo from tracking",
    90  	Flags: []cli.Flag{
    91  		cli.BoolFlag{
    92  			Name:  "global",
    93  			Usage: "remove repository from global set",
    94  		},
    95  	},
    96  	Action: func(c *cli.Context) error {
    97  		global := c.Bool("global")
    98  		cfp, err := cfgPath(global)
    99  		if err != nil {
   100  			return err
   101  		}
   102  
   103  		cfg, err := gx.LoadConfigFrom(cfp)
   104  		if err != nil {
   105  			return err
   106  		}
   107  
   108  		if !c.Args().Present() {
   109  			return fmt.Errorf("specify repo to remove")
   110  		}
   111  		name := c.Args().First()
   112  
   113  		if global {
   114  			if _, ok := cfg.Repos[name]; !ok {
   115  				return fmt.Errorf("no repo named %s", name)
   116  			}
   117  			delete(cfg.Repos, name)
   118  		} else {
   119  			if _, ok := cfg.ExtraRepos[name]; !ok {
   120  				return fmt.Errorf("no repo named %s", name)
   121  			}
   122  			delete(cfg.ExtraRepos, name)
   123  		}
   124  
   125  		return gx.WriteConfig(cfg, cfp)
   126  	},
   127  }
   128  
   129  var RepoListCommand = cli.Command{
   130  	Name:  "list",
   131  	Usage: "list tracked repos or packages in a repo",
   132  	Action: func(c *cli.Context) error {
   133  		cfg, err := gx.LoadConfig()
   134  		if err != nil {
   135  			return err
   136  		}
   137  
   138  		if !c.Args().Present() {
   139  			tabPrintSortedMap(nil, cfg.GetRepos())
   140  			return nil
   141  		}
   142  
   143  		rname := c.Args().First()
   144  		r, ok := cfg.GetRepos()[rname]
   145  		if !ok {
   146  			return fmt.Errorf("no such repo: %s", rname)
   147  		}
   148  
   149  		repo, err := pm.FetchRepo(r, true)
   150  		if err != nil {
   151  			return err
   152  		}
   153  
   154  		tabPrintSortedMap(nil, repo)
   155  		return nil
   156  	},
   157  }
   158  
   159  func tabPrintSortedMap(headers []string, m map[string]string) {
   160  	var names []string
   161  	for k := range m {
   162  		names = append(names, k)
   163  	}
   164  
   165  	sort.Strings(names)
   166  
   167  	w := tabwriter.NewWriter(os.Stdout, 12, 4, 1, ' ', 0)
   168  	if headers != nil {
   169  		fmt.Fprintf(w, "%s\t%s\n", headers[0], headers[1])
   170  	}
   171  
   172  	for _, n := range names {
   173  		fmt.Fprintf(w, "%s\t%s\n", n, m[n])
   174  	}
   175  	w.Flush()
   176  }
   177  
   178  var RepoQueryCommand = cli.Command{
   179  	Name:  "query",
   180  	Usage: "search for a package in repos",
   181  	Action: func(c *cli.Context) error {
   182  		if !c.Args().Present() {
   183  			return fmt.Errorf("must specify search criteria")
   184  		}
   185  
   186  		searcharg := c.Args().First()
   187  
   188  		out, err := pm.QueryRepos(searcharg)
   189  		if err != nil {
   190  			return err
   191  		}
   192  
   193  		if len(out) > 0 {
   194  			tabPrintSortedMap([]string{"repo", "ref"}, out)
   195  		} else {
   196  			return fmt.Errorf("not found")
   197  		}
   198  		return nil
   199  	},
   200  }
   201  
   202  var RepoUpdateCommand = cli.Command{
   203  	Name:  "update",
   204  	Usage: "update cached versions of repos",
   205  	Action: func(c *cli.Context) error {
   206  		cfg, err := gx.LoadConfig()
   207  		if err != nil {
   208  			return err
   209  		}
   210  		repos := cfg.GetRepos()
   211  
   212  		var args []string
   213  		if c.Args().Present() {
   214  			args = c.Args()
   215  		} else {
   216  			for k := range repos {
   217  				args = append(args, k)
   218  			}
   219  		}
   220  
   221  		for _, r := range args {
   222  			path, ok := repos[r]
   223  			if !ok {
   224  				return fmt.Errorf("unknown repo: %s", r)
   225  			}
   226  
   227  			val, ok, err := gx.CheckCacheFile(path)
   228  			if err != nil {
   229  				return fmt.Errorf("checking cache: %s", err)
   230  			}
   231  
   232  			nval, err := pm.ResolveRepoName(path, false)
   233  			if err != nil {
   234  				return fmt.Errorf("resolving repo: %s", err)
   235  			}
   236  
   237  			if ok {
   238  				if nval == val {
   239  					Log("%s: up to date", r)
   240  				} else {
   241  					Log("%s: updated from %s to %s", r, val, nval)
   242  				}
   243  			} else if !ok {
   244  				Log("%s: %s", r, nval)
   245  			}
   246  		}
   247  		return nil
   248  	},
   249  }