diff options
author | Michael Matloob <matloob@golang.org> | 2021-06-08 17:07:10 -0400 |
---|---|---|
committer | Michael Matloob <matloob@golang.org> | 2021-07-27 21:26:57 +0000 |
commit | f05f5ceffa6edec89436a825176eefdd1fe828e5 (patch) | |
tree | bd655bb7c9346cc28ffc07e1c0ccec9c96ecf439 /src/cmd/go/internal/modload/init.go | |
parent | 7ce257147fe0ab3413c8e36909c2408c833efdb8 (diff) | |
download | go-f05f5ceffa6edec89436a825176eefdd1fe828e5.tar.gz go-f05f5ceffa6edec89436a825176eefdd1fe828e5.zip |
[dev.cmdgo] cmd/go: fold index and modFile into MainModules
For #45713
Change-Id: I5e4b0ae16dcc9ba5ac30683370a3a1d3416e24f2
Reviewed-on: https://go-review.googlesource.com/c/go/+/334935
Trust: Michael Matloob <matloob@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Diffstat (limited to 'src/cmd/go/internal/modload/init.go')
-rw-r--r-- | src/cmd/go/internal/modload/init.go | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index f211e1767c..607054d1eb 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -17,6 +17,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" @@ -85,6 +86,11 @@ type MainModuleSet struct { // inGorootSrc caches whether modRoot is within GOROOT/src. // The "std" module is special within GOROOT/src, but not otherwise. inGorootSrc map[module.Version]bool + + modFiles map[module.Version]*modfile.File + + indexMu sync.Mutex + indices map[module.Version]*modFileIndex } func (mms *MainModuleSet) PathPrefix(m module.Version) string { @@ -141,6 +147,36 @@ func (mms *MainModuleSet) mustGetSingleMainModule() module.Version { return mms.versions[0] } +func (mms *MainModuleSet) GetSingleIndexOrNil() *modFileIndex { + if mms == nil { + return nil + } + if len(mms.versions) == 0 { + return nil + } + if len(mms.versions) != 1 { + _ = TODOWorkspaces("Check if we're in workspace mode before returning the below error.") + panic("internal error: mustGetSingleMainModule called in workspace mode") + } + return mms.indices[mms.versions[0]] +} + +func (mms *MainModuleSet) Index(m module.Version) *modFileIndex { + mms.indexMu.Lock() + defer mms.indexMu.Unlock() + return mms.indices[m] +} + +func (mms *MainModuleSet) SetIndex(m module.Version, index *modFileIndex) { + mms.indexMu.Lock() + defer mms.indexMu.Unlock() + mms.indices[m] = index +} + +func (mms *MainModuleSet) ModFile(m module.Version) *modfile.File { + return mms.modFiles[m] +} + func (mms *MainModuleSet) Len() int { if mms == nil { return 0 @@ -178,6 +214,7 @@ const ( // in go.mod, edit it before loading. func ModFile() *modfile.File { Init() + modFile := MainModules.ModFile(MainModules.mustGetSingleMainModule()) if modFile == nil { die() } @@ -557,7 +594,7 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) { if len(modRoots) == 0 { _ = TODOWorkspaces("Instead of creating a fake module with an empty modroot, make MainModules.Len() == 0 mean that we're in module mode but not inside any module.") mainModule := module.Version{Path: "command-line-arguments"} - MainModules = makeMainModules([]module.Version{mainModule}, []string{""}) + MainModules = makeMainModules([]module.Version{mainModule}, []string{""}, []*modfile.File{nil}, []*modFileIndex{nil}) goVersion := LatestGoVersion() rawGoVersion.Store(mainModule, goVersion) requirements = newRequirements(modDepthFromGoVersion(goVersion), nil, nil) @@ -566,6 +603,7 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) { var modFiles []*modfile.File var mainModules []module.Version + var indices []*modFileIndex for _, modroot := range modRoots { gomod := modFilePath(modroot) var data []byte @@ -593,11 +631,10 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) { base.Fatalf("go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod") } - modFile = f // TODO(golang.org/cl/327329): remove the global modFile variable and replace it with multiple modfiles modFiles = append(modFiles, f) mainModule := f.Module.Mod mainModules = append(mainModules, mainModule) - index = indexModFile(data, f, mainModule, fixed) + indices = append(indices, indexModFile(data, f, mainModule, fixed)) if err := module.CheckImportPath(f.Module.Mod.Path); err != nil { if pathErr, ok := err.(*module.InvalidPathError); ok { @@ -607,7 +644,7 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) { } } - MainModules = makeMainModules(mainModules, modRoots) + MainModules = makeMainModules(mainModules, modRoots, modFiles, indices) setDefaultBuildMod() // possibly enable automatic vendoring rs = requirementsFromModFiles(ctx, modFiles) @@ -623,14 +660,16 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) { if cfg.BuildMod == "vendor" { readVendorList() - checkVendorConsistency() + index := MainModules.Index(mainModule) + modFile := MainModules.ModFile(mainModule) + checkVendorConsistency(index, modFile) rs.initVendor(vendorList) } - if index.goVersionV == "" { + if MainModules.Index(mainModule).goVersionV == "" { // TODO(#45551): Do something more principled instead of checking // cfg.CmdName directly here. if cfg.BuildMod == "mod" && cfg.CmdName != "mod graph" && cfg.CmdName != "mod why" { - addGoStmt(mainModule, LatestGoVersion()) + addGoStmt(MainModules.ModFile(mainModule), mainModule, LatestGoVersion()) if go117EnableLazyLoading { // We need to add a 'go' version to the go.mod file, but we must assume // that its existing contents match something between Go 1.11 and 1.16. @@ -689,12 +728,12 @@ func CreateModFile(ctx context.Context, modPath string) { } fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath) - modFile = new(modfile.File) + modFile := new(modfile.File) modFile.AddModuleStmt(modPath) - MainModules = makeMainModules([]module.Version{modFile.Module.Mod}, []string{modRoot}) - addGoStmt(modFile.Module.Mod, LatestGoVersion()) // Add the go directive before converted module requirements. + MainModules = makeMainModules([]module.Version{modFile.Module.Mod}, []string{modRoot}, []*modfile.File{modFile}, []*modFileIndex{nil}) + addGoStmt(modFile, modFile.Module.Mod, LatestGoVersion()) // Add the go directive before converted module requirements. - convertedFrom, err := convertLegacyConfig(modPath) + convertedFrom, err := convertLegacyConfig(modFile, modPath) if convertedFrom != "" { fmt.Fprintf(os.Stderr, "go: copying requirements from %s\n", base.ShortPath(convertedFrom)) } @@ -792,7 +831,7 @@ func AllowMissingModuleImports() { // makeMainModules creates a MainModuleSet and associated variables according to // the given main modules. -func makeMainModules(ms []module.Version, rootDirs []string) *MainModuleSet { +func makeMainModules(ms []module.Version, rootDirs []string, modFiles []*modfile.File, indices []*modFileIndex) *MainModuleSet { for _, m := range ms { if m.Version != "" { panic("mainModulesCalled with module.Version with non empty Version field: " + fmt.Sprintf("%#v", m)) @@ -803,10 +842,14 @@ func makeMainModules(ms []module.Version, rootDirs []string) *MainModuleSet { inGorootSrc: map[module.Version]bool{}, pathPrefix: map[module.Version]string{}, modRoot: map[module.Version]string{}, + modFiles: map[module.Version]*modfile.File{}, + indices: map[module.Version]*modFileIndex{}, } for i, m := range ms { mainModules.pathPrefix[m] = m.Path mainModules.modRoot[m] = rootDirs[i] + mainModules.modFiles[m] = modFiles[i] + mainModules.indices[m] = indices[i] if rel := search.InDir(rootDirs[i], cfg.GOROOTsrc); rel != "" { mainModules.inGorootSrc[m] = true @@ -840,15 +883,18 @@ func requirementsFromModFiles(ctx context.Context, modFiles []*modfile.File) *Re } direct := map[string]bool{} for _, modFile := range modFiles { - // TODO(golang.org/cl/327329): Use the correct index here. + requirement: for _, r := range modFile.Require { - if index != nil && index.exclude[r.Mod] { - if cfg.BuildMod == "mod" { - fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) - } else { - fmt.Fprintf(os.Stderr, "go: ignoring requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) + // TODO(#45713): Maybe join + for _, mainModule := range MainModules.Versions() { + if index := MainModules.Index(mainModule); index != nil && index.exclude[r.Mod] { + if cfg.BuildMod == "mod" { + fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) + } else { + fmt.Fprintf(os.Stderr, "go: ignoring requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) + } + continue requirement } - continue } roots = append(roots, r.Mod) @@ -908,6 +954,7 @@ func setDefaultBuildMod() { } if len(modRoots) == 1 { + index := MainModules.GetSingleIndexOrNil() if fi, err := fsys.Stat(filepath.Join(modRoots[0], "vendor")); err == nil && fi.IsDir() { modGo := "unspecified" if index != nil && index.goVersionV != "" { @@ -933,7 +980,7 @@ func setDefaultBuildMod() { // convertLegacyConfig imports module requirements from a legacy vendoring // configuration file, if one is present. -func convertLegacyConfig(modPath string) (from string, err error) { +func convertLegacyConfig(modFile *modfile.File, modPath string) (from string, err error) { noneSelected := func(path string) (version string) { return "none" } queryPackage := func(path, rev string) (module.Version, error) { pkgMods, modOnly, err := QueryPattern(context.Background(), path, rev, noneSelected, nil) @@ -967,7 +1014,7 @@ func convertLegacyConfig(modPath string) (from string, err error) { // addGoStmt adds a go directive to the go.mod file if it does not already // include one. The 'go' version added, if any, is the latest version supported // by this toolchain. -func addGoStmt(mod module.Version, v string) { +func addGoStmt(modFile *modfile.File, mod module.Version, v string) { if modFile.Go != nil && modFile.Go.Version != "" { return } @@ -1231,8 +1278,11 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements) if MainModules.Len() != 1 || MainModules.ModRoot(MainModules.Versions()[0]) == "" { _ = TODOWorkspaces("also check that workspace mode is off") // We aren't in a module, so we don't have anywhere to write a go.mod file. + _ = TODOWorkspaces("also check that workspace mode is off") return } + mainModule := MainModules.Versions()[0] + modFile := MainModules.ModFile(mainModule) var list []*modfile.Require for _, m := range rs.rootModules { @@ -1251,6 +1301,7 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements) } modFile.Cleanup() + index := MainModules.GetSingleIndexOrNil() dirty := index.modFileIsDirty(modFile) if dirty && cfg.BuildMod != "mod" { // If we're about to fail due to -mod=readonly, @@ -1281,7 +1332,7 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements) mainModule := MainModules.Versions()[0] // At this point we have determined to make the go.mod file on disk equal to new. - index = indexModFile(new, modFile, mainModule, false) + MainModules.SetIndex(mainModule, indexModFile(new, modFile, mainModule, false)) // Update go.sum after releasing the side lock and refreshing the index. // 'go mod init' shouldn't write go.sum, since it will be incomplete. |