aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/modload/init.go
diff options
context:
space:
mode:
authorMichael Matloob <matloob@golang.org>2021-06-08 17:07:10 -0400
committerMichael Matloob <matloob@golang.org>2021-07-27 21:26:57 +0000
commitf05f5ceffa6edec89436a825176eefdd1fe828e5 (patch)
treebd655bb7c9346cc28ffc07e1c0ccec9c96ecf439 /src/cmd/go/internal/modload/init.go
parent7ce257147fe0ab3413c8e36909c2408c833efdb8 (diff)
downloadgo-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.go95
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.