modzip "golang.org/x/mod/zip"
)
-// The downloadCache is used to cache the operation of downloading a module to disk
-// (if it's not already downloaded) and getting the directory it was downloaded to.
-// It is important that downloadCache must not be accessed by any of the exported
-// functions of this package after they return, because it can be modified by the
-// non-thread-safe SetState function
-var downloadCache = new(par.ErrCache[module.Version, string]) // version → directory;
-
var ErrToolchain = errors.New("internal error: invalid operation on toolchain module")
// Download downloads the specific module version to the
}
// The par.Cache here avoids duplicate work.
- return downloadCache.Do(mod, func() (string, error) {
+ return ModuleFetchState.downloadCache.Do(mod, func() (string, error) {
dir, err := download(ctx, mod)
if err != nil {
return "", err
base.Fatal(err)
}
- return downloadCache.Do(mod, func() (string, error) {
+ return ModuleFetchState.downloadCache.Do(mod, func() (string, error) {
ctx, span := trace.StartSpan(ctx, "modfetch.Unzip "+mod.String())
defer span.Done()
// accessed by any of the exported functions of this package after they return, because
// they can be modified by the non-thread-safe SetState function.
-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
sum string
// State holds a snapshot of the global state of the modfetch package.
type State struct {
- goSumFile string
- workspaceGoSumFiles []string
- lookupCache *par.Cache[lookupCacheKey, Repo]
- downloadCache *par.ErrCache[module.Version, string]
- sumState sumState
+ // path to go.sum; set by package modload
+ GoSumFile string
+ // path to module go.sums in workspace; set by package modload
+ WorkspaceGoSumFiles []string
+ // The Lookup cache is used cache the work done by Lookup.
+ // It is important that the global functions of this package that access it do not
+ // do so after they return.
+ lookupCache *par.Cache[lookupCacheKey, Repo]
+ // The downloadCache is used to cache the operation of downloading a module to disk
+ // (if it's not already downloaded) and getting the directory it was downloaded to.
+ // It is important that downloadCache must not be accessed by any of the exported
+ // functions of this package after they return, because it can be modified by the
+ // non-thread-safe SetState function.
+ downloadCache *par.ErrCache[module.Version, string] // version → directory;
+
+ sumState sumState
+}
+
+var ModuleFetchState *State = NewState()
+
+func NewState() *State {
+ s := new(State)
+ s.lookupCache = new(par.Cache[lookupCacheKey, Repo])
+ s.downloadCache = new(par.ErrCache[module.Version, string])
+ return s
}
// Reset resets globals in the modfetch package, so previous loads don't affect
defer goSum.mu.Unlock()
oldState = State{
- goSumFile: GoSumFile,
- workspaceGoSumFiles: WorkspaceGoSumFiles,
- lookupCache: lookupCache,
- downloadCache: downloadCache,
+ GoSumFile: ModuleFetchState.GoSumFile,
+ WorkspaceGoSumFiles: ModuleFetchState.WorkspaceGoSumFiles,
+ lookupCache: ModuleFetchState.lookupCache,
+ downloadCache: ModuleFetchState.downloadCache,
sumState: goSum.sumState,
}
- GoSumFile = newState.goSumFile
- WorkspaceGoSumFiles = newState.workspaceGoSumFiles
+ ModuleFetchState.GoSumFile = newState.GoSumFile
+ ModuleFetchState.WorkspaceGoSumFiles = newState.WorkspaceGoSumFiles
// Uses of lookupCache and downloadCache both can call checkModSum,
// which in turn sets the used bit on goSum.status for modules.
// Set (or reset) them so used can be computed properly.
- lookupCache = newState.lookupCache
- downloadCache = newState.downloadCache
+ ModuleFetchState.lookupCache = newState.lookupCache
+ ModuleFetchState.downloadCache = newState.downloadCache
// Set, or reset all fields on goSum. If being reset to empty, it will be initialized later.
goSum.sumState = newState.sumState
// use of go.sum is now enabled.
// The goSum lock must be held.
func initGoSum() (bool, error) {
- if GoSumFile == "" {
+ if ModuleFetchState.GoSumFile == "" {
return false, nil
}
if goSum.m != nil {
goSum.status = make(map[modSum]modSumStatus)
goSum.w = make(map[string]map[module.Version][]string)
- for _, f := range WorkspaceGoSumFiles {
+ for _, f := range ModuleFetchState.WorkspaceGoSumFiles {
goSum.w[f] = make(map[module.Version][]string)
_, err := readGoSumFile(goSum.w[f], f)
if err != nil {
}
}
- enabled, err := readGoSumFile(goSum.m, GoSumFile)
+ enabled, err := readGoSumFile(goSum.m, ModuleFetchState.GoSumFile)
goSum.enabled = enabled
return enabled, err
}
// goSum.mu must be locked.
func haveModSumLocked(mod module.Version, h string) bool {
sumFileName := "go.sum"
- if strings.HasSuffix(GoSumFile, "go.work.sum") {
+ if strings.HasSuffix(ModuleFetchState.GoSumFile, "go.work.sum") {
sumFileName = "go.work.sum"
}
for _, vh := range goSum.m[mod] {
if readonly {
return ErrGoSumDirty
}
- if fsys.Replaced(GoSumFile) {
+ if fsys.Replaced(ModuleFetchState.GoSumFile) {
base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
}
defer unlock()
}
- err := lockedfile.Transform(GoSumFile, func(data []byte) ([]byte, error) {
+ err := lockedfile.Transform(ModuleFetchState.GoSumFile, func(data []byte) ([]byte, error) {
tidyGoSum := tidyGoSum(data, keep)
return tidyGoSum, nil
})
func TidyGoSum(keep map[module.Version]bool) (before, after []byte) {
goSum.mu.Lock()
defer goSum.mu.Unlock()
- before, err := lockedfile.Read(GoSumFile)
+ before, err := lockedfile.Read(ModuleFetchState.GoSumFile)
if err != nil && !errors.Is(err, fs.ErrNotExist) {
base.Fatalf("reading go.sum: %v", err)
}
// truncated the file to remove erroneous hashes, and we shouldn't restore
// them without good reason.
goSum.m = make(map[module.Version][]string, len(goSum.m))
- readGoSum(goSum.m, GoSumFile, data)
+ readGoSum(goSum.m, ModuleFetchState.GoSumFile, data)
for ms, st := range goSum.status {
if st.used && !sumInWorkspaceModulesLocked(ms.mod) {
addModSumLocked(ms.mod, ms.sum)