From 63c43c96d3c10c9327d6585ad611d0d31284c11a Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 2 Oct 2019 13:05:09 -0700 Subject: [PATCH] cmdget: accept package paths Fixes #62 --- cmdget.go | 40 +++++++++++++++++++++++++++++++++++----- testdata/help.txt | 4 ++-- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/cmdget.go b/cmdget.go index b922079..8473f1c 100644 --- a/cmdget.go +++ b/cmdget.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "sort" "strings" "gopkg.in/errgo.v2/fmt/errors" @@ -14,11 +15,13 @@ import ( ) var getCommand = &Command{ - UsageLine: "get [-vcs] [-u] [-f] [module...]", + UsageLine: "get [-vcs] [-u] [-f] [module/package...]", Short: "start hacking a module", Long: ` The get command checks out Go module dependencies into a directory where they can be edited. +If a package is named, its containing module +is checked out. It uses $GOHACK/ as the destination directory, or $HOME/gohack/ if $GOHACK is empty. @@ -61,12 +64,39 @@ func runGet1(args []string) error { // Perhaps we should be more resilient in that case? return errors.Notef(err, nil, "cannot get module info") } - for _, mpath := range args { - m := mods[mpath] - if m == nil { - errorf("module %q does not appear to be in use", mpath) + // Args could be package paths or modules. + // Resolve them all to modules, deduplicate, and sort. + resolved := make(map[string]bool) + for _, arg := range args { + if _, ok := mods[arg]; ok { + // module in use + resolved[arg] = true continue } + // Either a package path, or an unused module. + // Try to resolve as a package path. + out, err := runCmd(cwd, "go", "list", "-f", "{{with .Module}}{{.Path}}{{end}}", arg) + if err == nil { + // Resolved to a module. Is it in use? + out = strings.TrimSpace(out) + if _, ok := mods[out]; ok { + resolved[out] = true + continue + } + } + // Either an unused module, or an invalid package path, + // or a valid package path that resolves to an unused module, + // or something else. + errorf("module/package %q does not appear to be in use", arg) + } + mpaths := make([]string, 0, len(resolved)) + for mpath := range resolved { + mpaths = append(mpaths, mpath) + } + sort.Strings(mpaths) + + for _, mpath := range mpaths { + m := mods[mpath] // must be present, by construction (above) // Early check that we can replace the module, so we don't // do all the work to check it out only to find we can't // add the replace directive. diff --git a/testdata/help.txt b/testdata/help.txt index d9fb4c8..9ee51d6 100644 --- a/testdata/help.txt +++ b/testdata/help.txt @@ -1,8 +1,8 @@ # --help flag produces output to stderr and fails ! gohack get --help -stderr '^usage: get \[-vcs] \[-u] \[-f] \[module...]\nRun ''gohack help get'' for details.\n' +stderr '^usage: get \[-vcs] \[-u] \[-f] \[module/package...]\nRun ''gohack help get'' for details.\n' ! stdout .+ gohack help get -stdout '^usage: get \[-vcs] \[-u] \[-f] \[module...]$' +stdout '^usage: get \[-vcs] \[-u] \[-f] \[module/package...]$' ! stderr .+