aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go
diff options
context:
space:
mode:
authorJay Conrod <jayconrod@google.com>2021-07-28 13:17:08 -0700
committerJay Conrod <jayconrod@google.com>2021-07-28 13:17:10 -0700
commit47cdfa95ae85919c6f050a87b54c69f64c2666fc (patch)
tree5624b59820907e60527401f99c75f47a66aa019e /src/cmd/go
parent176baafd5b6d968fc0df25b344ffe826e47e6879 (diff)
parent9eee0ed4391942c73157c868a9ddcfdef48982f9 (diff)
downloadgo-47cdfa95ae85919c6f050a87b54c69f64c2666fc.tar.gz
go-47cdfa95ae85919c6f050a87b54c69f64c2666fc.zip
[dev.cmdgo] all: merge master (9eee0ed) into dev.cmdgo
Conflicts: - src/cmd/go/internal/modload/init.go - src/cmd/go/internal/modload/load.go Merge List: + 2021-07-28 9eee0ed439 cmd/go: fix go.mod file name printed in error messages for replacements + 2021-07-28 b39e0f461c runtime: don't crash on nil pointers in checkptrAlignment + 2021-07-27 7cd10c1149 cmd/go: use .mod instead of .zip to determine if version has go.mod file + 2021-07-27 c8cf0f74e4 cmd/go: add missing flag in UsageLine + 2021-07-27 7ba8e796c9 testing: clarify T.Name returns a distinct name of the running test + 2021-07-27 33ff155970 go/types: preserve untyped constants on the RHS of a shift expression + 2021-07-26 840e583ff3 runtime: correct variable name in comment + 2021-07-26 bfbb288574 runtime: remove adjustTimers counter + 2021-07-26 9c81fd53b3 cmd/vet: add missing copyright header + 2021-07-26 ecaa6816bf doc: clarify non-nil zero length slice to array pointer conversion + 2021-07-26 1868f8296e crypto/x509: update iOS bundled roots to version 55188.120.1.0.1 + 2021-07-25 849b791129 spec: use consistent capitalization for rune literal hex constants + 2021-07-23 0914646ab9 doc/1.17: fix two dead rfc links + 2021-07-22 052da5717e cmd/compile: do not change field offset in ABI analysis + 2021-07-22 798ec73519 runtime: don't clear timerModifiedEarliest if adjustTimers is 0 + 2021-07-22 fdb45acd1f runtime: move mem profile sampling into m-acquired section + 2021-07-21 3e48c0381f reflect: add missing copyright header + 2021-07-21 48c88f1b1b reflect: add Value.CanConvert + 2021-07-20 9e26569293 cmd/go: don't add C compiler ID to hash for standard library + 2021-07-20 d568e6e075 runtime/debug: skip TestPanicOnFault on netbsd/arm + 2021-07-19 c8f4e6152d spec: correct example comment in Conversions from slice to array + 2021-07-19 1d91551b73 time: correct typo in documentation for UnixMicro + 2021-07-19 404127c30f cmd/compile: fix off-by-one error in traceback argument counting + 2021-07-19 6298cfe672 cmd/compile: fix typo in fatal message of builtinCall + 2021-07-19 49402bee36 cmd/{compile,link}: fix bug in map.zero handling + 2021-07-18 a66190ecee test/bench/go1: fix size for RegexpMatchMedium_32 + 2021-07-18 650fc2117a text/scanner: use Go convention in Position doc comment + 2021-07-16 aa4e0f528e net/http: correct capitalization in cancelTimeBody comment + 2021-07-15 0941dbca6a testing: clarify in docs that TestMain is advanced + 2021-07-15 69728ead87 cmd/go: update error messages in tests to match CL 332573 + 2021-07-15 c1cc9f9c3d cmd/compile: fix lookup package of redeclared dot import symbol + 2021-07-15 21a04e3335 doc/go1.17: mention GOARCH=loong64 + 2021-07-14 2b00a54baf go/build, runtime/internal/sys: reserve GOARCH=loong64 + 2021-07-14 60ddf42b46 cmd/go: change link in error message from /wiki to /doc. + 2021-07-13 d8f348a589 cmd/go: remove a duplicated word from 'go help mod graph' + 2021-07-12 a98589711d crypto/tls: test key type when casting + 2021-07-12 cfbd73ba33 doc/go1.17: editing pass over the "Compiler" section + 2021-07-09 ab4085ce84 runtime/pprof: call runtime.GC twice in memory profile test + 2021-07-08 296ddf2a93 net: filter bad names from Lookup functions instead of hard failing + 2021-07-08 ce76298ee7 Update oudated comment + 2021-07-08 2ca44fe221 doc/go1.17: linkify time.UnixMilli and time.UnixMicro + 2021-07-07 5c59e11f5e cmd/compile: remove special-casing of blank in types.sconv{,2} + 2021-07-07 b003a8b1ae cmd/compile: optimize types.sconv + 2021-07-07 11f5df2d67 cmd/compile: extract pkgqual from symfmt + 2021-07-07 991fd381d5 cmd/go: don't lock .mod and .sum files for read in overlay + 2021-07-07 186a3bb4b0 cmd/go/internal/modfetch/codehost: skip hg tests if no hg binary is present + 2021-07-07 00c00558e1 cmd/go/internal/modload: remove unused functions + 2021-07-07 f264879f74 cmd/go/internal/modload: fix an apparent typo in the AutoRoot comment + 2021-07-07 c96833e5ba doc: remove stale comment about arm64 port Change-Id: Ide5fb43a0fcb5d998386ed60dfd6ced241238a44
Diffstat (limited to 'src/cmd/go')
-rw-r--r--src/cmd/go/alldocs.go6
-rw-r--r--src/cmd/go/go_test.go32
-rw-r--r--src/cmd/go/internal/lockedfile/lockedfile_filelock.go3
-rw-r--r--src/cmd/go/internal/lockedfile/lockedfile_plan9.go6
-rw-r--r--src/cmd/go/internal/modcmd/edit.go2
-rw-r--r--src/cmd/go/internal/modcmd/graph.go2
-rw-r--r--src/cmd/go/internal/modcmd/init.go2
-rw-r--r--src/cmd/go/internal/modfetch/codehost/git_test.go49
-rw-r--r--src/cmd/go/internal/modfetch/coderepo.go23
-rw-r--r--src/cmd/go/internal/modfetch/fetch.go17
-rw-r--r--src/cmd/go/internal/modload/init.go9
-rw-r--r--src/cmd/go/internal/modload/load.go39
-rw-r--r--src/cmd/go/internal/modload/modfile.go78
-rw-r--r--src/cmd/go/internal/modload/query.go34
-rw-r--r--src/cmd/go/internal/work/exec.go11
-rw-r--r--src/cmd/go/testdata/script/mod_overlay.txt10
-rw-r--r--src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_update_sum_readonly.txt34
21 files changed, 226 insertions, 139 deletions
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index fb99dccb46..af1ee39684 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1087,7 +1087,7 @@
//
// Usage:
//
-// go mod edit [editing flags] [go.mod]
+// go mod edit [editing flags] [-fmt|-print|-json] [go.mod]
//
// Edit provides a command-line interface for editing go.mod,
// for use primarily by tools or scripts. It reads only go.mod;
@@ -1202,7 +1202,7 @@
// and one of its requirements. Each module is identified as a string of the form
// path@version, except for the main module, which has no @version suffix.
//
-// The -go flag causes graph to report the module graph as loaded by by the
+// The -go flag causes graph to report the module graph as loaded by the
// given Go version, instead of the version indicated by the 'go' directive
// in the go.mod file.
//
@@ -1213,7 +1213,7 @@
//
// Usage:
//
-// go mod init [module]
+// go mod init [module-path]
//
// Init initializes and writes a new go.mod file in the current directory, in
// effect creating a new module rooted at the current directory. The go.mod file
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index c0c86ab9f5..6ce276537b 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2848,3 +2848,35 @@ func TestExecInDeletedDir(t *testing.T) {
// `go version` should not fail
tg.run("version")
}
+
+// A missing C compiler should not force the net package to be stale.
+// Issue 47215.
+func TestMissingCC(t *testing.T) {
+ if !canCgo {
+ t.Skip("test is only meaningful on systems with cgo")
+ }
+ cc := os.Getenv("CC")
+ if cc == "" {
+ cc = "gcc"
+ }
+ if filepath.IsAbs(cc) {
+ t.Skipf(`"CC" (%s) is an absolute path`, cc)
+ }
+ _, err := exec.LookPath(cc)
+ if err != nil {
+ t.Skipf(`"CC" (%s) not on PATH`, cc)
+ }
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ netStale, _ := tg.isStale("net")
+ if netStale {
+ t.Skip(`skipping test because "net" package is currently stale`)
+ }
+
+ tg.setenv("PATH", "") // No C compiler on PATH.
+ netStale, _ = tg.isStale("net")
+ if netStale {
+ t.Error(`clearing "PATH" causes "net" to be stale`)
+ }
+}
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
index 729df5c681..e4923f6876 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
@@ -11,7 +11,6 @@ import (
"io/fs"
"os"
- "cmd/go/internal/fsys"
"cmd/go/internal/lockedfile/internal/filelock"
)
@@ -21,7 +20,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
// calls for Linux and Windows anyway, so it's simpler to use that approach
// consistently.
- f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
+ f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
if err != nil {
return nil, err
}
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
index 3d4b97d78e..979118b10a 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
@@ -13,8 +13,6 @@ import (
"os"
"strings"
"time"
-
- "cmd/go/internal/fsys"
)
// Opening an exclusive-use file returns an error.
@@ -59,7 +57,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
// If the file was unpacked or created by some other program, it might not
// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
// can be confident that a successful OpenFile implies exclusive use.
- if fi, err := fsys.Stat(name); err == nil {
+ if fi, err := os.Stat(name); err == nil {
if fi.Mode()&fs.ModeExclusive == 0 {
if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
return nil, err
@@ -72,7 +70,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
nextSleep := 1 * time.Millisecond
const maxSleep = 500 * time.Millisecond
for {
- f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
+ f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
if err == nil {
return f, nil
}
diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go
index e856e7c630..bb3d521092 100644
--- a/src/cmd/go/internal/modcmd/edit.go
+++ b/src/cmd/go/internal/modcmd/edit.go
@@ -25,7 +25,7 @@ import (
)
var cmdEdit = &base.Command{
- UsageLine: "go mod edit [editing flags] [go.mod]",
+ UsageLine: "go mod edit [editing flags] [-fmt|-print|-json] [go.mod]",
Short: "edit go.mod from tools or scripts",
Long: `
Edit provides a command-line interface for editing go.mod,
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index 5ef1d4ed04..2cbabae044 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -26,7 +26,7 @@ in text form. Each line in the output has two space-separated fields: a module
and one of its requirements. Each module is identified as a string of the form
path@version, except for the main module, which has no @version suffix.
-The -go flag causes graph to report the module graph as loaded by by the
+The -go flag causes graph to report the module graph as loaded by the
given Go version, instead of the version indicated by the 'go' directive
in the go.mod file.
diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go
index 73cc282d81..958c3066ac 100644
--- a/src/cmd/go/internal/modcmd/init.go
+++ b/src/cmd/go/internal/modcmd/init.go
@@ -13,7 +13,7 @@ import (
)
var cmdInit = &base.Command{
- UsageLine: "go mod init [module]",
+ UsageLine: "go mod init [module-path]",
Short: "initialize new module in current directory",
Long: `
Init initializes and writes a new go.mod file in the current directory, in
diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go
index 89a73baad9..a684fa1a9b 100644
--- a/src/cmd/go/internal/modfetch/codehost/git_test.go
+++ b/src/cmd/go/internal/modfetch/codehost/git_test.go
@@ -8,7 +8,6 @@ import (
"archive/zip"
"bytes"
"flag"
- "fmt"
"internal/testenv"
"io"
"io/fs"
@@ -47,12 +46,6 @@ var altRepos = []string{
var localGitRepo string
func testMain(m *testing.M) int {
- if _, err := exec.LookPath("git"); err != nil {
- fmt.Fprintln(os.Stderr, "skipping because git binary not found")
- fmt.Println("PASS")
- return 0
- }
-
dir, err := os.MkdirTemp("", "gitrepo-test-")
if err != nil {
log.Fatal(err)
@@ -60,23 +53,25 @@ func testMain(m *testing.M) int {
defer os.RemoveAll(dir)
if testenv.HasExternalNetwork() && testenv.HasExec() {
- // Clone gitrepo1 into a local directory.
- // If we use a file:// URL to access the local directory,
- // then git starts up all the usual protocol machinery,
- // which will let us test remote git archive invocations.
- localGitRepo = filepath.Join(dir, "gitrepo2")
- if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
- log.Fatal(err)
- }
- if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
- log.Fatal(err)
+ if _, err := exec.LookPath("git"); err == nil {
+ // Clone gitrepo1 into a local directory.
+ // If we use a file:// URL to access the local directory,
+ // then git starts up all the usual protocol machinery,
+ // which will let us test remote git archive invocations.
+ localGitRepo = filepath.Join(dir, "gitrepo2")
+ if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
+ log.Fatal(err)
+ }
+ if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
+ log.Fatal(err)
+ }
}
}
return m.Run()
}
-func testRepo(remote string) (Repo, error) {
+func testRepo(t *testing.T, remote string) (Repo, error) {
if remote == "localGitRepo" {
// Convert absolute path to file URL. LocalGitRepo will not accept
// Windows absolute paths because they look like a host:path remote.
@@ -87,15 +82,17 @@ func testRepo(remote string) (Repo, error) {
} else {
url = "file:///" + filepath.ToSlash(localGitRepo)
}
+ testenv.MustHaveExecPath(t, "git")
return LocalGitRepo(url)
}
- kind := "git"
+ vcs := "git"
for _, k := range []string{"hg"} {
if strings.Contains(remote, "/"+k+"/") {
- kind = k
+ vcs = k
}
}
- return NewRepo(kind, remote)
+ testenv.MustHaveExecPath(t, vcs)
+ return NewRepo(vcs, remote)
}
var tagsTests = []struct {
@@ -116,7 +113,7 @@ func TestTags(t *testing.T) {
for _, tt := range tagsTests {
f := func(t *testing.T) {
- r, err := testRepo(tt.repo)
+ r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@@ -168,7 +165,7 @@ func TestLatest(t *testing.T) {
for _, tt := range latestTests {
f := func(t *testing.T) {
- r, err := testRepo(tt.repo)
+ r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@@ -221,7 +218,7 @@ func TestReadFile(t *testing.T) {
for _, tt := range readFileTests {
f := func(t *testing.T) {
- r, err := testRepo(tt.repo)
+ r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@@ -412,7 +409,7 @@ func TestReadZip(t *testing.T) {
for _, tt := range readZipTests {
f := func(t *testing.T) {
- r, err := testRepo(tt.repo)
+ r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@@ -581,7 +578,7 @@ func TestStat(t *testing.T) {
for _, tt := range statTests {
f := func(t *testing.T) {
- r, err := testRepo(tt.repo)
+ r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
index f817a04583..dfef9f73c2 100644
--- a/src/cmd/go/internal/modfetch/coderepo.go
+++ b/src/cmd/go/internal/modfetch/coderepo.go
@@ -864,22 +864,25 @@ func (r *codeRepo) GoMod(version string) (data []byte, err error) {
data, err = r.code.ReadFile(rev, path.Join(dir, "go.mod"), codehost.MaxGoMod)
if err != nil {
if os.IsNotExist(err) {
- return r.legacyGoMod(rev, dir), nil
+ return LegacyGoMod(r.modPath), nil
}
return nil, err
}
return data, nil
}
-func (r *codeRepo) legacyGoMod(rev, dir string) []byte {
- // We used to try to build a go.mod reflecting pre-existing
- // package management metadata files, but the conversion
- // was inherently imperfect (because those files don't have
- // exactly the same semantics as go.mod) and, when done
- // for dependencies in the middle of a build, impossible to
- // correct. So we stopped.
- // Return a fake go.mod that simply declares the module path.
- return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(r.modPath)))
+// LegacyGoMod generates a fake go.mod file for a module that doesn't have one.
+// The go.mod file contains a module directive and nothing else: no go version,
+// no requirements.
+//
+// We used to try to build a go.mod reflecting pre-existing
+// package management metadata files, but the conversion
+// was inherently imperfect (because those files don't have
+// exactly the same semantics as go.mod) and, when done
+// for dependencies in the middle of a build, impossible to
+// correct. So we stopped.
+func LegacyGoMod(modPath string) []byte {
+ return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(modPath)))
}
func (r *codeRepo) modPrefix(rev string) string {
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index 7b3525e914..408b2860ad 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -22,6 +22,7 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
+ "cmd/go/internal/fsys"
"cmd/go/internal/lockedfile"
"cmd/go/internal/par"
"cmd/go/internal/robustio"
@@ -416,7 +417,18 @@ func initGoSum() (bool, error) {
goSum.m = make(map[module.Version][]string)
goSum.status = make(map[modSum]modSumStatus)
- data, err := lockedfile.Read(GoSumFile)
+ var (
+ data []byte
+ err error
+ )
+ if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
+ // Don't lock go.sum if it's part of the overlay.
+ // On Plan 9, locking requires chmod, and we don't want to modify any file
+ // in the overlay. See #44700.
+ data, err = os.ReadFile(actualSumFile)
+ } else {
+ data, err = lockedfile.Read(GoSumFile)
+ }
if err != nil && !os.IsNotExist(err) {
return false, err
}
@@ -718,6 +730,9 @@ Outer:
if readonly {
return ErrGoSumDirty
}
+ if _, ok := fsys.OverlayPath(GoSumFile); ok {
+ base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
+ }
// Make a best-effort attempt to acquire the side lock, only to exclude
// previous versions of the 'go' command from making simultaneous edits.
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index 00dfc8b2dc..a3337d6d23 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -191,7 +191,7 @@ type Root int
const (
// AutoRoot is the default for most commands. modload.Init will look for
// a go.mod file in the current directory or any parent. If none is found,
- // modules may be disabled (GO111MODULE=on) or commands may run in a
+ // modules may be disabled (GO111MODULE=auto) or commands may run in a
// limited module mode.
AutoRoot Root = iota
@@ -1364,6 +1364,13 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
}
return
}
+ gomod := ModFilePath()
+ if _, ok := fsys.OverlayPath(gomod); ok {
+ if dirty {
+ base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
+ }
+ return
+ }
new, err := modFile.Format()
if err != nil {
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index e7b03b08e9..57b729f78c 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -715,20 +715,6 @@ func (mms *MainModuleSet) DirImportPath(ctx context.Context, dir string) (path s
return ".", module.Version{}
}
-// TargetPackages returns the list of packages in the target (top-level) module
-// matching pattern, which may be relative to the working directory, under all
-// build tag settings.
-func TargetPackages(ctx context.Context, pattern string) *search.Match {
- // TargetPackages is relative to the main module, so ensure that the main
- // module is a thing that can contain packages.
- LoadModFile(ctx) // Sets Target.
- ModRoot() // Emits an error if Target cannot contain packages.
-
- m := search.NewMatch(pattern)
- matchPackages(ctx, m, imports.AnyTags(), omitStd, MainModules.Versions())
- return m
-}
-
// ImportMap returns the actual package import path
// for an import path found in source code.
// If the given import path does not appear in the source code
@@ -760,29 +746,6 @@ func PackageModule(path string) module.Version {
return pkg.mod
}
-// PackageImports returns the imports for the package named by the import path.
-// Test imports will be returned as well if tests were loaded for the package
-// (i.e., if "all" was loaded or if LoadTests was set and the path was matched
-// by a command line argument). PackageImports will return nil for
-// unknown package paths.
-func PackageImports(path string) (imports, testImports []string) {
- pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
- if !ok {
- return nil, nil
- }
- imports = make([]string, len(pkg.imports))
- for i, p := range pkg.imports {
- imports[i] = p.path
- }
- if pkg.test != nil {
- testImports = make([]string, len(pkg.test.imports))
- for i, p := range pkg.test.imports {
- testImports[i] = p.path
- }
- }
- return imports, testImports
-}
-
// Lookup returns the source directory, import path, and any loading error for
// the package at path as imported from the package in parentDir.
// Lookup requires that one of the Load functions in this package has already
@@ -1883,7 +1846,7 @@ func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements)
fmt.Fprintf(os.Stderr, "If reproducibility with go %s is not needed:\n\tgo mod tidy%s -compat=%s\n", ld.TidyCompatibleVersion, goFlag, ld.GoVersion)
// TODO(#46141): Populate the linked wiki page.
- fmt.Fprintf(os.Stderr, "For other options, see:\n\thttps://golang.org/wiki/PruningModules\n")
+ fmt.Fprintf(os.Stderr, "For other options, see:\n\thttps://golang.org/doc/modules/pruning\n")
}
mg, err := rs.Graph(ctx)
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
index 79126a46b5..31e79a3646 100644
--- a/src/cmd/go/internal/modload/modfile.go
+++ b/src/cmd/go/internal/modload/modfile.go
@@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
+ "os"
"path/filepath"
"strings"
"sync"
@@ -15,6 +16,7 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
+ "cmd/go/internal/fsys"
"cmd/go/internal/lockedfile"
"cmd/go/internal/modfetch"
"cmd/go/internal/par"
@@ -614,39 +616,14 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
}
c := rawGoModSummaryCache.Do(m, func() interface{} {
summary := new(modFileSummary)
- var f *modfile.File
- if m.Version == "" {
- // m is a replacement module with only a file path.
- dir := m.Path
- if !filepath.IsAbs(dir) {
- dir = filepath.Join(ModRoot(), dir)
- }
- gomod := filepath.Join(dir, "go.mod")
-
- data, err := lockedfile.Read(gomod)
- if err != nil {
- return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
- }
- f, err = modfile.ParseLax(gomod, data, nil)
- if err != nil {
- return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))}
- }
- } else {
- if !semver.IsValid(m.Version) {
- // Disallow the broader queries supported by fetch.Lookup.
- base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
- }
-
- data, err := modfetch.GoMod(m.Path, m.Version)
- if err != nil {
- return cached{nil, err}
- }
- f, err = modfile.ParseLax("go.mod", data, nil)
- if err != nil {
- return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))}
- }
+ name, data, err := rawGoModData(m)
+ if err != nil {
+ return cached{nil, err}
+ }
+ f, err := modfile.ParseLax(name, data, nil)
+ if err != nil {
+ return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(name), err))}
}
-
if f.Module != nil {
summary.module = f.Module.Mod
summary.deprecated = f.Module.Deprecated
@@ -682,6 +659,43 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result
+// rawGoModData returns the content of the go.mod file for module m, ignoring
+// all replacements that may apply to m.
+//
+// rawGoModData cannot be used on the Target module.
+//
+// Unlike rawGoModSummary, rawGoModData does not cache its results in memory.
+// Use rawGoModSummary instead unless you specifically need these bytes.
+func rawGoModData(m module.Version) (name string, data []byte, err error) {
+ if m.Version == "" {
+ // m is a replacement module with only a file path.
+ dir := m.Path
+ if !filepath.IsAbs(dir) {
+ dir = filepath.Join(ModRoot(), dir)
+ }
+ name = filepath.Join(dir, "go.mod")
+ if gomodActual, ok := fsys.OverlayPath(name); ok {
+ // Don't lock go.mod if it's part of the overlay.
+ // On Plan 9, locking requires chmod, and we don't want to modify any file
+ // in the overlay. See #44700.
+ data, err = os.ReadFile(gomodActual)
+ } else {
+ data, err = lockedfile.Read(gomodActual)
+ }
+ if err != nil {
+ return "", nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(name), err))
+ }
+ } else {
+ if !semver.IsValid(m.Version) {
+ // Disallow the broader queries supported by fetch.Lookup.
+ base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
+ }
+ name = "go.mod"
+ data, err = modfetch.GoMod(m.Path, m.Version)
+ }
+ return name, data, err
+}
+
// queryLatestVersionIgnoringRetractions looks up the latest version of the
// module with the given path without considering retracted or excluded
// versions.
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index 05ef0a9c48..ce8a4682f0 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -5,13 +5,13 @@
package modload
import (
+ "bytes"
"context"
"errors"
"fmt"
"io/fs"
"os"
pathpkg "path"
- "path/filepath"
"sort"
"strings"
"sync"
@@ -933,8 +933,8 @@ func (e *PackageNotInModuleError) ImportPath() string {
return ""
}
-// ModuleHasRootPackage returns whether module m contains a package m.Path.
-func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
+// moduleHasRootPackage returns whether module m contains a package m.Path.
+func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
needSum := false
root, isLocal, err := fetch(ctx, m, needSum)
if err != nil {
@@ -944,14 +944,32 @@ func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
return ok, err
}
-func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) {
- needSum := false
- root, _, err := fetch(ctx, m, needSum)
+// versionHasGoMod returns whether a version has a go.mod file.
+//
+// versionHasGoMod fetches the go.mod file (possibly a fake) and true if it
+// contains anything other than a module directive with the same path. When a
+// module does not have a real go.mod file, the go command acts as if it had one
+// that only contained a module directive. Normal go.mod files created after
+// 1.12 at least have a go directive.
+//
+// This function is a heuristic, since it's possible to commit a file that would
+// pass this test. However, we only need a heurstic for determining whether
+// +incompatible versions may be "latest", which is what this function is used
+// for.
+//
+// This heuristic is useful for two reasons: first, when using a proxy,
+// this lets us fetch from the .mod endpoint which is much faster than the .zip
+// endpoint. The .mod file is used anyway, even if the .zip file contains a
+// go.mod with different content. Second, if we don't fetch the .zip, then
+// we don't need to verify it in go.sum. This makes 'go list -m -u' faster
+// and simpler.
+func versionHasGoMod(_ context.Context, m module.Version) (bool, error) {
+ _, data, err := rawGoModData(m)
if err != nil {
return false, err
}
- fi, err := os.Stat(filepath.Join(root, "go.mod"))
- return err == nil && !fi.IsDir(), nil
+ isFake := bytes.Equal(data, modfetch.LegacyGoMod(m.Path))
+ return !isFake, nil
}
// A versionRepo is a subset of modfetch.Repo that can report information about
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index b506b83656..5a225fb9f1 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -252,8 +252,15 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
ccExe := b.ccExe()
fmt.Fprintf(h, "CC=%q %q %q %q\n", ccExe, cppflags, cflags, ldflags)
- if ccID, err := b.gccToolID(ccExe[0], "c"); err == nil {
- fmt.Fprintf(h, "CC ID=%q\n", ccID)
+ // Include the C compiler tool ID so that if the C
+ // compiler changes we rebuild the package.
+ // But don't do that for standard library packages like net,
+ // so that the prebuilt .a files from a Go binary install
+ // don't need to be rebuilt with the local compiler.
+ if !p.Standard {
+ if ccID, err := b.gccToolID(ccExe[0], "c"); err == nil {
+ fmt.Fprintf(h, "CC ID=%q\n", ccID)
+ }
}
if len(p.CXXFiles)+len(p.SwigCXXFiles) > 0 {
cxxExe := b.cxxExe()
diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt
in