aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/modload/init.go
diff options
context:
space:
mode:
authorMichael Matloob <matloob@golang.org>2021-06-28 15:48:03 -0400
committerMichael Matloob <matloob@golang.org>2021-07-30 22:29:52 +0000
commit47694b59eb30bfe6a1c12a2eaaf631a4e956b9c7 (patch)
tree37f2aa8c6b76c71f7241ca604dbc02261e2ab960 /src/cmd/go/internal/modload/init.go
parent90830699aee61a154e989b2d9f8ce3ff4eabbce1 (diff)
downloadgo-47694b59eb30bfe6a1c12a2eaaf631a4e956b9c7.tar.gz
go-47694b59eb30bfe6a1c12a2eaaf631a4e956b9c7.zip
[dev.cmdgo] cmd/go: provide a more helpful missing required module error in workspaces
If the user is in a workspace, they might not be in the main module they need to run go get from to add a module that provides a missing dependency. Figure out what that module is from the import stack (there might be multiple but we pick according to the stack computed by the loader for errors) and tell the user to cd to that directory first in the message. Change-Id: I7c919eb61ea3dd122334ff1acd2d7e817cad4b25 Reviewed-on: https://go-review.googlesource.com/c/go/+/334940 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.go33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index 53c73cb4a0..18b07cb125 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -89,6 +89,8 @@ type MainModuleSet struct {
modFiles map[module.Version]*modfile.File
+ modContainingCWD module.Version
+
indexMu sync.Mutex
indices map[module.Version]*modFileIndex
}
@@ -184,6 +186,13 @@ func (mms *MainModuleSet) Len() int {
return len(mms.versions)
}
+// ModContainingCWD returns the main module containing the working directory,
+// or module.Version{} if none of the main modules contain the working
+// directory.
+func (mms *MainModuleSet) ModContainingCWD() module.Version {
+ return mms.modContainingCWD
+}
+
var MainModules *MainModuleSet
type Root int
@@ -315,8 +324,7 @@ func Init() {
} else if inWorkspaceMode() {
// We're in workspace mode.
} else {
- modRoots = findModuleRoots(base.Cwd())
- if modRoots == nil {
+ if modRoot := findModuleRoot(base.Cwd()); modRoot == "" {
if cfg.ModFile != "" {
base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.")
}
@@ -328,17 +336,18 @@ func Init() {
// Stay in GOPATH mode.
return
}
- } else if search.InDir(modRoots[0], os.TempDir()) == "." {
+ } else if search.InDir(modRoot, os.TempDir()) == "." {
// If you create /tmp/go.mod for experimenting,
// then any tests that create work directories under /tmp
// will find it and get modules when they're not expecting them.
// It's a bit of a peculiar thing to disallow but quite mysterious
// when it happens. See golang.org/issue/26708.
- modRoots = nil
fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in system temp root %v\n", os.TempDir())
if !mustUseModules {
return
}
+ } else {
+ modRoots = []string{modRoot}
}
}
if cfg.ModFile != "" && !strings.HasSuffix(cfg.ModFile, ".mod") {
@@ -424,12 +433,11 @@ func WillBeEnabled() bool {
return false
}
- if modRoots := findModuleRoots(base.Cwd()); modRoots == nil {
+ if modRoot := findModuleRoot(base.Cwd()); modRoot == "" {
// GO111MODULE is 'auto', and we can't find a module root.
// Stay in GOPATH mode.
return false
- } else if search.InDir(modRoots[0], os.TempDir()) == "." {
- _ = TODOWorkspaces("modRoots[0] is not right here")
+ } else if search.InDir(modRoot, os.TempDir()) == "." {
// If you create /tmp/go.mod for experimenting,
// then any tests that create work directories under /tmp
// will find it and get modules when they're not expecting them.
@@ -856,6 +864,7 @@ func makeMainModules(ms []module.Version, rootDirs []string, modFiles []*modfile
panic("mainModulesCalled with module.Version with non empty Version field: " + fmt.Sprintf("%#v", m))
}
}
+ modRootContainingCWD := findModuleRoot(base.Cwd())
mainModules := &MainModuleSet{
versions: ms[:len(ms):len(ms)],
inGorootSrc: map[module.Version]bool{},
@@ -870,6 +879,10 @@ func makeMainModules(ms []module.Version, rootDirs []string, modFiles []*modfile
mainModules.modFiles[m] = modFiles[i]
mainModules.indices[m] = indices[i]
+ if mainModules.modRoot[m] == modRootContainingCWD {
+ mainModules.modContainingCWD = m
+ }
+
if rel := search.InDir(rootDirs[i], cfg.GOROOTsrc); rel != "" {
mainModules.inGorootSrc[m] = true
if m.Path == "std" {
@@ -1108,7 +1121,7 @@ var altConfigs = []string{
".git/config",
}
-func findModuleRoots(dir string) (roots []string) {
+func findModuleRoot(dir string) (roots string) {
if dir == "" {
panic("dir not set")
}
@@ -1117,7 +1130,7 @@ func findModuleRoots(dir string) (roots []string) {
// Look for enclosing go.mod.
for {
if fi, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
- return []string{dir}
+ return dir
}
d := filepath.Dir(dir)
if d == dir {
@@ -1125,7 +1138,7 @@ func findModuleRoots(dir string) (roots []string) {
}
dir = d
}
- return nil
+ return ""
}
func findWorkspaceFile(dir string) (root string) {