return ""
}
+// PackageModuleInfo returns information about the module that provides
+// a given package. If modules are not enabled or if the package is in the
+// standard library or if the package was not successfully loaded with
+// ImportPaths or a similar loading function, nil is returned.
func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic {
if isStandardImportPath(pkgpath) || !Enabled() {
return nil
}
- return moduleInfo(findModule(pkgpath, pkgpath), true)
+ m, ok := findModule(pkgpath)
+ if !ok {
+ return nil
+ }
+ return moduleInfo(m, true)
}
func ModuleInfo(path string) *modinfo.ModulePublic {
if isStandardImportPath(path) || !Enabled() {
return ""
}
-
- target := findModule(path, path)
+ target := mustFindModule(path, path)
mdeps := make(map[module.Version]bool)
for _, dep := range deps {
if !isStandardImportPath(dep) {
- mdeps[findModule(path, dep)] = true
+ mdeps[mustFindModule(path, dep)] = true
}
}
var mods []module.Version
return buf.String()
}
-// findModule returns the module containing the package at path,
-// needed to build the package at target.
-func findModule(target, path string) module.Version {
+// mustFindModule is like findModule, but it calls base.Fatalf if the
+// module can't be found.
+//
+// TODO(jayconrod): remove this. Callers should use findModule and return
+// errors instead of relying on base.Fatalf.
+func mustFindModule(target, path string) module.Version {
pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
if ok {
if pkg.err != nil {
panic("unreachable")
}
+// findModule searches for the module that contains the package at path.
+// If the package was loaded with ImportPaths or one of the other loading
+// functions, its containing module and true are returned. Otherwise,
+// module.Version{} and false are returend.
+func findModule(path string) (module.Version, bool) {
+ if pkg, ok := loaded.pkgCache.Get(path).(*loadPkg); ok {
+ return pkg.mod, pkg.mod != module.Version{}
+ }
+ if path == "command-line-arguments" {
+ return Target, true
+ }
+ return module.Version{}, false
+}
+
func ModInfoProg(info string, isgccgo bool) []byte {
// Inject a variable with the debug information as runtime.modinfo,
// but compile it in package main so that it is specific to the binary.
--- /dev/null
+# This test checks error messages for non-existant packages in module mode.
+# Veries golang.org/issue/35414
+env GO111MODULE=on
+cd $WORK
+
+go list -e -f {{.Error}} .
+stdout 'package \.: no Go files in \$WORK'
+
+go list -e -f {{.Error}} ./empty
+stdout 'package \./empty: no Go files in \$WORK[/\\]empty'
+
+go list -e -f {{.Error}} ./exclude
+stdout 'package \./exclude: build constraints exclude all Go files in \$WORK[/\\]exclude'
+
+go list -e -f {{.Error}} ./missing
+stdout 'package \./missing: cannot find package "." in:\s*\$WORK[/\\]missing'
+
+# use 'go build -n' because 'go list' reports no error.
+! go build -n ./testonly
+stderr 'example.com/m/testonly: no non-test Go files in \$WORK[/\\]testonly'
+
+-- $WORK/go.mod --
+module example.com/m
+
+go 1.14
+
+-- $WORK/empty/empty.txt --
+-- $WORK/exclude/exclude.go --
+// +build exclude
+
+package exclude
+-- $WORK/testonly/testonly_test.go --
+package testonly_test
+-- $WORK/excluded-stdout --
+package ./excluded: cannot find package "." in:
+ $WORK/excluded