gpm/cmd/get.go

114 lines
2.1 KiB
Go

package cmd
import (
"encoding/json"
"fmt"
"io/ioutil"
"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 := ioutil.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()
}