Skip to content

Commit

Permalink
cmd/go: show an error when a package in a module conflicts with one i…
Browse files Browse the repository at this point in the history
…n std

Fixes #35270

Change-Id: I5d2a04359702be6dc04affb867540091b926bc23
Reviewed-on: https://go-review.googlesource.com/c/go/+/434095
Run-TryBot: xie cui <523516579@qq.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
  • Loading branch information
cuiweixie authored and gopherbot committed Oct 25, 2022
1 parent 2bdb5c5 commit 2dcc9ac
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 19 deletions.
42 changes: 27 additions & 15 deletions src/cmd/go/internal/modload/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
return module.Version{}, "", "", nil, &invalidImportError{importPath: path, err: err}
}

// Check each module on the build list.
var dirs, roots []string
var mods []module.Version

// Is the package in the standard library?
pathIsStd := search.IsStandardImportPath(path)
if pathIsStd && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
Expand All @@ -303,35 +307,43 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
if str.HasPathPrefix(path, "cmd") {
modroot = filepath.Join(cfg.GOROOTsrc, "cmd")
}
return module.Version{}, modroot, dir, nil, nil
dirs = append(dirs, dir)
roots = append(roots, modroot)
mods = append(mods, module.Version{})
}

// -mod=vendor is special.
// Everything must be in the main module or the main module's vendor directory.
if cfg.BuildMod == "vendor" {
mainModule := MainModules.mustGetSingleMainModule()
modRoot := MainModules.ModRoot(mainModule)
mainDir, mainOK, mainErr := dirInModule(path, MainModules.PathPrefix(mainModule), modRoot, true)
if mainOK {
mods = append(mods, mainModule)
dirs = append(dirs, mainDir)
roots = append(roots, modRoot)
}
vendorDir, vendorOK, _ := dirInModule(path, "", filepath.Join(modRoot, "vendor"), false)
if mainOK && vendorOK {
return module.Version{}, modRoot, "", nil, &AmbiguousImportError{importPath: path, Dirs: []string{mainDir, vendorDir}}
if vendorOK {
readVendorList(mainModule)
mods = append(mods, vendorPkgModule[path])
dirs = append(dirs, vendorDir)
roots = append(roots, modRoot)
}
// Prefer to return main directory if there is one,
// Note that we're not checking that the package exists.
// We'll leave that for load.
if !vendorOK && mainDir != "" {
return mainModule, modRoot, mainDir, nil, nil

if len(dirs) > 1 {
return module.Version{}, modRoot, "", nil, &AmbiguousImportError{importPath: path, Dirs: dirs}
}

if mainErr != nil {
return module.Version{}, "", "", nil, mainErr
}
readVendorList(mainModule)
return vendorPkgModule[path], modRoot, vendorDir, nil, nil
}

// Check each module on the build list.
var dirs, roots []string
var mods []module.Version
if len(dirs) == 0 {
return module.Version{}, modRoot, "", nil, &ImportMissingError{Path: path}
}

return mods[0], roots[0], dirs[0], nil, nil
}

// Iterate over possible modules for the path, not all selected modules.
// Iterating over selected modules would make the overall loading time
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/go/testdata/script/mod_go_version_missing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ cmp go.mod go.mod.orig

! go list -mod=vendor all
! stderr '^go: inconsistent vendoring'
stderr 'cannot find package "." in:\n\t.*[/\\]vendor[/\\]example.com[/\\]badedit$'
stderr 'go: finding module for package example.com/badedit'
stderr 'cannot query module due to -mod=vendor'

# When we set -mod=mod, the go version should be updated immediately,
# to the current version, converting the requirements from eager to lazy.
Expand Down
57 changes: 57 additions & 0 deletions src/cmd/go/testdata/script/mod_issue35270.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

cd a
! go build
stderr '^ambiguous import: found package image in multiple modules:\s+image\s+.+\s.+image.+\s$'


cd ../b
! go build -mod=vendor
stderr '^main.go:4:5: ambiguous import: found package image in multiple directories:\s+.+image\s+.+image\s+$'

cd ../c
! go build -mod=vendor
stderr 'main.go:4:5: package p is not in GOROOT'

-- a/go.mod --
module image

-- a/main.go --
package main

func main() {
println("hello world!")
}

-- b/go.mod --
module test

-- b/vendor/image/b.go --
package image
func Add(a, b int) int {
return a + b
}

-- b/main.go --
package main

import (
"image"
)

func main() {
println(image.Add(1,1))
}

-- c/go.mod --
module test

-- c/main.go --
package main

import (
"p"
)

func main() {
println(p.Add(1,1))
}
5 changes: 3 additions & 2 deletions src/cmd/go/testdata/script/mod_std_vendor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ cd broken
! go build -mod=readonly
stderr 'disabled by -mod=readonly'
! go build -mod=vendor
stderr 'cannot find package'
stderr 'hpack'
stderr 'go: finding module for package golang.org/x/net/http2/hpack'
stderr 'http.go:5:2: cannot query module due to -mod=vendor'


# ...even if they explicitly use the "cmd/vendor/" or "vendor/" prefix.
cd ../importcmd
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/testdata/script/mod_vendor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ stderr 'go: module diamondright: can''t resolve module using the vendor director
go list -mod=mod -f {{.Dir}} w
stdout 'src[\\/]w'
! go list -mod=vendor -f {{.Dir}} w
stderr 'src[\\/]vendor[\\/]w'
stderr 'package w is not in GOROOT'

go list -mod=mod -f {{.Dir}} diamondright
stdout 'src[\\/]diamondright'
Expand Down

0 comments on commit 2dcc9ac

Please sign in to comment.