package cmd import ( "encoding/json" "fmt" "io" "net/http" "os" "os/exec" "strings" "go.jolheiser.com/gpm/config" "github.com/AlecAivazis/survey/v2" "github.com/urfave/cli/v2" "go.jolheiser.com/beaver" ) var Get = cli.Command{ Name: "get", Usage: "Get package(s)", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "ignore-local", Usage: "Ignore local packages", }, &cli.BoolFlag{ Name: "offline", Usage: "Offline mode, return error instead of querying server", }, }, Action: doGet, } func doGet(ctx *cli.Context) error { cfg, err := config.Load() if err != nil { return err } pkgs := ctx.Args().Slice() if len(pkgs) == 0 { pkgsQuestion := &survey.Multiline{ Message: "Enter packages to get, one for each line", } var pkgsAnswer string if err := survey.AskOne(pkgsQuestion, &pkgsAnswer); err != nil { return err } pkgs = strings.Split(pkgsAnswer, "\n") } local := cfg.Packages.Map() for _, pkg := range pkgs { var url string if u, ok := local[pkg]; ok && !ctx.Bool("ignore-local") { url = u.Import } else if !ctx.Bool("offline") { u, err := queryServer(ctx.String("url"), pkg) if err != nil { beaver.Error(err) continue } url = u } if url == "" { beaver.Errorf("no package found for `%s`", pkg) continue } beaver.Infof("getting `%s`...", pkg) if err := goGet(url); err != nil { beaver.Error(err) } } return nil } func queryServer(server, name string) (string, error) { endpoint := fmt.Sprintf("%s/package/%s", server, name) resp, err := http.Get(endpoint) if err != nil { return "", fmt.Errorf("could not query server at `%s`", endpoint) } if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("could not find server package for `%s`", name) } body, err := io.ReadAll(resp.Body) if err != nil { return "", err } defer resp.Body.Close() var pkg config.Package if err := json.Unmarshal(body, &pkg); err != nil { return "", err } return pkg.Import, nil } func goGet(url string) error { cmd := exec.Command("go", "get", url) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }