aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/modfetch/fetch.go
diff options
context:
space:
mode:
authorJay Conrod <jayconrod@google.com>2020-06-08 18:06:11 -0400
committerJay Conrod <jayconrod@google.com>2020-08-14 21:04:12 +0000
commit9a759593d7a71b4c061fd9bd053bd79584c632dc (patch)
tree3b1e5df9e12173481ffefb0499cedbc1509b9b65 /src/cmd/go/internal/modfetch/fetch.go
parent016e13df7475329c65524b2eabbc5207ceb4ee74 (diff)
downloadgo-9a759593d7a71b4c061fd9bd053bd79584c632dc.tar.gz
go-9a759593d7a71b4c061fd9bd053bd79584c632dc.zip
cmd/go: don't save sums for modules loaded for import resolution
modfetch.WriteGoSum now accepts a map[module.Version]bool parameter. This is used to prevent some new sums from being saved to go.sum when they would be removed by the next 'go mod tidy'. Previusly, sums were saved for modules looked up during import resolution. A new function, modload.TrimGoSum, is also introduced, which marks sums for deletion. 'go mod tidy' now uses this. The new logic distinguishes between go.mod sums and content sums, which lets 'go mod tidy' delete sums for modules in the build graph but not the build list. Fixes #31580 Fixes #36260 Fixes #33008 Change-Id: I06c4125704a8bbc9969de05265967ec1d2e6d3e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/237017 Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Matloob <matloob@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/cmd/go/internal/modfetch/fetch.go')
-rw-r--r--src/cmd/go/internal/modfetch/fetch.go83
1 files changed, 60 insertions, 23 deletions
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index 8df2289097..e40158b535 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -375,12 +375,15 @@ type modSum struct {
var goSum struct {
mu sync.Mutex
m map[module.Version][]string // content of go.sum file
- checked map[modSum]bool // sums actually checked during execution
- dirty bool // whether we added any new sums to m
+ status map[modSum]modSumStatus // state of sums in m
overwrite bool // if true, overwrite go.sum without incorporating its contents
enabled bool // whether to use go.sum at all
}
+type modSumStatus struct {
+ used, dirty bool
+}
+
// initGoSum initializes the go.sum data.
// The boolean it returns reports whether the
// use of go.sum is now enabled.
@@ -394,7 +397,7 @@ func initGoSum() (bool, error) {
}
goSum.m = make(map[module.Version][]string)
- goSum.checked = make(map[modSum]bool)
+ goSum.status = make(map[modSum]modSumStatus)
data, err := lockedfile.Read(GoSumFile)
if err != nil && !os.IsNotExist(err) {
return false, err
@@ -504,6 +507,11 @@ func checkModSum(mod module.Version, h string) error {
return err
}
done := inited && haveModSumLocked(mod, h)
+ if inited {
+ st := goSum.status[modSum{mod, h}]
+ st.used = true
+ goSum.status[modSum{mod, h}] = st
+ }
goSum.mu.Unlock()
if done {
@@ -523,6 +531,9 @@ func checkModSum(mod module.Version, h string) error {
if inited {
goSum.mu.Lock()
addModSumLocked(mod, h)
+ st := goSum.status[modSum{mod, h}]
+ st.dirty = true
+ goSum.status[modSum{mod, h}] = st
goSum.mu.Unlock()
}
return nil
@@ -532,7 +543,6 @@ func checkModSum(mod module.Version, h string) error {
// If it finds a conflicting pair instead, it calls base.Fatalf.
// goSum.mu must be locked.
func haveModSumLocked(mod module.Version, h string) bool {
- goSum.checked[modSum{mod, h}] = true
for _, vh := range goSum.m[mod] {
if h == vh {
return true
@@ -554,7 +564,6 @@ func addModSumLocked(mod module.Version, h string) {
fmt.Fprintf(os.Stderr, "warning: verifying %s@%s: unknown hashes in go.sum: %v; adding %v"+hashVersionMismatch, mod.Path, mod.Version, strings.Join(goSum.m[mod], ", "), h)
}
goSum.m[mod] = append(goSum.m[mod], h)
- goSum.dirty = true
}
// checkSumDB checks the mod, h pair against the Go checksum database.
@@ -598,13 +607,35 @@ func Sum(mod module.Version) string {
}
// WriteGoSum writes the go.sum file if it needs to be updated.
-func WriteGoSum() {
+//
+// keep is used to check whether a newly added sum should be saved in go.sum.
+// It should have entries for both module content sums and go.mod sums
+// (version ends with "/go.mod"). Existing sums will be preserved unless they
+// have been marked for deletion with TrimGoSum.
+func WriteGoSum(keep map[module.Version]bool) {
goSum.mu.Lock()
defer goSum.mu.Unlock()
- if !goSum.enabled || !goSum.dirty {
- // If we haven't read go.sum yet or if we don't have anything to add,
- // don't bother opening it.
+ // If we haven't read the go.sum file yet, don't bother writing it.
+ if !goSum.enabled {
+ return
+ }
+
+ // Check whether we need to add sums for which keep[m] is true or remove
+ // unused sums marked with TrimGoSum. If there are no changes to make,
+ // just return without opening go.sum.
+ dirty := false
+Outer:
+ for m, hs := range goSum.m {
+ for _, h := range hs {
+ st := goSum.status[modSum{m, h}]
+ if st.dirty && (!st.used || keep[m]) {
+ dirty = true
+ break Outer
+ }
+ }
+ }
+ if !dirty {
return
}
if cfg.BuildMod == "readonly" {
@@ -625,9 +656,10 @@ func WriteGoSum() {
// them without good reason.
goSum.m = make(map[module.Version][]string, len(goSum.m))
readGoSum(goSum.m, GoSumFile, data)
- for ms := range goSum.checked {
- addModSumLocked(ms.mod, ms.sum)
- goSum.dirty = true
+ for ms, st := range goSum.status {
+ if st.used {
+ addModSumLocked(ms.mod, ms.sum)
+ }
}
}
@@ -642,7 +674,10 @@ func WriteGoSum() {
list := goSum.m[m]
sort.Strings(list)
for _, h := range list {
- fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h)
+ st := goSum.status[modSum{m, h}]
+ if !st.dirty || (st.used && keep[m]) {
+ fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h)
+ }
}
}
return buf.Bytes(), nil
@@ -652,12 +687,16 @@ func WriteGoSum() {
base.Fatalf("go: updating go.sum: %v", err)
}
- goSum.checked = make(map[modSum]bool)
- goSum.dirty = false
+ goSum.status = make(map[modSum]modSumStatus)
goSum.overwrite = false
}
-// TrimGoSum trims go.sum to contain only the modules for which keep[m] is true.
+// TrimGoSum trims go.sum to contain only the modules needed for reproducible
+// builds.
+//
+// keep is used to check whether a sum should be retained in go.mod. It should
+// have entries for both module content sums and go.mod sums (version ends
+// with "/go.mod").
func TrimGoSum(keep map[module.Version]bool) {
goSum.mu.Lock()
defer goSum.mu.Unlock()
@@ -669,13 +708,11 @@ func TrimGoSum(keep map[module.Version]bool) {
return
}
- for m := range goSum.m {
- // If we're keeping x@v we also keep x@v/go.mod.
- // Map x@v/go.mod back to x@v for the keep lookup.
- noGoMod := module.Version{Path: m.Path, Version: strings.TrimSuffix(m.Version, "/go.mod")}
- if !keep[m] && !keep[noGoMod] {
- delete(goSum.m, m)
- goSum.dirty = true
+ for m, hs := range goSum.m {
+ if !keep[m] {
+ for _, h := range hs {
+ goSum.status[modSum{m, h}] = modSumStatus{used: false, dirty: true}
+ }
goSum.overwrite = true
}
}