From: Russ Cox Date: Wed, 18 Apr 2018 20:34:45 +0000 (-0400) Subject: [release-branch.go1.10] cmd/go: fix go list .Stale computation X-Git-Tag: go1.10.2~6 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=11d7a5a950a7189855bd98caf3083c9ea3d77beb;p=gostls13.git [release-branch.go1.10] cmd/go: fix go list .Stale computation If X depends on Y and X was installed but Y is only present in the cache (as happens when you "go install X") then we should report X as up-to-date, not as stale. This applies whether X is a package or a main binary. Fixes golang/go#25026 Fixes golang/go#25032 Change-Id: I26a0b375b1f7f7ac909cc0db68e92f4e04529208 Reviewed-on: https://go-review.googlesource.com/107957 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills (cherry picked from commit 9e0e6981fc536c9e51ce24c425141a3d09b39e3a) Reviewed-on: https://go-review.googlesource.com/110076 Reviewed-by: Ian Lance Taylor --- diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go index cf049ec35b..a296005780 100644 --- a/misc/cgo/testshared/shared_test.go +++ b/misc/cgo/testshared/shared_test.go @@ -790,6 +790,7 @@ func TestRebuilding(t *testing.T) { // If the .a file is newer than the .so, the .so is rebuilt (but not the .a) t.Run("newarchive", func(t *testing.T) { resetFileStamps() + AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a")) goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase") AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a")) cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a")) diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 7e6b492db4..6a7904c99a 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -5074,6 +5074,28 @@ func TestCacheOutput(t *testing.T) { } } +func TestCacheListStale(t *testing.T) { + tooSlow(t) + if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") { + t.Skip("GODEBUG gocacheverify") + } + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.makeTempdir() + tg.setenv("GOCACHE", tg.path("cache")) + tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n") + tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n") + tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n") + + tg.setenv("GOPATH", tg.path("gopath")) + tg.run("install", "p", "m") + tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p") + tg.grepStdout("^m false", "m should not be stale") + tg.grepStdout("^q true", "q should be stale") + tg.grepStdout("^p false", "p should not be stale") +} + func TestCacheCoverage(t *testing.T) { tooSlow(t) diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go index 39ca20ee4f..bf63b8f472 100644 --- a/src/cmd/go/internal/work/buildid.go +++ b/src/cmd/go/internal/work/buildid.go @@ -397,15 +397,7 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID // If so, it's up to date and we can reuse it instead of rebuilding it. var buildID string if target != "" && !cfg.BuildA { - var err error - buildID, err = buildid.ReadFile(target) - if err != nil && b.ComputeStaleOnly { - if p != nil && !p.Stale { - p.Stale = true - p.StaleReason = "target missing" - } - return true - } + buildID, _ = buildid.ReadFile(target) if strings.HasPrefix(buildID, actionID+buildIDSeparator) { a.buildID = buildID a.built = target @@ -482,7 +474,10 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID } } } - return true + + // Fall through to update a.buildID from the build artifact cache, + // which will affect the computation of buildIDs for targets + // higher up in the dependency graph. } // Check the build artifact cache. @@ -510,6 +505,10 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID a.built = file a.Target = "DO NOT USE - using cache" a.buildID = buildID + if p := a.Package; p != nil { + // Clearer than explaining that something else is stale. + p.StaleReason = "not installed but available in build cache" + } return true } } @@ -520,6 +519,10 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID a.output = []byte{} } + if b.ComputeStaleOnly { + return true + } + return false } diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 02981d7164..a50c996041 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -1093,7 +1093,7 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) { // We want to hide that awful detail as much as possible, so don't // advertise it by touching the mtimes (usually the libraries are up // to date). - if !a.buggyInstall { + if !a.buggyInstall && !b.ComputeStaleOnly { now := time.Now() os.Chtimes(a.Target, now, now) }