mirror of
https://github.com/golang/go.git
synced 2025-10-20 11:33:18 +00:00
cmd/go/internal/modload: add hint for missing implicit dependency
By default (and with -mod=readonly), the go command imports an error if a package provided by an implicitly required module is imported by a package in the main module. This import requires an update to go.mod: the module must be required explicitly. The package loader now provides a hint that 'go get' should be run on the importing package. This is preferred to 'go get' on the imported package, since that would add an "// indirect" requirement. For #43131 Change-Id: I0b353ce8ac8c4ddf1a9863544dfaf6c1964daf42 Reviewed-on: https://go-review.googlesource.com/c/go/+/279528 Trust: Jay Conrod <jayconrod@google.com> Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
c9fb4eb0a2
commit
223331fc0c
2 changed files with 92 additions and 1 deletions
|
@ -863,12 +863,21 @@ func loadFromRoots(params loaderParams) *loader {
|
||||||
for _, pkg := range ld.pkgs {
|
for _, pkg := range ld.pkgs {
|
||||||
if pkg.mod == Target {
|
if pkg.mod == Target {
|
||||||
for _, dep := range pkg.imports {
|
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
|
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
|
// 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
|
// imports.AnyTags, then we didn't necessarily load every package that
|
||||||
|
|
82
src/cmd/go/testdata/script/mod_get_promote_implicit.txt
vendored
Normal file
82
src/cmd/go/testdata/script/mod_get_promote_implicit.txt
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
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
|
Loading…
Add table
Add a link
Reference in a new issue