diff options
Diffstat (limited to 'libgo/go/cmd/go/internal/modfetch/fetch.go')
-rw-r--r-- | libgo/go/cmd/go/internal/modfetch/fetch.go | 120 |
1 files changed, 99 insertions, 21 deletions
diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go index d3d30d970b3..f5423b48ad3 100644 --- a/libgo/go/cmd/go/internal/modfetch/fetch.go +++ b/libgo/go/cmd/go/internal/modfetch/fetch.go @@ -48,7 +48,7 @@ func Download(ctx context.Context, mod module.Version) (dir string, err error) { dir string err error } - c := downloadCache.Do(mod, func() interface{} { + c := downloadCache.Do(mod, func() any { dir, err := download(ctx, mod) if err != nil { return cached{"", err} @@ -165,7 +165,7 @@ func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err e zipfile string err error } - c := downloadZipCache.Do(mod, func() interface{} { + c := downloadZipCache.Do(mod, func() any { zipfile, err := CachePath(mod, "zip") if err != nil { return cached{"", err} @@ -384,7 +384,8 @@ func RemoveAll(dir string) error { return robustio.RemoveAll(dir) } -var GoSumFile string // path to go.sum; set by package modload +var GoSumFile string // path to go.sum; set by package modload +var WorkspaceGoSumFiles []string // path to module go.sums in workspace; set by package modload type modSum struct { mod module.Version @@ -393,16 +394,39 @@ type modSum struct { var goSum struct { mu sync.Mutex - m map[module.Version][]string // content of go.sum file - 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 + m map[module.Version][]string // content of go.sum file + w map[string]map[module.Version][]string // sum file in workspace -> content of that sum file + 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 } +// Reset resets globals in the modfetch package, so previous loads don't affect +// contents of go.sum files +func Reset() { + GoSumFile = "" + WorkspaceGoSumFiles = nil + + // Uses of lookupCache and downloadCache both can call checkModSum, + // which in turn sets the used bit on goSum.status for modules. + // Reset them so used can be computed properly. + lookupCache = par.Cache{} + downloadCache = par.Cache{} + + // Clear all fields on goSum. It will be initialized later + goSum.mu.Lock() + goSum.m = nil + goSum.w = nil + goSum.status = nil + goSum.overwrite = false + goSum.enabled = false + goSum.mu.Unlock() +} + // initGoSum initializes the go.sum data. // The boolean it returns reports whether the // use of go.sum is now enabled. @@ -417,23 +441,38 @@ func initGoSum() (bool, error) { goSum.m = make(map[module.Version][]string) goSum.status = make(map[modSum]modSumStatus) + goSum.w = make(map[string]map[module.Version][]string) + + for _, f := range WorkspaceGoSumFiles { + goSum.w[f] = make(map[module.Version][]string) + _, err := readGoSumFile(goSum.w[f], f) + if err != nil { + return false, err + } + } + + enabled, err := readGoSumFile(goSum.m, GoSumFile) + goSum.enabled = enabled + return enabled, err +} + +func readGoSumFile(dst map[module.Version][]string, file string) (bool, error) { var ( data []byte err error ) - if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok { + if actualSumFile, ok := fsys.OverlayPath(file); ok { // Don't lock go.sum if it's part of the overlay. // On Plan 9, locking requires chmod, and we don't want to modify any file // in the overlay. See #44700. data, err = os.ReadFile(actualSumFile) } else { - data, err = lockedfile.Read(GoSumFile) + data, err = lockedfile.Read(file) } if err != nil && !os.IsNotExist(err) { return false, err } - goSum.enabled = true - readGoSum(goSum.m, GoSumFile, data) + readGoSum(dst, file, data) return true, nil } @@ -485,6 +524,16 @@ func HaveSum(mod module.Version) bool { if err != nil || !inited { return false } + for _, goSums := range goSum.w { + for _, h := range goSums[mod] { + if !strings.HasPrefix(h, "h1:") { + continue + } + if !goSum.status[modSum{mod, h}].dirty { + return true + } + } + } for _, h := range goSum.m[mod] { if !strings.HasPrefix(h, "h1:") { continue @@ -602,15 +651,32 @@ 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 { + sumFileName := "go.sum" + if strings.HasSuffix(GoSumFile, "go.work.sum") { + sumFileName = "go.work.sum" + } for _, vh := range goSum.m[mod] { if h == vh { return true } if strings.HasPrefix(vh, "h1:") { - base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\tgo.sum: %v"+goSumMismatch, mod.Path, mod.Version, h, vh) + base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+goSumMismatch, mod.Path, mod.Version, h, sumFileName, vh) + } + } + // Also check workspace sums. + foundMatch := false + // Check sums from all files in case there are conflicts between + // the files. + for goSumFile, goSums := range goSum.w { + for _, vh := range goSums[mod] { + if h == vh { + foundMatch = true + } else if strings.HasPrefix(vh, "h1:") { + base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+goSumMismatch, mod.Path, mod.Version, h, goSumFile, vh) + } } } - return false + return foundMatch } // addModSumLocked adds the pair mod,h to go.sum. @@ -693,19 +759,21 @@ func isValidSum(data []byte) bool { return true } +var ErrGoSumDirty = errors.New("updates to go.sum needed, disabled by -mod=readonly") + // WriteGoSum writes the go.sum file if it needs to be updated. // // 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) { +func WriteGoSum(keep map[module.Version]bool, readonly bool) error { goSum.mu.Lock() defer goSum.mu.Unlock() // If we haven't read the go.sum file yet, don't bother writing it. if !goSum.enabled { - return + return nil } // Check whether we need to add sums for which keep[m] is true or remove @@ -723,10 +791,10 @@ Outer: } } if !dirty { - return + return nil } - if cfg.BuildMod == "readonly" { - base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly") + if readonly { + return ErrGoSumDirty } if _, ok := fsys.OverlayPath(GoSumFile); ok { base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay") @@ -747,7 +815,7 @@ Outer: goSum.m = make(map[module.Version][]string, len(goSum.m)) readGoSum(goSum.m, GoSumFile, data) for ms, st := range goSum.status { - if st.used { + if st.used && !sumInWorkspaceModulesLocked(ms.mod) { addModSumLocked(ms.mod, ms.sum) } } @@ -765,7 +833,7 @@ Outer: sort.Strings(list) for _, h := range list { st := goSum.status[modSum{m, h}] - if !st.dirty || (st.used && keep[m]) { + if (!st.dirty || (st.used && keep[m])) && !sumInWorkspaceModulesLocked(m) { fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h) } } @@ -774,11 +842,21 @@ Outer: }) if err != nil { - base.Fatalf("go: updating go.sum: %v", err) + return fmt.Errorf("updating go.sum: %w", err) } goSum.status = make(map[modSum]modSumStatus) goSum.overwrite = false + return nil +} + +func sumInWorkspaceModulesLocked(m module.Version) bool { + for _, goSums := range goSum.w { + if _, ok := goSums[m]; ok { + return true + } + } + return false } // TrimGoSum trims go.sum to contain only the modules needed for reproducible |