[dev.cmdgo] cmd/go: remove modload.ModRoot function

In some cases, ModRoot was being called in a multi module context. In
those cases, pass in the correct main module. In other cases, a
mainModule variable was already available, so call MainModules.ModRoot
on that mainModule variable to make it more clear. In yet other cases
ModRoot is just needed to determine GoMod, so determine modroot from
the current directory in those cases.

For #45713

Change-Id: I8c8aa633cfae40d0c8740bdbf985f2b60c9daf2c
Reviewed-on: https://go-review.googlesource.com/c/go/+/339171
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>
This commit is contained in:
Michael Matloob 2021-08-02 16:02:45 -04:00
parent 3025ce2fa8
commit aaf914d0e6
9 changed files with 56 additions and 43 deletions

View File

@ -148,7 +148,7 @@ func ExtraEnvVars() []cfg.EnvVar {
gomod := "" gomod := ""
modload.Init() modload.Init()
if modload.HasModRoot() { if modload.HasModRoot() {
gomod = filepath.Join(modload.ModRoot(), "go.mod") gomod = modload.ModFilePath()
} else if modload.Enabled() { } else if modload.Enabled() {
gomod = os.DevNull gomod = os.DevNull
} }

View File

@ -74,7 +74,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
} }
_, pkgs := modload.LoadPackages(ctx, loadOpts, "all") _, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
vdir := filepath.Join(modload.ModRoot(), "vendor") vdir := filepath.Join(modload.VendorDir())
if err := os.RemoveAll(vdir); err != nil { if err := os.RemoveAll(vdir); err != nil {
base.Fatalf("go mod vendor: %v", err) base.Fatalf("go mod vendor: %v", err)
} }

View File

@ -724,7 +724,16 @@ func (r *resolver) performLocalQueries(ctx context.Context) {
// restricted to matching packages in the main module. // restricted to matching packages in the main module.
pkgPattern, mainModule := modload.MainModules.DirImportPath(ctx, q.pattern) pkgPattern, mainModule := modload.MainModules.DirImportPath(ctx, q.pattern)
if pkgPattern == "." { if pkgPattern == "." {
return errSet(fmt.Errorf("%s%s is not within module rooted at %s", q.pattern, absDetail, modload.ModRoot())) modload.MustHaveModRoot()
var modRoots []string
for _, m := range modload.MainModules.Versions() {
modRoots = append(modRoots, modload.MainModules.ModRoot(m))
}
var plural string
if len(modRoots) != 1 {
plural = "s"
}
return errSet(fmt.Errorf("%s%s is not within module%s rooted at %s", q.pattern, absDetail, plural, strings.Join(modRoots, ", ")))
} }
match := modload.MatchInModule(ctx, pkgPattern, mainModule, imports.AnyTags()) match := modload.MatchInModule(ctx, pkgPattern, mainModule, imports.AnyTags())
@ -737,7 +746,8 @@ func (r *resolver) performLocalQueries(ctx context.Context) {
return errSet(fmt.Errorf("no package in current directory")) return errSet(fmt.Errorf("no package in current directory"))
} }
if !q.isWildcard() { if !q.isWildcard() {
return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.ModRoot())) modload.MustHaveModRoot()
return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.MainModules.ModRoot(mainModule)))
} }
search.WarnUnmatched([]*search.Match{match}) search.WarnUnmatched([]*search.Match{match})
return pathSet{} return pathSet{}

View File

@ -323,7 +323,7 @@ func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode Li
if filepath.IsAbs(r.Path) { if filepath.IsAbs(r.Path) {
info.Replace.Dir = r.Path info.Replace.Dir = r.Path
} else { } else {
info.Replace.Dir = filepath.Join(ModRoot(), r.Path) info.Replace.Dir = filepath.Join(replacedFrom, r.Path)
} }
info.Replace.GoMod = filepath.Join(info.Replace.Dir, "go.mod") info.Replace.GoMod = filepath.Join(info.Replace.Dir, "go.mod")
} }

View File

