]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.10] cmd/go: fix go list .Stale computation
authorRuss Cox <rsc@golang.org>
Wed, 18 Apr 2018 20:34:45 +0000 (16:34 -0400)
committerAndrew Bonventre <andybons@golang.org>
Fri, 27 Apr 2018 20:51:11 +0000 (20:51 +0000)
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 <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit 9e0e6981fc536c9e51ce24c425141a3d09b39e3a)
Reviewed-on: https://go-review.googlesource.com/110076
Reviewed-by: Ian Lance Taylor <iant@golang.org>
misc/cgo/testshared/shared_test.go
src/cmd/go/go_test.go
src/cmd/go/internal/work/buildid.go
src/cmd/go/internal/work/exec.go

index cf049ec35b8a11f5ebe22707dad33a7c3bb547a6..a2960057809117f7b3c0cb68e8dc111889e231b9 100644 (file)
@@ -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"))
index 7e6b492db49ddd5d1cb9eb0e52f9fa42e2fa60d1..6a7904c99a18780e3f342b5ba8f4ed914aec9aea 100644 (file)
@@ -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)
 
index 39ca20ee4f0c9cc276b852e7dc66d93b278f36ae..bf63b8f4721874c78f03a3584df45de667f09fdd 100644 (file)
@@ -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
 }
 
index 02981d7164e309b145142d2292946656eab13825..a50c996041262e90f82f68f18135f73c83b95c41 100644 (file)
@@ -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)
                }