gomod := ""
modload.Init()
if modload.HasModRoot() {
- gomod = filepath.Join(modload.ModRoot(), "go.mod")
+ gomod = modload.ModFilePath()
} else if modload.Enabled() {
gomod = os.DevNull
}
}
_, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
- vdir := filepath.Join(modload.ModRoot(), "vendor")
+ vdir := filepath.Join(modload.VendorDir())
if err := os.RemoveAll(vdir); err != nil {
base.Fatalf("go mod vendor: %v", err)
}
// restricted to matching packages in the main module.
pkgPattern, mainModule := modload.MainModules.DirImportPath(ctx, q.pattern)
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())
return errSet(fmt.Errorf("no package in current directory"))
}
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})
return pathSet{}
if filepath.IsAbs(r.Path) {
info.Replace.Dir = r.Path
} 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")
}
if mainErr != nil {
return module.Version{}, "", mainErr
}
- readVendorList()
+ readVendorList(mainModule)
return vendorPkgModule[path], vendorDir, nil
}
if modRoot := MainModules.ModRoot(mod); modRoot != "" {
return modRoot, true, nil
}
- if r, _ := Replacement(mod); r.Path != "" {
+ if r, replacedFrom := Replacement(mod); r.Path != "" {
if r.Version == "" {
dir = r.Path
if !filepath.IsAbs(dir) {
- dir = filepath.Join(ModRoot(), dir)
+ dir = filepath.Join(replacedFrom, dir)
}
// Ensure that the replacement directory actually exists:
// dirInModule does not report errors for missing modules,
}
if inWorkspaceMode() {
-
_ = TODOWorkspaces("go.work.sum, and also allow modfetch to fall back to individual go.sums")
_ = TODOWorkspaces("replaces")
var err error
//
// See golang.org/issue/32027.
} else {
- _ = TODOWorkspaces("Instead of modfile path, find modfile OR workfile path depending on mode")
- modfetch.GoSumFile = strings.TrimSuffix(ModFilePath(), ".mod") + ".sum"
+ modfetch.GoSumFile = strings.TrimSuffix(modFilePath(modRoots[0]), ".mod") + ".sum"
}
}
return modRoots != nil || cfg.ModulesEnabled
}
-// ModRoot returns the root of the main module.
-// It calls base.Fatalf if there is no main module.
-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 VendorDir() string {
+ return filepath.Join(MainModules.ModRoot(MainModules.mustGetSingleMainModule()), "vendor")
}
func inWorkspaceMode() bool {
return modRoots != nil
}
-// ModFilePath returns the effective path of the go.mod file. Normally, this
-// "go.mod" in the directory returned by ModRoot, but the -modfile flag may
-// change its location. ModFilePath calls base.Fatalf if there is no main
+// MustHaveModRoot checks that a main module or main modules are present,
+// and calls base.Fatalf if there are no main modules.
+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.
func ModFilePath() string {
- return modFilePath(ModRoot())
+ MustHaveModRoot()
+ return modFilePath(findModuleRoot(base.Cwd()))
}
func modFilePath(modRoot string) string {
mainModule := MainModules.mustGetSingleMainModule()
if cfg.BuildMod == "vendor" {
- readVendorList()
+ readVendorList(mainModule)
index := MainModules.Index(mainModule)
modFile := MainModules.ModFile(mainModule)
checkVendorConsistency(index, modFile)
modRoot := base.Cwd()
modRoots = []string{modRoot}
Init()
- modFilePath := ModFilePath()
+ modFilePath := modFilePath(modRoot)
if _, err := fsys.Stat(modFilePath); err == nil {
base.Fatalf("go: %s already exists", modFilePath)
}
return
}
mainModule := MainModules.Versions()[0]
+ modFilePath := modFilePath(MainModules.ModRoot(mainModule))
modFile := MainModules.ModFile(mainModule)
var list []*modfile.Require
}
return
}
- gomod := ModFilePath()
- if _, ok := fsys.OverlayPath(gomod); ok {
+ if _, ok := fsys.OverlayPath(modFilePath); ok {
if dirty {
base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
}
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) {
// The go.mod file is already equal to new, possibly as the result of some
// other process.
if !filepath.IsAbs(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.AddError(fmt.Errorf("directory prefix %s outside available modules", base.ShortPath(absDir)))
return
return "", fmt.Errorf("without -mod=vendor, directory %s has no package path", absDir)
}
- readVendorList()
+ readVendorList(mainModule)
pkg := strings.TrimPrefix(suffix, "/vendor/")
if _, ok := vendorPkgModule[pkg]; !ok {
return "", fmt.Errorf("directory %s is not a package listed in vendor/modules.txt", absDir)
tryMod := func(m module.Version) (string, bool) {
var root string
var err error
- if repl, _ := Replacement(m); repl.Path != "" && repl.Version == "" {
+ if repl, replModRoot := Replacement(m); repl.Path != "" && repl.Version == "" {
root = repl.Path
if !filepath.IsAbs(root) {
- root = filepath.Join(ModRoot(), root)
+ root = filepath.Join(replModRoot, root)
}
} else if repl.Path != "" {
root, err = modfetch.DownloadDir(repl)
// For every module other than the target,
// 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,
// so assume that it requires everything.
}
// readVendorList reads the list of vendored modules from vendor/modules.txt.
-func readVendorList() {
+func readVendorList(mainModule module.Version) {
vendorOnce.Do(func() {
vendorList = nil
vendorPkgModule = make(map[string]module.Version)
vendorVersion = make(map[string]string)
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 !errors.Is(err, fs.ErrNotExist) {
base.Fatalf("go: %s", err)
// 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.
func checkVendorConsistency(index *modFileIndex, modFile *modfile.File) {
- readVendorList()
+ readVendorList(MainModules.mustGetSingleMainModule())
pre114 := false
if semver.Compare(index.goVersionV, "v1.14") < 0 {