} else {
// p is in a module, so make it available based on the importer's import path instead
// of the file path (https://golang.org/issue/23970).
- if importerPath == "." {
+ if importer.Internal.CmdlineFiles {
// The importer is a list of command-line files.
// Pretend that the import path is the import path of the
// directory containing them.
+ // If the directory is outside the main module, this will resolve to ".",
+ // which is not a prefix of any valid module.
importerPath = ModDirImportPath(importer.Dir)
}
parentOfInternal := p.ImportPath[:i]
}
if cfg.ModulesEnabled {
- if !p.Internal.CmdlineFiles {
- p.Module = ModPackageModuleInfo(p.ImportPath)
+ mainPath := p.ImportPath
+ if p.Internal.CmdlineFiles {
+ mainPath = "command-line-arguments"
}
+ p.Module = ModPackageModuleInfo(mainPath)
if p.Name == "main" {
- p.Internal.BuildInfo = ModPackageBuildInfo(p.ImportPath, p.Deps)
+ p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps)
}
}
}
}
bp, err := ctxt.ImportDir(dir, 0)
- if ModDirImportPath != nil {
- // Use the effective import path of the directory
- // for deciding visibility during pkg.load.
- bp.ImportPath = ModDirImportPath(dir)
- }
pkg := new(Package)
pkg.Internal.Local = true
pkg.Internal.CmdlineFiles = true
"internal/goroot"
"os"
"path/filepath"
+ "runtime/debug"
"strings"
)
Path: m.Path,
Version: m.Version,
Main: true,
- Dir: ModRoot(),
- GoMod: filepath.Join(ModRoot(), "go.mod"),
}
- if modFile.Go != nil {
- info.GoVersion = modFile.Go.Version
+ if HasModRoot() {
+ info.Dir = ModRoot()
+ info.GoMod = filepath.Join(info.Dir, "go.mod")
+ if modFile.Go != nil {
+ info.GoVersion = modFile.Go.Version
+ }
}
return info
}
if isStandardImportPath(path) || !Enabled() {
return ""
}
+
target := findModule(path, path)
mdeps := make(map[module.Version]bool)
for _, dep := range deps {
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 {
- // TODO: This should use loaded.
- if path == "." {
- return buildList[0]
+ pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
+ if ok {
+ if pkg.err != nil {
+ base.Fatalf("build %v: cannot load %v: %v", target, path, pkg.err)
+ }
+ return pkg.mod
}
- if cfg.BuildMod == "vendor" {
- readVendorList()
- return vendorMap[path]
+
+ if path == "command-line-arguments" {
+ return Target
}
- for _, mod := range buildList {
- if maybeInModule(path, mod.Path) {
- return mod
- }
+
+ if printStackInDie {
+ debug.PrintStack()
}
base.Fatalf("build %v: cannot find module for path %v", target, path)
panic("unreachable")
Init()
if modRoot == "" {
- Target = module.Version{Path: "main"}
+ Target = module.Version{Path: "command-line-arguments"}
buildList = []module.Version{Target}
return
}
cd $GOPATH/src/x/y
go env GOMOD
stdout 'NUL|/dev/null'
-! go list -m
-stderr 'cannot find main module'
+go list -m
+stdout '^command-line-arguments$'
cd $GOPATH/foo
go env GOMOD
! go get -d llvm.org/llvm/bindings/go/llvm
stderr 'ReadZip not implemented for svn'
! go install .
-# TODO(bcmills): The error message here should mention ReadZip.
-stderr 'cannot find module for path llvm.org'
+stderr 'ReadZip not implemented for svn'
-- go.mod --
module golang/go/issues/28943/main
# which is not in a module.
! go list
stderr 'cannot find main module'
-! go list -m
-stderr 'cannot find main module'
+go list -m
+stdout '^command-line-arguments$'
# 'go list' in the working directory should fail even if there is a a 'package
# main' present: without a main module, we do not know its package path.
! go list ./foo
stderr 'can only use path@version syntax with'
+# 'go fmt' should be able to format files outside of a module.
+go fmt foo/foo.go
+
+
# The remainder of the test checks dependencies by linking and running binaries.
[short] stop
# 'go run' should use 'main' as the effective module and import path.
go run ./foo/foo.go
-stdout 'path is \.$'
-stdout 'main is main \(devel\)'
+stdout 'path is command-line-arguments$'
+stdout 'main is command-line-arguments \(devel\)'
stdout 'using example.com/version v1.1.0'
# 'go generate' should work with file arguments.
--- /dev/null
+env GO111MODULE=on
+
+cd foo
+
+# Testing an explicit source file should use the same import visibility as the
+# package in the same directory.
+go list -test -deps
+go list -test -deps foo_test.go
+
+# If the file is inside the main module's vendor directory, it should have
+# visibility based on the vendor-relative import path.
+mkdir vendor/example.com/foo
+cp foo_test.go vendor/example.com/foo
+go list -test -deps vendor/example.com/foo/foo_test.go
+
+# If the file is outside the main module entirely, it should be treated as outside.
+cp foo_test.go ../foo_test.go
+! go list -test -deps ../foo_test.go
+stderr 'use of internal package'
+
+-- foo/go.mod --
+module example.com/foo
+require example.com/internal v0.0.0
+replace example.com/internal => ../internal
+
+-- foo/internal.go --
+package foo
+import _ "example.com/internal"
+
+-- foo/foo_test.go --
+package foo_test
+
+import (
+ "testing"
+ "example.com/internal"
+)
+
+func TestHacksEnabled(t *testing.T) {
+ if !internal.Hacks {
+ t.Fatal("hacks not enabled")
+ }
+}
+
+-- internal/go.mod --
+module example.com/internal
+
+-- internal/internal.go --
+package internal
+const Hacks = true