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 }