]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: fix go get -u wildcard corner case
authorDmitriy Dudkin <dudkin.dmitriy@gmail.com>
Thu, 25 Feb 2016 02:00:01 +0000 (04:00 +0200)
committerRuss Cox <rsc@golang.org>
Wed, 5 Oct 2016 23:53:29 +0000 (23:53 +0000)
Suppose you have already downloaded "foo.bar/baz", where the repo
is for all of foo.bar/, and you then "go get -u foo.bar/...".
The command-line wildcard expands to foo.bar/baz,
and go get updates the foo.bar/ repo.
Suppose that the repo update brought in foo.bar/quux,
though, which depends on other.site/bar.
Download does not consider foo.bar/quux, since it's
only looking at foo.bar/baz, so it didn't download other.site/bar.
After the download, we call importPaths(args) to decide what to install.
That call was reevaluating the original wildcard with the new repo
and matching foo.bar/quux, which was missing its dependency
other.site/bar, causing a build failure.

The fix in this CL is to remember the pre-download expansion
of the argument list and pass it to the installer. Then only the things
we tried to download get installed.

The case where foo.bar/ is not even checked out yet continues to work,
because in that case we leave the wildcard in place, and download
reevaluates it during the download.

The fix in this CL may not be the right long-term fix, but it is at least a fix.
It may be that download should be passed all the original wildcards
so that it can reexpand them as new code is downloaded, ideally reaching
a fixed point. That can be left for another day.

In short:

- The problem is that the "install" half of "go get" was trying to install
  more than the "download" half was properly downloading.
- The fix in this CL is to install just what was downloaded (install less).
- It may be that a future CL should instead download what will be installed (download more).

Fixes #14450.

Change-Id: Ia1984761d24439549b7cff322bc0dbc262c1a653
Reviewed-on: https://go-review.googlesource.com/19892
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/go/get.go
src/cmd/go/go_test.go

index 572a8654488d44d1afe24a960f99b4920a6b9f02..01b4e015d2929523a277bee177b0335d729c4d52 100644 (file)
@@ -104,7 +104,8 @@ func runGet(cmd *Command, args []string) {
        if *getT {
                mode |= getTestDeps
        }
-       for _, arg := range downloadPaths(args) {
+       args = downloadPaths(args)
+       for _, arg := range args {
                download(arg, nil, &stk, mode)
        }
        exitIfErrors()
index 2fda20ce03bfe774e8caf316945a18114a0634a7..4839b9bcbbe4da326b00e2d8819d52344eed0d0b 100644 (file)
@@ -2965,3 +2965,30 @@ func TestGenerateUsesBuildContext(t *testing.T) {
        tg.run("generate", "gen")
        tg.grepStdout("darwin 386", "unexpected GOOS/GOARCH combination")
 }
+
+// Issue 14450: go get -u .../ tried to import not downloaded package
+func TestGoGetUpdateWithWildcard(t *testing.T) {
+       testenv.MustHaveExternalNetwork(t)
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.makeTempdir()
+       tg.setenv("GOPATH", tg.path("."))
+       const aPkgImportPath = "github.com/tmwh/go-get-issue-14450/a"
+       tg.run("get", aPkgImportPath)
+       tg.run("get", "-u", ".../")
+       tg.grepStderrNot("cannot find package", "did not update packages given wildcard path")
+
+       var expectedPkgPaths = []string{
+               "src/github.com/tmwh/go-get-issue-14450/b",
+               "src/github.com/tmwh/go-get-issue-14450-b-dependency/c",
+               "src/github.com/tmwh/go-get-issue-14450-b-dependency/d",
+       }
+
+       for _, importPath := range expectedPkgPaths {
+               _, err := os.Stat(tg.path(importPath))
+               tg.must(err)
+       }
+       const notExpectedPkgPath = "src/github.com/tmwh/go-get-issue-14450-c-dependency/e"
+       tg.mustNotExist(tg.path(notExpectedPkgPath))
+}