for _, pkg := range ld.pkgs {
if pkg.mod == Target {
for _, dep := range pkg.imports {
- if dep.mod.Path != "" {
+ if dep.mod.Path != "" && dep.mod.Path != Target.Path && index != nil {
+ _, explicit := index.require[dep.mod]
+ if allowWriteGoMod && cfg.BuildMod == "readonly" && !explicit {
+ // TODO(#40775): attach error to package instead of using
+ // base.Errorf. Ideally, 'go list' should not fail because of this,
+ // but today, LoadPackages calls WriteGoMod unconditionally, which
+ // would fail with a less clear message.
+ base.Errorf("go: %[1]s: package %[2]s imported from implicitly required module; try 'go get -d %[1]s' to add missing requirements", pkg.path, dep.path)
+ }
ld.direct[dep.mod.Path] = true
}
}
}
}
+ base.ExitIfErrors()
// If we didn't scan all of the imports from the main module, or didn't use
// imports.AnyTags, then we didn't necessarily load every package that
--- /dev/null
+cp go.mod.orig go.mod
+
+# If we list a package in an implicit dependency imported from the main module,
+# we should get an error because the dependency should have an explicit
+# requirement.
+go list -m indirect-with-pkg
+stdout '^indirect-with-pkg v1.0.0 => ./indirect-with-pkg$'
+! go list ./use-indirect
+stderr '^go: m/use-indirect: package indirect-with-pkg imported from implicitly required module; try ''go get -d m/use-indirect'' to add missing requirements$'
+
+# We can promote the implicit requirement by getting the importing package,
+# as hinted.
+go get -d m/use-indirect
+cmp go.mod go.mod.use
+cp go.mod.orig go.mod
+
+-- go.mod.orig --
+module m
+
+go 1.16
+
+require direct v1.0.0
+
+replace (
+ direct v1.0.0 => ./direct
+ indirect-with-pkg v1.0.0 => ./indirect-with-pkg
+ indirect-without-pkg v1.0.0 => ./indirect-without-pkg
+)
+-- go.mod.use --
+module m
+
+go 1.16
+
+require (
+ direct v1.0.0
+ indirect-with-pkg v1.0.0
+)
+
+replace (
+ direct v1.0.0 => ./direct
+ indirect-with-pkg v1.0.0 => ./indirect-with-pkg
+ indirect-without-pkg v1.0.0 => ./indirect-without-pkg
+)
+-- go.mod.indirect --
+module m
+
+go 1.16
+
+require (
+ direct v1.0.0
+ indirect-with-pkg v1.0.0 // indirect
+ indirect-without-pkg v1.0.0 // indirect
+)
+
+replace (
+ direct v1.0.0 => ./direct
+ indirect-with-pkg v1.0.0 => ./indirect-with-pkg
+ indirect-without-pkg v1.0.0 => ./indirect-without-pkg
+)
+-- use-indirect/use-indirect.go --
+package use
+
+import _ "indirect-with-pkg"
+-- direct/go.mod --
+module direct
+
+go 1.16
+
+require (
+ indirect-with-pkg v1.0.0
+ indirect-without-pkg v1.0.0
+)
+-- indirect-with-pkg/go.mod --
+module indirect-with-pkg
+
+go 1.16
+-- indirect-with-pkg/p.go --
+package p
+-- indirect-without-pkg/go.mod --
+module indirect-without-pkg
+
+go 1.16