if i > 0 {
i-- // rewind over slash in ".../internal"
}
+
+ var where string
if p.Module == nil {
parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
// p is in a module, so make it available based on the import path instead
// of the file path (https://golang.org/issue/23970).
parent := p.ImportPath[:i]
- // TODO(bcmills): In case of replacements, use the module path declared by
- // the replacement module, not the path seen by the user.
- importerPath := (*stk)[len(*stk)-2]
- if strings.HasPrefix(importerPath, parent) {
+ importer := (*stk)[len(*stk)-2]
+ if str.HasPathPrefix(importer, parent) {
return p
}
+ where = " in " + importer
}
// Internal is present, and srcDir is outside parent's tree. Not allowed.
perr := *p
perr.Error = &PackageError{
ImportStack: stk.Copy(),
- Err: "use of internal package " + p.ImportPath + " not allowed",
+ Err: "use of internal package " + p.ImportPath + " not allowed" + where,
}
perr.Incomplete = true
return &perr
return p
}
+ if p.Standard && ModPackageModuleInfo != nil {
+ // Modules must not import vendor packages in the standard library,
+ // but the usual vendor visibility check will not catch them
+ // because the module loader presents them with an ImportPath starting
+ // with "golang_org/" instead of "vendor/".
+ importer := (*stk)[len(*stk)-2]
+ if mod := ModPackageModuleInfo(importer); mod != nil {
+ dir := p.Dir
+ if relDir, err := filepath.Rel(p.Root, p.Dir); err == nil {
+ dir = relDir
+ }
+ if _, ok := FindVendor(filepath.ToSlash(dir)); ok {
+ perr := *p
+ perr.Error = &PackageError{
+ ImportStack: stk.Copy(),
+ Err: "use of vendored package " + path + " not allowed",
+ }
+ perr.Incomplete = true
+ return &perr
+ }
+ }
+ }
+
if perr := disallowVendorVisibility(srcDir, p, stk); perr != p {
return perr
}
env GO111MODULE=on
# golang.org/x/internal should be importable from other golang.org/x modules.
+rm go.mod
go mod -init -module golang.org/x/anything
go build .
# ...but that should not leak into other modules.
! go build ./baddep
-stderr 'use of internal package'
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
# Internal packages in the standard library should not leak into modules.
! go build ./fromstd
-stderr 'use of internal package'
+stderr 'use of internal package internal/testenv not allowed$'
+
+# Packages found via standard-library vendoring should not leak.
+! go build ./fromstdvendor
+stderr 'use of vendored package golang_org/x/net/http/httpguts not allowed$'
# Dependencies should be able to use their own internal modules...
# ... but other modules should not, even if they have transitive dependencies.
! go build .
-stderr 'use of internal package'
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx$'
# And transitive dependencies still should not leak.
! go build ./baddep
-stderr 'use of internal package'
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
+
+
+# Replacing an internal module should keep it internal to the same paths.
+rm go.mod
+go mod -init -module golang.org/notx
+go mod -replace golang.org/x/internal=./replace/golang.org/notx/internal
+go build ./throughdep
+
+! go build ./baddep
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
+
+go mod -replace golang.org/x/internal=./vendor/golang.org/x/internal
+go build ./throughdep
+
+! go build ./baddep
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
-- useinternal.go --
-- fromstd/useinternal.go --
package fromstd
import _ "internal/testenv"
+
+-- fromstdvendor/useinternal.go --
+package fromstdvendor
+import _ "golang_org/x/net/http/httpguts"
+
+-- replace/golang.org/notx/internal/go.mod --
+module golang.org/x/internal
+
+-- replace/golang.org/notx/internal/subtle/subtle.go --
+package subtle
+// Ha ha! Nothing here!
+
+-- vendor/golang.org/x/internal/go.mod --
+module golang.org/x/internal
+
+-- vendor/golang.org/x/internal/subtle/subtle.go --
+package subtle
+// Ha ha! Nothing here!