@ -294,7 +294,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
if mainErr != nil { if mainErr != nil {
return module.Version{}, "", mainErr return module.Version{}, "", mainErr
} }
readVendorList() readVendorList(mainModule)
return vendorPkgModule[path], vendorDir, nil return vendorPkgModule[path], vendorDir, nil
} }
@ -653,11 +653,11 @@ func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, i
if modRoot := MainModules.ModRoot(mod); modRoot != "" { if modRoot := MainModules.ModRoot(mod); modRoot != "" {
return modRoot, true, nil return modRoot, true, nil
} }
if r, _ := Replacement(mod); r.Path != "" { if r, replacedFrom := Replacement(mod); r.Path != "" {
if r.Version == "" { if r.Version == "" {
dir = r.Path dir = r.Path
if !filepath.IsAbs(dir) { if !filepath.IsAbs(dir) {
dir = filepath.Join(ModRoot(), dir) dir = filepath.Join(replacedFrom, dir)
} }
// Ensure that the replacement directory actually exists: // Ensure that the replacement directory actually exists:
// dirInModule does not report errors for missing modules, // dirInModule does not report errors for missing modules,

View File

@ -374,7 +374,6 @@ func Init() {
} }
if inWorkspaceMode() { if inWorkspaceMode() {
_ = TODOWorkspaces("go.work.sum, and also allow modfetch to fall back to individual go.sums") _ = TODOWorkspaces("go.work.sum, and also allow modfetch to fall back to individual go.sums")
_ = TODOWorkspaces("replaces") _ = TODOWorkspaces("replaces")
var err error var err error
@ -403,8 +402,7 @@ func Init() {
// //
// See golang.org/issue/32027. // See golang.org/issue/32027.
} else { } else {
_ = TODOWorkspaces("Instead of modfile path, find modfile OR workfile path depending on mode") modfetch.GoSumFile = strings.TrimSuffix(modFilePath(modRoots[0]), ".mod") + ".sum"
modfetch.GoSumFile = strings.TrimSuffix(ModFilePath(), ".mod") + ".sum"
} }
} }
@ -463,21 +461,8 @@ func Enabled() bool {
return modRoots != nil || cfg.ModulesEnabled return modRoots != nil || cfg.ModulesEnabled
} }
// ModRoot returns the root of the main module. func VendorDir() string {
// It calls base.Fatalf if there is no main module. return filepath.Join(MainModules.ModRoot(MainModules.mustGetSingleMainModule()), "vendor")
func ModRoot() string {
if !HasModRoot() {
die()
}
if inWorkspaceMode() {
panic("ModRoot called in workspace mode")
}
// This is similar to MustGetSingleMainModule but we can't call that
// because MainModules may not yet exist when ModRoot is called.
if len(modRoots) != 1 {
panic("not in workspace mode but there are multiple ModRoots")
}
return modRoots[0]
} }
func inWorkspaceMode() bool { func inWorkspaceMode() bool {
@ -495,12 +480,21 @@ func HasModRoot() bool {
return modRoots != nil return modRoots != nil
} }
// ModFilePath returns the effective path of the go.mod file. Normally, this // MustHaveModRoot checks that a main module or main modules are present,
// "go.mod" in the directory returned by ModRoot, but the -modfile flag may // and calls base.Fatalf if there are no main modules.
// change its location. ModFilePath calls base.Fatalf if there is no main func MustHaveModRoot() {
Init()
if !HasModRoot() {
die()
}
}
// ModFilePath returns the path that would be used for the go.mod
// file, if in module mode. ModFilePath calls base.Fatalf if there is no main
// module, even if -modfile is set. // module, even if -modfile is set.
func ModFilePath() string { func ModFilePath() string {
return modFilePath(ModRoot()) MustHaveModRoot()
return modFilePath(findModuleRoot(base.Cwd()))
} }
func modFilePath(modRoot string) string { func modFilePath(modRoot string) string {
@ -674,7 +668,7 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
mainModule := MainModules.mustGetSingleMainModule() mainModule := MainModules.mustGetSingleMainModule()
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
readVendorList() readVendorList(mainModule)
index := MainModules.Index(mainModule) index := MainModules.Index(mainModule)
modFile := MainModules.ModFile(mainModule) modFile := MainModules.ModFile(mainModule)
checkVendorConsistency(index, modFile) checkVendorConsistency(index, modFile)
@ -719,7 +713,7 @@ func CreateModFile(ctx context.Context, modPath string) {
modRoot := base.Cwd() modRoot := base.Cwd()
modRoots = []string{modRoot} modRoots = []string{modRoot}
Init() Init()
modFilePath := ModFilePath() modFilePath := modFilePath(modRoot)
if _, err := fsys.Stat(modFilePath); err == nil { if _, err := fsys.Stat(modFilePath); err == nil {
base.Fatalf("go: %s already exists", modFilePath) base.Fatalf("go: %s already exists", modFilePath)
} }
@ -1344,6 +1338,7 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
return return
} }
mainModule := MainModules.Versions()[0] mainModule := MainModules.Versions()[0]
modFilePath := modFilePath(MainModules.ModRoot(mainModule))
modFile := MainModules.ModFile(mainModule) modFile := MainModules.ModFile(mainModule)
var list []*modfile.Require var list []*modfile.Require
@ -1383,8 +1378,7 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
} }
return return
} }
gomod := ModFilePath() if _, ok := fsys.OverlayPath(modFilePath); ok {
if _, ok := fsys.OverlayPath(gomod); ok {
if dirty { if dirty {
base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay") base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
} }
@ -1422,7 +1416,7 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
errNoChange := errors.New("no update needed") errNoChange := errors.New("no update needed")
err = lockedfile.Transform(ModFilePath(), func(old []byte) ([]byte, error) { err = lockedfile.Transform(modFilePath, func(old []byte) ([]byte, error) {
if bytes.Equal(old, new) { if bytes.Equal(old, new) {
// The go.mod file is already equal to new, possibly as the result of some // The go.mod file is already equal to new, possibly as the result of some
// other process. // other process.

View File

@ -440,7 +440,16 @@ func matchLocalDirs(ctx context.Context, m *search.Match, rs *Requirements) {
if !filepath.IsAbs(dir) { if !filepath.IsAbs(dir) {
absDir = filepath.Join(base.Cwd(), dir) absDir = filepath.Join(base.Cwd(), dir)
} }
if search.InDir(absDir, cfg.GOROOTsrc) == "" && search.InDir(absDir, ModRoot()) == "" && pathInModuleCache(ctx, absDir, rs) == "" {
modRoot := findModuleRoot(absDir)
found := false
for _, mod := range MainModules.Versions() {
if MainModules.ModRoot(mod) == modRoot {
found = true
break
}
}
if !found && search.InDir(absDir, cfg.GOROOTsrc) == "" && pathInModuleCache(ctx, absDir, rs) == "" {
m.Dirs = []string{} m.Dirs = []string{}
m.AddError(fmt.Errorf("directory prefix %s outside available modules", base.ShortPath(absDir))) m.AddError(fmt.Errorf("directory prefix %s outside available modules", base.ShortPath(absDir)))
return return
@ -513,7 +522,7 @@ func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (str
return "", fmt.Errorf("without -mod=vendor, directory %s has no package path", absDir) return "", fmt.Errorf("without -mod=vendor, directory %s has no package path", absDir)
} }
readVendorList() readVendorList(mainModule)
pkg := strings.TrimPrefix(suffix, "/vendor/") pkg := strings.TrimPrefix(suffix, "/vendor/")
if _, ok := vendorPkgModule[pkg]; !ok { if _, ok := vendorPkgModule[pkg]; !ok {
return "", fmt.Errorf("directory %s is not a package listed in vendor/modules.txt", absDir) return "", fmt.Errorf("directory %s is not a package listed in vendor/modules.txt", absDir)
@ -582,10 +591,10 @@ func pathInModuleCache(ctx context.Context, dir string, rs *Requirements) string
tryMod := func(m module.Version) (string, bool) { tryMod := func(m module.Version) (string, bool) {
var root string var root string
var err error var err error
if repl, _ := Replacement(m); repl.Path != "" && repl.Version == "" { if repl, replModRoot := Replacement(m); repl.Path != "" && repl.Version == "" {
root = repl.Path root = repl.Path
if !filepath.IsAbs(root) { if !filepath.IsAbs(root) {
root = filepath.Join(ModRoot(), root) root = filepath.Join(replModRoot, root)
} }
} else if repl.Path != "" { } else if repl.Path != "" {
root, err = modfetch.DownloadDir(repl) root, err = modfetch.DownloadDir(repl)

View File

@ -528,7 +528,7 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
// For every module other than the target, // For every module other than the target,
// return the full list of modules from modules.txt. // return the full list of modules from modules.txt.
readVendorList() readVendorList(MainModules.mustGetSingleMainModule())
// We don't know what versions the vendored module actually relies on, // We don't know what versions the vendored module actually relies on,
// so assume that it requires everything. // so assume that it requires everything.

View File

@ -36,13 +36,13 @@ type vendorMetadata struct {
} }
// readVendorList reads the list of vendored modules from vendor/modules.txt. // readVendorList reads the list of vendored modules from vendor/modules.txt.
func readVendorList() { func readVendorList(mainModule module.Version) {
vendorOnce.Do(func() { vendorOnce.Do(func() {
vendorList = nil vendorList = nil
vendorPkgModule = make(map[string]module.Version) vendorPkgModule = make(map[string]module.Version)
vendorVersion = make(map[string]string) vendorVersion = make(map[string]string)
vendorMeta = make(map[module.Version]vendorMetadata) vendorMeta = make(map[module.Version]vendorMetadata)
data, err := os.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) data, err := os.ReadFile(filepath.Join(MainModules.ModRoot(mainModule), "vendor/modules.txt"))
if err != nil { if err != nil {
if !errors.Is(err, fs.ErrNotExist) { if !errors.Is(err, fs.ErrNotExist) {
base.Fatalf("go: %s", err) base.Fatalf("go: %s", err)
@ -136,7 +136,7 @@ func readVendorList() {
// go 1.14) or at least does not contradict (go 1.13 or earlier) the // go 1.14) or at least does not contradict (go 1.13 or earlier) the
// requirements and replacements listed in the main module's go.mod file. // requirements and replacements listed in the main module's go.mod file.
func checkVendorConsistency(index *modFileIndex, modFile *modfile.File) { func checkVendorConsistency(index *modFileIndex, modFile *modfile.File) {
readVendorList() readVendorList(MainModules.mustGetSingleMainModule())
pre114 := false pre114 := false
if semver.Compare(index.goVersionV, "v1.14") < 0 { if semver.Compare(index.goVersionV, "v1.14") < 0 {