summaryrefslogtreecommitdiff
path: root/libgo/go/cmd/go/internal
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/cmd/go/internal')
-rw-r--r--libgo/go/cmd/go/internal/base/base.go2
-rw-r--r--libgo/go/cmd/go/internal/bug/bug.go2
-rw-r--r--libgo/go/cmd/go/internal/fmtcmd/fmt.go3
-rw-r--r--libgo/go/cmd/go/internal/generate/generate.go20
-rw-r--r--libgo/go/cmd/go/internal/get/get.go2
-rw-r--r--libgo/go/cmd/go/internal/help/helpdoc.go19
-rw-r--r--libgo/go/cmd/go/internal/list/list.go12
-rw-r--r--libgo/go/cmd/go/internal/load/pkg.go134
-rw-r--r--libgo/go/cmd/go/internal/load/test.go8
-rw-r--r--libgo/go/cmd/go/internal/modcmd/download.go4
-rw-r--r--libgo/go/cmd/go/internal/modcmd/edit.go5
-rw-r--r--libgo/go/cmd/go/internal/modcmd/graph.go2
-rw-r--r--libgo/go/cmd/go/internal/modcmd/init.go2
-rw-r--r--libgo/go/cmd/go/internal/modcmd/tidy.go2
-rw-r--r--libgo/go/cmd/go/internal/modcmd/vendor.go78
-rw-r--r--libgo/go/cmd/go/internal/modcmd/verify.go2
-rw-r--r--libgo/go/cmd/go/internal/modcmd/why.go2
-rw-r--r--libgo/go/cmd/go/internal/modfetch/codehost/codehost.go2
-rw-r--r--libgo/go/cmd/go/internal/modfetch/codehost/git.go2
-rw-r--r--libgo/go/cmd/go/internal/modfetch/fetch.go108
-rw-r--r--libgo/go/cmd/go/internal/modfetch/proxy.go61
-rw-r--r--libgo/go/cmd/go/internal/modget/get.go127
-rw-r--r--libgo/go/cmd/go/internal/modget/query.go4
-rw-r--r--libgo/go/cmd/go/internal/modload/buildlist.go11
-rw-r--r--libgo/go/cmd/go/internal/modload/help.go484
-rw-r--r--libgo/go/cmd/go/internal/modload/import.go82
-rw-r--r--libgo/go/cmd/go/internal/modload/import_test.go13
-rw-r--r--libgo/go/cmd/go/internal/modload/init.go81
-rw-r--r--libgo/go/cmd/go/internal/modload/load.go21
-rw-r--r--libgo/go/cmd/go/internal/modload/modfile.go4
-rw-r--r--libgo/go/cmd/go/internal/modload/mvs.go16
-rw-r--r--libgo/go/cmd/go/internal/modload/query.go10
-rw-r--r--libgo/go/cmd/go/internal/modload/vendor.go2
-rw-r--r--libgo/go/cmd/go/internal/str/str.go14
-rw-r--r--libgo/go/cmd/go/internal/test/genflags.go2
-rw-r--r--libgo/go/cmd/go/internal/test/test.go2
-rw-r--r--libgo/go/cmd/go/internal/test/testflag.go2
-rw-r--r--libgo/go/cmd/go/internal/tool/tool.go17
-rw-r--r--libgo/go/cmd/go/internal/vcs/vcs.go4
-rw-r--r--libgo/go/cmd/go/internal/vet/vetflag.go2
-rw-r--r--libgo/go/cmd/go/internal/work/build.go7
-rw-r--r--libgo/go/cmd/go/internal/work/buildid.go2
-rw-r--r--libgo/go/cmd/go/internal/work/exec.go17
-rw-r--r--libgo/go/cmd/go/internal/work/gccgo.go8
44 files changed, 491 insertions, 913 deletions
diff --git a/libgo/go/cmd/go/internal/base/base.go b/libgo/go/cmd/go/internal/base/base.go
index 004588c7320..954ce47a989 100644
--- a/libgo/go/cmd/go/internal/base/base.go
+++ b/libgo/go/cmd/go/internal/base/base.go
@@ -10,9 +10,9 @@ import (
"context"
"flag"
"fmt"
+ exec "internal/execabs"
"log"
"os"
- "os/exec"
"strings"
"sync"
diff --git a/libgo/go/cmd/go/internal/bug/bug.go b/libgo/go/cmd/go/internal/bug/bug.go
index 1085feaaee8..4aa08b4ff6e 100644
--- a/libgo/go/cmd/go/internal/bug/bug.go
+++ b/libgo/go/cmd/go/internal/bug/bug.go
@@ -9,10 +9,10 @@ import (
"bytes"
"context"
"fmt"
+ exec "internal/execabs"
"io"
urlpkg "net/url"
"os"
- "os/exec"
"path/filepath"
"regexp"
"runtime"
diff --git a/libgo/go/cmd/go/internal/fmtcmd/fmt.go b/libgo/go/cmd/go/internal/fmtcmd/fmt.go
index b0c1c59b40c..6b98f0ccd31 100644
--- a/libgo/go/cmd/go/internal/fmtcmd/fmt.go
+++ b/libgo/go/cmd/go/internal/fmtcmd/fmt.go
@@ -75,7 +75,8 @@ func runFmt(ctx context.Context, cmd *base.Command, args []string) {
}
if pkg.Error != nil {
var nogo *load.NoGoError
- if errors.As(pkg.Error, &nogo) && len(pkg.InternalAllGoFiles()) > 0 {
+ var embed *load.EmbedError
+ if (errors.As(pkg.Error, &nogo) || errors.As(pkg.Error, &embed)) && len(pkg.InternalAllGoFiles()) > 0 {
// Skip this error, as we will format
// all files regardless.
} else {
diff --git a/libgo/go/cmd/go/internal/generate/generate.go b/libgo/go/cmd/go/internal/generate/generate.go
index c7401948b8b..a48311d51b0 100644
--- a/libgo/go/cmd/go/internal/generate/generate.go
+++ b/libgo/go/cmd/go/internal/generate/generate.go
@@ -12,10 +12,10 @@ import (
"fmt"
"go/parser"
"go/token"
+ exec "internal/execabs"
"io"
"log"
"os"
- "os/exec"
"path/filepath"
"regexp"
"strconv"
@@ -52,15 +52,6 @@ that can be run locally. It must either be in the shell path
(gofmt), a fully qualified path (/usr/you/bin/mytool), or a
command alias, described below.
-To convey to humans and machine tools that code is generated,
-generated source should have a line that matches the following
-regular expression (in Go syntax):
-
- ^// Code generated .* DO NOT EDIT\.$
-
-The line may appear anywhere in the file, but is typically
-placed near the beginning so it is easy to find.
-
Note that go generate does not parse the file, so lines that look
like directives in comments or multiline strings will be treated
as directives.
@@ -72,6 +63,15 @@ arguments when it is run.
Quoted strings use Go syntax and are evaluated before execution; a
quoted string appears as a single argument to the generator.
+To convey to humans and machine tools that code is generated,
+generated source should have a line that matches the following
+regular expression (in Go syntax):
+
+ ^// Code generated .* DO NOT EDIT\.$
+
+This line must appear before the first non-comment, non-blank
+text in the file.
+
Go generate sets several variables when it runs the generator:
$GOARCH
diff --git a/libgo/go/cmd/go/internal/get/get.go b/libgo/go/cmd/go/internal/get/get.go
index 94a42c4f73a..38ff3823f22 100644
--- a/libgo/go/cmd/go/internal/get/get.go
+++ b/libgo/go/cmd/go/internal/get/get.go
@@ -202,7 +202,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
func downloadPaths(patterns []string) []string {
for _, arg := range patterns {
if strings.Contains(arg, "@") {
- base.Fatalf("go: cannot use path@version syntax in GOPATH mode")
+ base.Fatalf("go: can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
continue
}
diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go
index 98f58441b4d..e07ad0e1db1 100644
--- a/libgo/go/cmd/go/internal/help/helpdoc.go
+++ b/libgo/go/cmd/go/internal/help/helpdoc.go
@@ -266,7 +266,7 @@ listed in the GOPATH environment variable.
(See 'go help gopath-get' and 'go help gopath'.)
When using modules, downloaded packages are stored in the module cache.
-(See 'go help module-get' and 'go help goproxy'.)
+See https://golang.org/ref/mod#module-cache.
When using modules, an additional variant of the go-import meta tag is
recognized and is preferred over those listing version control systems.
@@ -276,7 +276,8 @@ That variant uses "mod" as the vcs in the content value, as in:
This tag means to fetch modules with paths beginning with example.org
from the module proxy available at the URL https://code.org/moduleproxy.
-See 'go help goproxy' for details about the proxy protocol.
+See https://golang.org/ref/mod#goproxy-protocol for details about the
+proxy protocol.
Import path checking
@@ -483,6 +484,10 @@ See 'go help env' for details.
General-purpose environment variables:
+ GO111MODULE
+ Controls whether the go command runs in module-aware mode or GOPATH mode.
+ May be "off", "on", or "auto".
+ See https://golang.org/ref/mod#mod-commands.
GCCGO
The gccgo command to run for 'go build -compiler=gccgo'.
GOARCH
@@ -521,20 +526,24 @@ General-purpose environment variables:
GOPATH
For more details see: 'go help gopath'.
GOPROXY
- URL of Go module proxy. See 'go help modules'.
+ URL of Go module proxy. See https://golang.org/ref/mod#environment-variables
+ and https://golang.org/ref/mod#module-proxy for details.
GOPRIVATE, GONOPROXY, GONOSUMDB
Comma-separated list of glob patterns (in the syntax of Go's path.Match)
of module path prefixes that should always be fetched directly
or that should not be compared against the checksum database.
- See 'go help private'.
+ See https://golang.org/ref/mod#private-modules.
GOROOT
The root of the go tree.
GOSUMDB
The name of checksum database to use and optionally its public key and
- URL. See 'go help module-auth'.
+ URL. See https://golang.org/ref/mod#authenticating.
GOTMPDIR
The directory where the go command will write
temporary source files, packages, and binaries.
+ GOVCS
+ Lists version control commands that may be used with matching servers.
+ See 'go help vcs'.
Environment variables for use with cgo:
diff --git a/libgo/go/cmd/go/internal/list/list.go b/libgo/go/cmd/go/internal/list/list.go
index ce6f579c058..b4d82d9f8cc 100644
--- a/libgo/go/cmd/go/internal/list/list.go
+++ b/libgo/go/cmd/go/internal/list/list.go
@@ -89,6 +89,14 @@ to -f '{{.ImportPath}}'. The struct being passed to the template is:
TestGoFiles []string // _test.go files in package
XTestGoFiles []string // _test.go files outside package
+ // Embedded files
+ EmbedPatterns []string // //go:embed patterns
+ EmbedFiles []string // files matched by EmbedPatterns
+ TestEmbedPatterns []string // //go:embed patterns in TestGoFiles
+ TestEmbedFiles []string // files matched by TestEmbedPatterns
+ XTestEmbedPatterns []string // //go:embed patterns in XTestGoFiles
+ XTestEmbedFiles []string // files matched by XTestEmbedPatterns
+
// Cgo directives
CgoCFLAGS []string // cgo: flags for C compiler
CgoCPPFLAGS []string // cgo: flags for C preprocessor
@@ -300,7 +308,7 @@ For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
-For more about modules, see 'go help modules'.
+For more about modules, see https://golang.org/ref/mod.
`,
}
@@ -577,8 +585,6 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
// Show vendor-expanded paths in listing
p.TestImports = p.Resolve(p.TestImports)
p.XTestImports = p.Resolve(p.XTestImports)
- p.TestEmbedFiles = p.ResolveEmbed(p.TestEmbedPatterns)
- p.XTestEmbedFiles = p.ResolveEmbed(p.XTestEmbedPatterns)
p.DepOnly = !cmdline[p]
if *listCompiled {
diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go
index b3679728f1f..8757d666fb2 100644
--- a/libgo/go/cmd/go/internal/load/pkg.go
+++ b/libgo/go/cmd/go/internal/load/pkg.go
@@ -96,7 +96,7 @@ type PackagePublic struct {
// Embedded files
EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
- EmbedFiles []string `json:",omitempty"` // files and directories matched by EmbedPatterns
+ EmbedFiles []string `json:",omitempty"` // files matched by EmbedPatterns
// Cgo directives
CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
@@ -122,11 +122,11 @@ type PackagePublic struct {
TestGoFiles []string `json:",omitempty"` // _test.go files in package
TestImports []string `json:",omitempty"` // imports from TestGoFiles
TestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
- TestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns
+ TestEmbedFiles []string `json:",omitempty"` // files matched by TestEmbedPatterns
XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
- XTestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns
+ XTestEmbedFiles []string `json:",omitempty"` // files matched by XTestEmbedPatterns
}
// AllFiles returns the names of all the files considered for the package.
@@ -304,7 +304,7 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
}
if path != stk.Top() {
- p = setErrorPos(p, importPos)
+ p.Error.setPos(importPos)
}
}
@@ -412,6 +412,9 @@ type PackageError struct {
}
func (p *PackageError) Error() string {
+ // TODO(#43696): decide when to print the stack or the position based on
+ // the error type and whether the package is in the main module.
+ // Document the rationale.
if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
// Omit import stack. The full path to the file where the error
// is the most important thing.
@@ -447,6 +450,15 @@ func (p *PackageError) MarshalJSON() ([]byte, error) {
return json.Marshal(perr)
}
+func (p *PackageError) setPos(posList []token.Position) {
+ if len(posList) == 0 {
+ return
+ }
+ pos := posList[0]
+ pos.Filename = base.ShortPath(pos.Filename)
+ p.Pos = pos.String()
+}
+
// ImportPathError is a type of error that prevents a package from being loaded
// for a given import path. When such a package is loaded, a *Package is
// returned with Err wrapping an ImportPathError: the error is attached to
@@ -695,17 +707,19 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
Err: ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
}
p.Incomplete = true
- setErrorPos(p, importPos)
+ p.Error.setPos(importPos)
}
}
// Checked on every import because the rules depend on the code doing the importing.
if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
- return setErrorPos(perr, importPos)
+ perr.Error.setPos(importPos)
+ return perr
}
if mode&ResolveImport != 0 {
if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p {
- return setErrorPos(perr, importPos)
+ perr.Error.setPos(importPos)
+ return perr
}
}
@@ -715,7 +729,8 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
ImportStack: stk.Copy(),
Err: ImportErrorf(path, "import %q is a program, not an importable package", path),
}
- return setErrorPos(&perr, importPos)
+ perr.Error.setPos(importPos)
+ return &perr
}
if p.Internal.Local && parent != nil && !parent.Internal.Local {
@@ -730,21 +745,13 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
ImportStack: stk.Copy(),
Err: err,
}
- return setErrorPos(&perr, importPos)
+ perr.Error.setPos(importPos)
+ return &perr
}
return p
}
-func setErrorPos(p *Package, importPos []token.Position) *Package {
- if len(importPos) > 0 {
- pos := importPos[0]
- pos.Filename = base.ShortPath(pos.Filename)
- p.Error.Pos = pos.String()
- }
- return p
-}
-
// loadPackageData loads information needed to construct a *Package. The result
// is cached, and later calls to loadPackageData for the same package will return
// the same data.
@@ -769,11 +776,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd
}
if strings.Contains(path, "@") {
- if cfg.ModulesEnabled {
- return nil, false, errors.New("can only use path@version syntax with 'go get'")
- } else {
- return nil, false, errors.New("cannot use path@version syntax in GOPATH mode")
- }
+ return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
}
// Determine canonical package path and directory.
@@ -1659,7 +1662,7 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
// must be either in an explicit command-line argument,
// or on the importer side (indicated by a non-empty importPos).
if path != stk.Top() && len(importPos) > 0 {
- p = setErrorPos(p, importPos)
+ p.Error.setPos(importPos)
}
}
}
@@ -1669,11 +1672,6 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
p.setLoadPackageDataError(err, path, stk, importPos)
}
- p.EmbedFiles, p.Internal.Embed, err = p.resolveEmbed(p.EmbedPatterns)
- if err != nil {
- setError(err)
- }
-
useBindir := p.Name == "main"
if !p.Standard {
switch cfg.BuildBuildmode {
@@ -1809,9 +1807,20 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
return
}
+ // Errors after this point are caused by this package, not the importing
+ // package. Pushing the path here prevents us from reporting the error
+ // with the position of the import declaration.
stk.Push(path)
defer stk.Pop()
+ p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
+ if err != nil {
+ p.Incomplete = true
+ setError(err)
+ embedErr := err.(*EmbedError)
+ p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])
+ }
+
// Check for case-insensitive collision of input files.
// To avoid problems on case-insensitive files, we reject any package
// where two different input files have equal names under a case-insensitive
@@ -1915,35 +1924,62 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
}
}
+// An EmbedError indicates a problem with a go:embed directive.
+type EmbedError struct {
+ Pattern string
+ Err error
+}
+
+func (e *EmbedError) Error() string {
+ return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
+}
+
+func (e *EmbedError) Unwrap() error {
+ return e.Err
+}
+
// ResolveEmbed resolves //go:embed patterns and returns only the file list.
-// For use by go list to compute p.TestEmbedFiles and p.XTestEmbedFiles.
-func (p *Package) ResolveEmbed(patterns []string) []string {
- files, _, _ := p.resolveEmbed(patterns)
- return files
+// For use by go mod vendor to find embedded files it should copy into the
+// vendor directory.
+// TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just
+// call (*Package).ResolveEmbed
+func ResolveEmbed(dir string, patterns []string) ([]string, error) {
+ files, _, err := resolveEmbed(dir, patterns)
+ return files, err
}
// resolveEmbed resolves //go:embed patterns to precise file lists.
// It sets files to the list of unique files matched (for go list),
// and it sets pmap to the more precise mapping from
// patterns to files.
-// TODO(rsc): All these messages need position information for better error reports.
-func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[string][]string, err error) {
+func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) {
+ var pattern string
+ defer func() {
+ if err != nil {
+ err = &EmbedError{
+ Pattern: pattern,
+ Err: err,
+ }
+ }
+ }()
+
+ // TODO(rsc): All these messages need position information for better error reports.
pmap = make(map[string][]string)
have := make(map[string]int)
dirOK := make(map[string]bool)
pid := 0 // pattern ID, to allow reuse of have map
- for _, pattern := range patterns {
+ for _, pattern = range patterns {
pid++
// Check pattern is valid for //go:embed.
if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) {
- return nil, nil, fmt.Errorf("pattern %s: invalid pattern syntax", pattern)
+ return nil, nil, fmt.Errorf("invalid pattern syntax")
}
// Glob to find matches.
- match, err := fsys.Glob(p.Dir + string(filepath.Separator) + filepath.FromSlash(pattern))
+ match, err := fsys.Glob(pkgdir + string(filepath.Separator) + filepath.FromSlash(pattern))
if err != nil {
- return nil, nil, fmt.Errorf("pattern %s: %v", pattern, err)
+ return nil, nil, err
}
// Filter list of matches down to the ones that will still exist when
@@ -1952,7 +1988,7 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
// then there may be other things lying around, like symbolic links or .git directories.)
var list []string
for _, file := range match {
- rel := filepath.ToSlash(file[len(p.Dir)+1:]) // file, relative to p.Dir
+ rel := filepath.ToSlash(file[len(pkgdir)+1:]) // file, relative to p.Dir
what := "file"
info, err := fsys.Lstat(file)
@@ -1965,28 +2001,28 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
// Check that directories along path do not begin a new module
// (do not contain a go.mod).
- for dir := file; len(dir) > len(p.Dir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
+ for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
- return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in different module", pattern, what, rel)
+ return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
}
if dir != file {
if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
- return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in non-directory %s", pattern, what, rel, dir[len(p.Dir)+1:])
+ return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
}
}
dirOK[dir] = true
if elem := filepath.Base(dir); isBadEmbedName(elem) {
if dir == file {
- return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: invalid name %s", pattern, what, rel, elem)
+ return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
} else {
- return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in invalid directory %s", pattern, what, rel, elem)
+ return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
}
}
}
switch {
default:
- return nil, nil, fmt.Errorf("pattern %s: cannot embed irregular file %s", pattern, rel)
+ return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
case info.Mode().IsRegular():
if have[rel] != pid {
@@ -2002,7 +2038,7 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
if err != nil {
return err
}
- rel := filepath.ToSlash(path[len(p.Dir)+1:])
+ rel := filepath.ToSlash(path[len(pkgdir)+1:])
name := info.Name()
if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') {
// Ignore bad names, assuming they won't go into modules.
@@ -2033,13 +2069,13 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
return nil, nil, err
}
if count == 0 {
- return nil, nil, fmt.Errorf("pattern %s: cannot embed directory %s: contains no embeddable files", pattern, rel)
+ return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel)
}
}
}
if len(list) == 0 {
- return nil, nil, fmt.Errorf("pattern %s: no matching files found", pattern)
+ return nil, nil, fmt.Errorf("no matching files found")
}
sort.Strings(list)
pmap[pattern] = list
diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go
index d884361aaad..eb8aef3ee28 100644
--- a/libgo/go/cmd/go/internal/load/test.go
+++ b/libgo/go/cmd/go/internal/load/test.go
@@ -124,12 +124,14 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
imports = append(imports, p1)
}
var err error
- p.TestEmbedFiles, testEmbed, err = p.resolveEmbed(p.TestEmbedPatterns)
+ p.TestEmbedFiles, testEmbed, err = resolveEmbed(p.Dir, p.TestEmbedPatterns)
if err != nil && ptestErr == nil {
ptestErr = &PackageError{
ImportStack: stk.Copy(),
Err: err,
}
+ embedErr := err.(*EmbedError)
+ ptestErr.setPos(p.Internal.Build.TestEmbedPatternPos[embedErr.Pattern])
}
stk.Pop()
@@ -145,12 +147,14 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
}
p.XTestImports[i] = p1.ImportPath
}
- p.XTestEmbedFiles, xtestEmbed, err = p.resolveEmbed(p.XTestEmbedPatterns)
+ p.XTestEmbedFiles, xtestEmbed, err = resolveEmbed(p.Dir, p.XTestEmbedPatterns)
if err != nil && pxtestErr == nil {
pxtestErr = &PackageError{
ImportStack: stk.Copy(),
Err: err,
}
+ embedErr := err.(*EmbedError)
+ pxtestErr.setPos(p.Internal.Build.XTestEmbedPatternPos[embedErr.Pattern])
}
stk.Pop()
diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go
index ef1ad780c81..e7d3d869cbc 100644
--- a/libgo/go/cmd/go/internal/modcmd/download.go
+++ b/libgo/go/cmd/go/internal/modcmd/download.go
@@ -52,7 +52,9 @@ corresponding to this Go struct:
The -x flag causes download to print the commands download executes.
-See 'go help modules' for more about module queries.
+See https://golang.org/ref/mod#go-mod-download for more about 'go mod download'.
+
+See https://golang.org/ref/mod#version-queries for more about version queries.
`,
}
diff --git a/libgo/go/cmd/go/internal/modcmd/edit.go b/libgo/go/cmd/go/internal/modcmd/edit.go
index b203a8a2b0a..1df104eb1dd 100644
--- a/libgo/go/cmd/go/internal/modcmd/edit.go
+++ b/libgo/go/cmd/go/internal/modcmd/edit.go
@@ -95,6 +95,7 @@ writing it back to go.mod. The JSON output corresponds to these Go types:
Require []Require
Exclude []Module
Replace []Replace
+ Retract []Retract
}
type Require struct {
@@ -121,9 +122,7 @@ Note that this only describes the go.mod file itself, not other modules
referred to indirectly. For the full set of modules available to a build,
use 'go list -m -json all'.
-For example, a tool can obtain the go.mod as a data structure by
-parsing the output of 'go mod edit -json' and can then make changes
-by invoking 'go mod edit' with -require, -exclude, and so on.
+See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
`,
}
diff --git a/libgo/go/cmd/go/internal/modcmd/graph.go b/libgo/go/cmd/go/internal/modcmd/graph.go
index 3277548c235..a88e9ef4557 100644
--- a/libgo/go/cmd/go/internal/modcmd/graph.go
+++ b/libgo/go/cmd/go/internal/modcmd/graph.go
@@ -26,6 +26,8 @@ Graph prints the module requirement graph (with replacements applied)
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.
+
+See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
`,
Run: runGraph,
}
diff --git a/libgo/go/cmd/go/internal/modcmd/init.go b/libgo/go/cmd/go/internal/modcmd/init.go
index c081bb547d1..73cc282d814 100644
--- a/libgo/go/cmd/go/internal/modcmd/init.go
+++ b/libgo/go/cmd/go/internal/modcmd/init.go
@@ -27,6 +27,8 @@ Gopkg.lock), and the current directory (if in GOPATH).
If a configuration file for a vendoring tool is present, init will attempt to
import module requirements from it.
+
+See https://golang.org/ref/mod#go-mod-init for more about 'go mod init'.
`,
Run: runInit,
}
diff --git a/libgo/go/cmd/go/internal/modcmd/tidy.go b/libgo/go/cmd/go/internal/modcmd/tidy.go
index fb43e33ec58..3b83d87a8eb 100644
--- a/libgo/go/cmd/go/internal/modcmd/tidy.go
+++ b/libgo/go/cmd/go/internal/modcmd/tidy.go
@@ -29,6 +29,8 @@ to standard error.
The -e flag causes tidy to attempt to proceed despite errors
encountered while loading packages.
+
+See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
`,
Run: runTidy,
}
diff --git a/libgo/go/cmd/go/internal/modcmd/vendor.go b/libgo/go/cmd/go/internal/modcmd/vendor.go
index 1bbb57d353b..d3ed9e00e22 100644
--- a/libgo/go/cmd/go/internal/modcmd/vendor.go
+++ b/libgo/go/cmd/go/internal/modcmd/vendor.go
@@ -7,7 +7,9 @@ package modcmd
import (
"bytes"
"context"
+ "errors"
"fmt"
+ "go/build"
"io"
"io/fs"
"os"
@@ -19,7 +21,9 @@ import (
"cmd/go/internal/cfg"
"cmd/go/internal/fsys"
"cmd/go/internal/imports"
+ "cmd/go/internal/load"
"cmd/go/internal/modload"
+ "cmd/go/internal/str"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
@@ -38,6 +42,8 @@ modules and packages to standard error.
The -e flag causes vendor to attempt to proceed despite errors
encountered while loading packages.
+
+See https://golang.org/ref/mod#go-mod-vendor for more about 'go mod vendor'.
`,
Run: runVendor,
}
@@ -180,19 +186,76 @@ func moduleLine(m, r module.Version) string {
}
func vendorPkg(vdir, pkg string) {
+ // TODO(#42504): Instead of calling modload.ImportMap then build.ImportDir,
+ // just call load.PackagesAndErrors. To do that, we need to add a good way
+ // to ignore build constraints.
realPath := modload.ImportMap(pkg)
if realPath != pkg && modload.ImportMap(realPath) != "" {
fmt.Fprintf(os.Stderr, "warning: %s imported as both %s and %s; making two copies.\n", realPath, realPath, pkg)
}
+ copiedFiles := make(map[string]bool)
dst := filepath.Join(vdir, pkg)
src := modload.PackageDir(realPath)
if src == "" {
fmt.Fprintf(os.Stderr, "internal error: no pkg for %s -> %s\n", pkg, realPath)
}
- copyDir(dst, src, matchPotentialSourceFile)
+ copyDir(dst, src, matchPotentialSourceFile, copiedFiles)
if m := modload.PackageModule(realPath); m.Path != "" {
- copyMetadata(m.Path, realPath, dst, src)
+ copyMetadata(m.Path, realPath, dst, src, copiedFiles)
+ }
+
+ ctx := build.Default
+ ctx.UseAllFiles = true
+ bp, err := ctx.ImportDir(src, build.IgnoreVendor)
+ // Because UseAllFiles is set on the build.Context, it's possible ta get
+ // a MultiplePackageError on an otherwise valid package: the package could
+ // have different names for GOOS=windows and GOOS=mac for example. On the
+ // other hand if there's a NoGoError, the package might have source files
+ // specifying "// +build ignore" those packages should be skipped because
+ // embeds from ignored files can't be used.
+ // TODO(#42504): Find a better way to avoid errors from ImportDir. We'll
+ // need to figure this out when we switch to PackagesAndErrors as per the
+ // TODO above.
+ var multiplePackageError *build.MultiplePackageError
+ var noGoError *build.NoGoError
+ if err != nil {
+ if errors.As(err, &noGoError) {
+ return // No source files in this package are built. Skip embeds in ignored files.
+ } else if !errors.As(err, &multiplePackageError) { // multiplePackgeErrors are okay, but others are not.
+ base.Fatalf("internal error: failed to find embedded files of %s: %v\n", pkg, err)
+ }
+ }
+ embedPatterns := str.StringList(bp.EmbedPatterns, bp.TestEmbedPatterns, bp.XTestEmbedPatterns)
+ embeds, err := load.ResolveEmbed(bp.Dir, embedPatterns)
+ if err != nil {
+ base.Fatalf("go mod vendor: %v", err)
+ }
+ for _, embed := range embeds {
+ embedDst := filepath.Join(dst, embed)
+ if copiedFiles[embedDst] {
+ continue
+ }
+
+ // Copy the file as is done by copyDir below.
+ r, err := os.Open(filepath.Join(src, embed))
+ if err != nil {
+ base.Fatalf("go mod vendor: %v", err)
+ }
+ if err := os.MkdirAll(filepath.Dir(embedDst), 0777); err != nil {
+ base.Fatalf("go mod vendor: %v", err)
+ }
+ w, err := os.Create(embedDst)
+ if err != nil {
+ base.Fatalf("go mod vendor: %v", err)
+ }
+ if _, err := io.Copy(w, r); err != nil {
+ base.Fatalf("go mod vendor: %v", err)
+ }
+ r.Close()
+ if err := w.Close(); err != nil {
+ base.Fatalf("go mod vendor: %v", err)
+ }
}
}
@@ -205,14 +268,14 @@ var copiedMetadata = make(map[metakey]bool)
// copyMetadata copies metadata files from parents of src to parents of dst,
// stopping after processing the src parent for modPath.
-func copyMetadata(modPath, pkg, dst, src string) {
+func copyMetadata(modPath, pkg, dst, src string, copiedFiles map[string]bool) {
for parent := 0; ; parent++ {
if copiedMetadata[metakey{modPath, dst}] {
break
}
copiedMetadata[metakey{modPath, dst}] = true
if parent > 0 {
- copyDir(dst, src, matchMetadata)
+ copyDir(dst, src, matchMetadata, copiedFiles)
}
if modPath == pkg {
break
@@ -280,7 +343,7 @@ func matchPotentialSourceFile(dir string, info fs.DirEntry) bool {
}
// copyDir copies all regular files satisfying match(info) from src to dst.
-func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) {
+func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool, copiedFiles map[string]bool) {
files, err := os.ReadDir(src)
if err != nil {
base.Fatalf("go mod vendor: %v", err)
@@ -292,11 +355,14 @@ func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) {
if file.IsDir() || !file.Type().IsRegular() || !match(src, file) {
continue
}
+ copiedFiles[file.Name()] = true
r, err := os.Open(filepath.Join(src, file.Name()))
if err != nil {
base.Fatalf("go mod vendor: %v", err)
}
- w, err := os.Create(filepath.Join(dst, file.Name()))
+ dstPath := filepath.Join(dst, file.Name())
+ copiedFiles[dstPath] = true
+ w, err := os.Create(dstPath)
if err != nil {
base.Fatalf("go mod vendor: %v", err)
}
diff --git a/libgo/go/cmd/go/internal/modcmd/verify.go b/libgo/go/cmd/go/internal/modcmd/verify.go
index c83e70076ae..83214291310 100644
--- a/libgo/go/cmd/go/internal/modcmd/verify.go
+++ b/libgo/go/cmd/go/internal/modcmd/verify.go
@@ -31,6 +31,8 @@ modified since being downloaded. If all the modules are unmodified,
verify prints "all modules verified." Otherwise it reports which
modules have been changed and causes 'go mod' to exit with a
non-zero status.
+
+See https://golang.org/ref/mod#go-mod-verify for more about 'go mod verify'.
`,
Run: runVerify,
}
diff --git a/libgo/go/cmd/go/internal/modcmd/why.go b/libgo/go/cmd/go/internal/modcmd/why.go
index e287c880601..a5f3e8afcbe 100644
--- a/libgo/go/cmd/go/internal/modcmd/why.go
+++ b/libgo/go/cmd/go/internal/modcmd/why.go
@@ -48,6 +48,8 @@ For example:
# golang.org/x/text/encoding
(main module does not need package golang.org/x/text/encoding)
$
+
+See https://golang.org/ref/mod#go-mod-why for more about 'go mod why'.
`,
}
diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go
index 86c1c14d4a7..378fbae34f9 100644
--- a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go
+++ b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go
@@ -10,10 +10,10 @@ import (
"bytes"
"crypto/sha256"
"fmt"
+ exec "internal/execabs"
"io"
"io/fs"
"os"
- "os/exec"
"path/filepath"
"strings"
"sync"
diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git.go b/libgo/go/cmd/go/internal/modfetch/codehost/git.go
index 8abc039e7fc..72005e27d5e 100644
--- a/libgo/go/cmd/go/internal/modfetch/codehost/git.go
+++ b/libgo/go/cmd/go/internal/modfetch/codehost/git.go
@@ -8,11 +8,11 @@ import (
"bytes"
"errors"
"fmt"
+ exec "internal/execabs"
"io"
"io/fs"
"net/url"
"os"
- "os/exec"
"path/filepath"
"sort"
"strconv"
diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go
index debeb3f3194..c55c3cf2534 100644
--- a/libgo/go/cmd/go/internal/modfetch/fetch.go
+++ b/libgo/go/cmd/go/internal/modfetch/fetch.go
@@ -768,90 +768,14 @@ var HelpModuleAuth = &base.Command{
UsageLine: "module-auth",
Short: "module authentication using go.sum",
Long: `
-The go command tries to authenticate every downloaded module,
-checking that the bits downloaded for a specific module version today
-match bits downloaded yesterday. This ensures repeatable builds
-and detects introduction of unexpected changes, malicious or not.
-
-In each module's root, alongside go.mod, the go command maintains
-a file named go.sum containing the cryptographic checksums of the
-module's dependencies.
-
-The form of each line in go.sum is three fields:
-
- <module> <version>[/go.mod] <hash>
-
-Each known module version results in two lines in the go.sum file.
-The first line gives the hash of the module version's file tree.
-The second line appends "/go.mod" to the version and gives the hash
-of only the module version's (possibly synthesized) go.mod file.
-The go.mod-only hash allows downloading and authenticating a
-module version's go.mod file, which is needed to compute the
-dependency graph, without also downloading all the module's source code.
-
-The hash begins with an algorithm prefix of the form "h<N>:".
-The only defined algorithm prefix is "h1:", which uses SHA-256.
-
-Module authentication failures
-
-The go command maintains a cache of downloaded packages and computes
-and records the cryptographic checksum of each package at download time.
-In normal operation, the go command checks the main module's go.sum file
-against these precomputed checksums instead of recomputing them on
-each command invocation. The 'go mod verify' command checks that
-the cached copies of module downloads still match both their recorded
-checksums and the entries in go.sum.
-
-In day-to-day development, the checksum of a given module version
-should never change. Each time a dependency is used by a given main
-module, the go command checks its local cached copy, freshly
-downloaded or not, against the main module's go.sum. If the checksums
-don't match, the go command reports the mismatch as a security error
-and refuses to run the build. When this happens, proceed with caution:
-code changing unexpectedly means today's build will not match
-yesterday's, and the unexpected change may not be beneficial.
-
-If the go command reports a mismatch in go.sum, the downloaded code
-for the reported module version does not match the one used in a
-previous build of the main module. It is important at that point
-to find out what the right checksum should be, to decide whether
-go.sum is wrong or the downloaded code is wrong. Usually go.sum is right:
-you want to use the same code you used yesterday.
-
-If a downloaded module is not yet included in go.sum and it is a publicly
-available module, the go command consults the Go checksum database to fetch
-the expected go.sum lines. If the downloaded code does not match those
-lines, the go command reports the mismatch and exits. Note that the
-database is not consulted for module versions already listed in go.sum.
-
-If a go.sum mismatch is reported, it is always worth investigating why
-the code downloaded today differs from what was downloaded yesterday.
-
-The GOSUMDB environment variable identifies the name of checksum database
-to use and optionally its public key and URL, as in:
-
- GOSUMDB="sum.golang.org"
- GOSUMDB="sum.golang.org+<publickey>"
- GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org"
-
-The go command knows the public key of sum.golang.org, and also that the name
-sum.golang.google.cn (available inside mainland China) connects to the
-sum.golang.org checksum database; use of any other database requires giving
-the public key explicitly.
-The URL defaults to "https://" followed by the database name.
-
-GOSUMDB defaults to "sum.golang.org", the Go checksum database run by Google.
-See https://sum.golang.org/privacy for the service's privacy policy.
-
-If GOSUMDB is set to "off", or if "go get" is invoked with the -insecure flag,
-the checksum database is not consulted, and all unrecognized modules are
-accepted, at the cost of giving up the security guarantee of verified repeatable
-downloads for all modules. A better way to bypass the checksum database
-for specific modules is to use the GOPRIVATE or GONOSUMDB environment
-variables. See 'go help private' for details.
-
-The 'go env -w' command (see 'go help env') can be used to set these variables
-for future go command invocations.
+When the go command downloads a module zip file or go.mod file into the
+module cache, it computes a cryptographic hash and compares it with a known
+value to verify the file hasn't changed since it was first downloaded. Known
+hashes are stored in a file in the module root directory named go.sum. Hashes
+may also be downloaded from the checksum database depending on the values of
+GOSUMDB, GOPRIVATE, and GONOSUMDB.
+
+For details, see https://golang.org/ref/mod#authenticating.
`,
}
@@ -865,8 +789,8 @@ regardless of source, against the public Go checksum database at sum.golang.org.
These defaults work well for publicly available source code.
The GOPRIVATE environment variable controls which modules the go command
-considers to be private (not available publicly) and should therefore not use the
-proxy or checksum database. The variable is a comma-separated list of
+considers to be private (not available publicly) and should therefore not use
+the proxy or checksum database. The variable is a comma-separated list of
glob patterns (in the syntax of Go's path.Match) of module path prefixes.
For example,
@@ -876,10 +800,6 @@ causes the go command to treat as private any module with a path prefix
matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private,
and rsc.io/private/quux.
-The GOPRIVATE environment variable may be used by other tools as well to
-identify non-public modules. For example, an editor could use GOPRIVATE
-to decide whether to hyperlink a package import to a godoc.org page.
-
For fine-grained control over module download and validation, the GONOPROXY
and GONOSUMDB environment variables accept the same kind of glob list
and override GOPRIVATE for the specific decision of whether to use the proxy
@@ -892,12 +812,6 @@ users would configure go using:
GOPROXY=proxy.example.com
GONOPROXY=none
-This would tell the go command and other tools that modules beginning with
-a corp.example.com subdomain are private but that the company proxy should
-be used for downloading both public and private modules, because
-GONOPROXY has been set to a pattern that won't match any modules,
-overriding GOPRIVATE.
-
The GOPRIVATE variable is also used to define the "public" and "private"
patterns for the GOVCS variable; see 'go help vcs'. For that usage,
GOPRIVATE applies even in GOPATH mode. In that case, it matches import paths
@@ -905,5 +819,7 @@ instead of module paths.
The 'go env -w' command (see 'go help env') can be used to set these variables
for future go command invocations.
+
+For more details, see https://golang.org/ref/mod#private-modules.
`,
}
diff --git a/libgo/go/cmd/go/internal/modfetch/proxy.go b/libgo/go/cmd/go/internal/modfetch/proxy.go
index d75b4da5215..6c86d8d786d 100644
--- a/libgo/go/cmd/go/internal/modfetch/proxy.go
+++ b/libgo/go/cmd/go/internal/modfetch/proxy.go
@@ -36,65 +36,8 @@ URLs of a specified form. The requests have no query parameters, so even
a site serving from a fixed file system (including a file:/// URL)
can be a module proxy.
-The GET requests sent to a Go module proxy are:
-
-GET $GOPROXY/<module>/@v/list returns a list of known versions of the given
-module, one per line.
-
-GET $GOPROXY/<module>/@v/<version>.info returns JSON-formatted metadata
-about that version of the given module.
-
-GET $GOPROXY/<module>/@v/<version>.mod returns the go.mod file
-for that version of the given module.
-
-GET $GOPROXY/<module>/@v/<version>.zip returns the zip archive
-for that version of the given module.
-
-GET $GOPROXY/<module>/@latest returns JSON-formatted metadata about the
-latest known version of the given module in the same format as
-<module>/@v/<version>.info. The latest version should be the version of
-the module the go command may use if <module>/@v/list is empty or no
-listed version is suitable. <module>/@latest is optional and may not
-be implemented by a module proxy.
-
-When resolving the latest version of a module, the go command will request
-<module>/@v/list, then, if no suitable versions are found, <module>/@latest.
-The go command prefers, in order: the semantically highest release version,
-the semantically highest pre-release version, and the chronologically
-most recent pseudo-version. In Go 1.12 and earlier, the go command considered
-pseudo-versions in <module>/@v/list to be pre-release versions, but this is
-no longer true since Go 1.13.
-
-To avoid problems when serving from case-sensitive file systems,
-the <module> and <version> elements are case-encoded, replacing every
-uppercase letter with an exclamation mark followed by the corresponding
-lower-case letter: github.com/Azure encodes as github.com/!azure.
-
-The JSON-formatted metadata about a given module corresponds to
-this Go data structure, which may be expanded in the future:
-
- type Info struct {
- Version string // version string
- Time time.Time // commit time
- }
-
-The zip archive for a specific version of a given module is a
-standard zip file that contains the file tree corresponding
-to the module's source code and related files. The archive uses
-slash-separated paths, and every file path in the archive must
-begin with <module>@<version>/, where the module and version are
-substituted directly, not case-encoded. The root of the module
-file tree corresponds to the <module>@<version>/ prefix in the
-archive.
-
-Even when downloading directly from version control systems,
-the go command synthesizes explicit info, mod, and zip files
-and stores them in its local cache, $GOPATH/pkg/mod/cache/download,
-the same as if it had downloaded them directly from a proxy.
-The cache layout is the same as the proxy URL space, so
-serving $GOPATH/pkg/mod/cache/download at (or copying it to)
-https://example.com/proxy would let other users access those
-cached module versions with GOPROXY=https://example.com/proxy.
+For details on the GOPROXY protocol, see
+https://golang.org/ref/mod#goproxy-protocol.
`,
}
diff --git a/libgo/go/cmd/go/internal/modget/get.go b/libgo/go/cmd/go/internal/modget/get.go
index 8463ec4e9c7..574f3e194d1 100644
--- a/libgo/go/cmd/go/internal/modget/get.go
+++ b/libgo/go/cmd/go/internal/modget/get.go
@@ -56,85 +56,49 @@ var CmdGet = &base.Command{
UsageLine: "go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]",
Short: "add dependencies to current module and install them",
Long: `
-Get resolves and adds dependencies to the current development module
-and then builds and installs them.
-
-The first step is to resolve which dependencies to add.
-
-For each named package or package pattern, get must decide which version of
-the corresponding module to use. By default, get looks up the latest tagged
-release version, such as v0.4.5 or v1.2.3. If there are no tagged release
-versions, get looks up the latest tagged pre-release version, such as
-v0.0.1-pre1. If there are no tagged versions at all, get looks up the latest
-known commit. If the module is not already required at a later version
-(for example, a pre-release newer than the latest release), get will use
-the version it looked up. Otherwise, get will use the currently
-required version.
-
-This default version selection can be overridden by adding an @version
-suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'.
-The version may be a prefix: @v1 denotes the latest available version starting
-with v1. See 'go help modules' under the heading 'Module queries' for the
-full query syntax.
-
-For modules stored in source control repositories, the version suffix can
-also be a commit hash, branch identifier, or other syntax known to the
-source control system, as in 'go get golang.org/x/text@master'. Note that
-branches with names that overlap with other module query syntax cannot be
-selected explicitly. For example, the suffix @v2 means the latest version
-starting with v2, not the branch named v2.
-
-If a module under consideration is already a dependency of the current
-development module, then get will update the required version.
-Specifying a version earlier than the current required version is valid and
-downgrades the dependency. The version suffix @none indicates that the
-dependency should be removed entirely, downgrading or removing modules
-depending on it as needed.
-
-The version suffix @latest explicitly requests the latest minor release of
-the module named by the given path. The suffix @upgrade is like @latest but
-will not downgrade a module if it is already required at a revision or
-pre-release version newer than the latest released version. The suffix
-@patch requests the latest patch release: the latest released version
-with the same major and minor version numbers as the currently required
-version. Like @upgrade, @patch will not downgrade a module already required
-at a newer version. If the path is not already required, @upgrade is
-equivalent to @latest, and @patch is disallowed.
-
-Although get defaults to using the latest version of the module containing
-a named package, it does not use the latest version of that module's
-dependencies. Instead it prefers to use the specific dependency versions
-requested by that module. For example, if the latest A requires module
-B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then 'go get A'
-will use the latest A but then use B v1.2.3, as requested by A. (If there
-are competing requirements for a particular module, then 'go get' resolves
-those requirements by taking the maximum requested version.)
+Get resolves its command-line arguments to packages at specific module versions,
+updates go.mod to require those versions, downloads source code into the
+module cache, then builds and installs the named packages.
+
+To add a dependency for a package or upgrade it to its latest version:
+
+ go get example.com/pkg
+
+To upgrade or downgrade a package to a specific version:
+
+ go get example.com/pkg@v1.2.3
+
+To remove a dependency on a module and downgrade modules that require it:
+
+ go get example.com/mod@none
+
+See https://golang.org/ref/mod#go-get for details.
+
+The 'go install' command may be used to build and install packages. When a
+version is specified, 'go install' runs in module-aware mode and ignores
+the go.mod file in the current directory. For example:
+
+ go install example.com/pkg@v1.2.3
+ go install example.com/pkg@latest
+
+See 'go help install' or https://golang.org/ref/mod#go-install for details.
+
+In addition to build flags (listed in 'go help build') 'go get' accepts the
+following flags.
The -t flag instructs get to consider modules needed to build tests of
packages specified on the command line.
The -u flag instructs get to update modules providing dependencies
of packages named on the command line to use newer minor or patch
-releases when available. Continuing the previous example, 'go get -u A'
-will use the latest A with B v1.3.1 (not B v1.2.3). If B requires module C,
-but C does not provide any packages needed to build packages in A
-(not including tests), then C will not be updated.
+releases when available.
The -u=patch flag (not -u patch) also instructs get to update dependencies,
but changes the default to select patch releases.
-Continuing the previous example,
-'go get -u=patch A@latest' will use the latest A with B v1.2.4 (not B v1.2.3),
-while 'go get -u=patch A' will use a patch release of A instead.
When the -t and -u flags are used together, get will update
test dependencies as well.
-In general, adding a new dependency may require upgrading
-existing dependencies to keep a working build, and 'go get' does
-this automatically. Similarly, downgrading one dependency may
-require downgrading other dependencies, and 'go get' does
-this automatically as well.
-
The -insecure flag permits fetching from repositories and resolving
custom domains using insecure schemes such as HTTP, and also bypassess
module sum validation using the checksum database. Use with caution.
@@ -143,12 +107,8 @@ To permit the use of insecure schemes, use the GOINSECURE environment
variable instead. To bypass module sum validation, use GOPRIVATE or
GONOSUMDB. See 'go help environment' for details.
-The second step is to download (if needed), build, and install
-the named packages.
-
-The -d flag instructs get to skip this step, downloading source code
-needed to build the named packages and their dependencies, but not
-building or installing.
+The -d flag instructs get not to build or install packages. get will only
+update go.mod and download source code needed to build packages.
Building and installing packages with get is deprecated. In a future release,
the -d flag will be enabled by default, and 'go get' will be only be used to
@@ -157,31 +117,14 @@ dependencies from the current module, use 'go install'. To install a package
ignoring the current module, use 'go install' with an @version suffix like
"@latest" after each argument.
-If an argument names a module but not a package (because there is no
-Go source code in the module's root directory), then the install step
-is skipped for that argument, instead of causing a build failure.
-For example 'go get golang.org/x/perf' succeeds even though there
-is no code corresponding to that import path.
-
-Note that package patterns are allowed and are expanded after resolving
-the module versions. For example, 'go get golang.org/x/perf/cmd/...'
-adds the latest golang.org/x/perf and then installs the commands in that
-latest version.
-
-With no package arguments, 'go get' applies to Go package in the
-current directory, if any. In particular, 'go get -u' and
-'go get -u=patch' update all the dependencies of that package.
-With no package arguments and also without -u, 'go get' is not much more
-than 'go install', and 'go get -d' not much more than 'go list'.
-
-For more about modules, see 'go help modules'.
+For more about modules, see https://golang.org/ref/mod.
For more about specifying packages, see 'go help packages'.
This text describes the behavior of get using modules to manage source
code and dependencies. If instead the go command is running in GOPATH
mode, the details of get's flags and effects change, as does 'go help get'.
-See 'go help modules' and 'go help gopath-get'.
+See 'go help gopath-get'.
See also: go build, go install, go clean, go mod.
`,
@@ -1558,7 +1501,7 @@ func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns
}
}
if retractPath != "" {
- fmt.Fprintf(os.Stderr, "go: run 'go get %s@latest' to switch to the latest unretracted version\n", retractPath)
+ fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest", retractPath)
}
}
diff --git a/libgo/go/cmd/go/internal/modget/query.go b/libgo/go/cmd/go/internal/modget/query.go
index 20eb0b6364e..d8364c8c0d3 100644
--- a/libgo/go/cmd/go/internal/modget/query.go
+++ b/libgo/go/cmd/go/internal/modget/query.go
@@ -281,14 +281,14 @@ func reportError(q *query, err error) {
// TODO(bcmills): Use errors.As to unpack these errors instead of parsing
// strings with regular expressions.
- patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:)\"`]|$)")
+ patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:;)\"`]|$)")
if patternRE.MatchString(errStr) {
if q.rawVersion == "" {
base.Errorf("go get: %s", errStr)
return
}
- versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :)\"`]|$)")
+ versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :;)\"`]|$)")
if versionRE.MatchString(errStr) {
base.Errorf("go get: %s", errStr)
return
diff --git a/libgo/go/cmd/go/internal/modload/buildlist.go b/libgo/go/cmd/go/internal/modload/buildlist.go
index 896adebbb19..45f220a6ee6 100644
--- a/libgo/go/cmd/go/internal/modload/buildlist.go
+++ b/libgo/go/cmd/go/internal/modload/buildlist.go
@@ -28,6 +28,11 @@ import (
//
var buildList []module.Version
+// additionalExplicitRequirements is a list of modules paths for which
+// WriteGoMod should record explicit requirements, even if they would be
+// selected without those requirements. Each path must also appear in buildList.
+var additionalExplicitRequirements []string
+
// capVersionSlice returns s with its cap reduced to its length.
func capVersionSlice(s []module.Version) []module.Version {
return s[:len(s):len(s)]
@@ -121,6 +126,12 @@ func EditBuildList(ctx context.Context, add, mustSelect []module.Version) error
if !inconsistent {
buildList = final
+ additionalExplicitRequirements = make([]string, 0, len(mustSelect))
+ for _, m := range mustSelect {
+ if m.Version != "none" {
+ additionalExplicitRequirements = append(additionalExplicitRequirements, m.Path)
+ }
+ }
return nil
}
diff --git a/libgo/go/cmd/go/internal/modload/help.go b/libgo/go/cmd/go/internal/modload/help.go
index d81dfd56fb5..1cb58961bed 100644
--- a/libgo/go/cmd/go/internal/modload/help.go
+++ b/libgo/go/cmd/go/internal/modload/help.go
@@ -12,395 +12,16 @@ var HelpModules = &base.Command{
UsageLine: "modules",
Short: "modules, module versions, and more",
Long: `
-A module is a collection of related Go packages.
-Modules are the unit of source code interchange and versioning.
-The go command has direct support for working with modules,
-including recording and resolving dependencies on other modules.
-Modules replace the old GOPATH-based approach to specifying
-which source files are used in a given build.
+Modules are how Go manages dependencies.
-Module support
+A module is a collection of packages that are released, versioned, and
+distributed together. Modules may be downloaded directly from version control
+repositories or from module proxy servers.
-The go command includes support for Go modules. Module-aware mode is active
-by default whenever a go.mod file is found in the current directory or in
-any parent directory.
+For a series of tutorials on modules, see
+https://golang.org/doc/tutorial/create-module.
-The quickest way to take advantage of module support is to check out your
-repository, create a go.mod file (described in the next section) there, and run
-go commands from within that file tree.
-
-For more fine-grained control, the go command continues to respect
-a temporary environment variable, GO111MODULE, which can be set to one
-of three string values: off, on, or auto (the default).
-If GO111MODULE=on, then the go command requires the use of modules,
-never consulting GOPATH. We refer to this as the command
-being module-aware or running in "module-aware mode".
-If GO111MODULE=off, then the go command never uses
-module support. Instead it looks in vendor directories and GOPATH
-to find dependencies; we now refer to this as "GOPATH mode."
-If GO111MODULE=auto or is unset, then the go command enables or disables
-module support based on the current directory.
-Module support is enabled only when the current directory contains a
-go.mod file or is below a directory containing a go.mod file.
-
-In module-aware mode, GOPATH no longer defines the meaning of imports
-during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod)
-and installed commands (in GOPATH/bin, unless GOBIN is set).
-
-Defining a module
-
-A module is defined by a tree of Go source files with a go.mod file
-in the tree's root directory. The directory containing the go.mod file
-is called the module root. Typically the module root will also correspond
-to a source code repository root (but in general it need not).
-The module is the set of all Go packages in the module root and its
-subdirectories, but excluding subtrees with their own go.mod files.
-
-The "module path" is the import path prefix corresponding to the module root.
-The go.mod file defines the module path and lists the specific versions
-of other modules that should be used when resolving imports during a build,
-by giving their module paths and versions.
-
-For example, this go.mod declares that the directory containing it is the root
-of the module with path example.com/m, and it also declares that the module
-depends on specific versions of golang.org/x/text and gopkg.in/yaml.v2:
-
- module example.com/m
-
- require (
- golang.org/x/text v0.3.0
- gopkg.in/yaml.v2 v2.1.0
- )
-
-The go.mod file can also specify replacements and excluded versions
-that only apply when building the module directly; they are ignored
-when the module is incorporated into a larger build.
-For more about the go.mod file, see 'go help go.mod'.
-
-To start a new module, simply create a go.mod file in the root of the
-module's directory tree, containing only a module statement.
-The 'go mod init' command can be used to do this:
-
- go mod init example.com/m
-
-In a project already using an existing dependency management tool like
-godep, glide, or dep, 'go mod init' will also add require statements
-matching the existing configuration.
-
-Once the go.mod file exists, no additional steps are required:
-go commands like 'go build', 'go test', or even 'go list' will automatically
-add new dependencies as needed to satisfy imports.
-
-The main module and the build list
-
-The "main module" is the module containing the directory where the go command
-is run. The go command finds the module root by looking for a go.mod in the
-current directory, or else the current directory's parent directory,
-or else the parent's parent directory, and so on.
-
-The main module's go.mod file defines the precise set of packages available
-for use by the go command, through require, replace, and exclude statements.
-Dependency modules, found by following require statements, also contribute
-to the definition of that set of packages, but only through their go.mod
-files' require statements: any replace and exclude statements in dependency
-modules are ignored. The replace and exclude statements therefore allow the
-main module complete control over its own build, without also being subject
-to complete control by dependencies.
-
-The set of modules providing packages to builds is called the "build list".
-The build list initially contains only the main module. Then the go command
-adds to the list the exact module versions required by modules already
-on the list, recursively, until there is nothing left to add to the list.
-If multiple versions of a particular module are added to the list,
-then at the end only the latest version (according to semantic version
-ordering) is kept for use in the build.
-
-The 'go list' command provides information about the main module
-and the build list. For example:
-
- go list -m # print path of main module
- go list -m -f={{.Dir}} # print root directory of main module
- go list -m all # print build list
-
-Maintaining module requirements
-
-The go.mod file is meant to be readable and editable by both programmers and
-tools. Most updates to dependencies can be performed using "go get" and
-"go mod tidy". Other module-aware build commands may be invoked using the
--mod=mod flag to automatically add missing requirements and fix inconsistencies.
-
-The "go get" command updates go.mod to change the module versions used in a
-build. An upgrade of one module may imply upgrading others, and similarly a
-downgrade of one module may imply downgrading others. The "go get" command
-makes these implied changes as well. See "go help module-get".
-
-The "go mod" command provides other functionality for use in maintaining
-and understanding modules and go.mod files. See "go help mod", particularly
-"go help mod tidy" and "go help mod edit".
-
-As part of maintaining the require statements in go.mod, the go command
-tracks which ones provide packages imported directly by the current module
-and which ones provide packages only used indirectly by other module
-dependencies. Requirements needed only for indirect uses are marked with a
-"// indirect" comment in the go.mod file. Indirect requirements may be
-automatically removed from the go.mod file once they are implied by other
-direct requirements. Indirect requirements only arise when using modules
-that fail to state some of their own dependencies or when explicitly
-upgrading a module's dependencies ahead of its own stated requirements.
-
-The -mod build flag provides additional control over the updating and use of
-go.mod for commands that build packages like "go build" and "go test".
-
-If invoked with -mod=readonly (the default in most situations), the go command
-reports an error if a package named on the command line or an imported package
-is not provided by any module in the build list computed from the main module's
-requirements. The go command also reports an error if a module's checksum is
-missing from go.sum (see Module downloading and verification). Either go.mod or
-go.sum must be updated in these situations.
-
-If invoked with -mod=mod, the go command automatically updates go.mod and
-go.sum, fixing inconsistencies and adding missing requirements and checksums
-as needed. If the go command finds an unfamiliar import, it looks up the
-module containing that import and adds a requirement for the latest version
-of that module to go.mod. In most cases, therefore, one may add an import to
-source code and run "go build", "go test", or even "go list" with -mod=mod:
-as part of analyzing the package, the go command will resolve the import and
-update the go.mod file.
-
-If invoked with -mod=vendor, the go command loads packages from the main
-module's vendor directory instead of downloading modules to and loading packages
-from the module cache. The go command assumes the vendor directory holds
-correct copies of dependencies, and it does not compute the set of required
-module versions from go.mod files. However, the go command does check that
-vendor/modules.txt (generated by "go mod vendor") contains metadata consistent
-with go.mod.
-
-If the go command is not invoked with a -mod flag, and the vendor directory
-is present, and the "go" version in go.mod is 1.14 or higher, the go command
-will act as if it were invoked with -mod=vendor. Otherwise, the -mod flag
-defaults to -mod=readonly.
-
-Note that neither "go get" nor the "go mod" subcommands accept the -mod flag.
-
-Pseudo-versions
-
-The go.mod file and the go command more generally use semantic versions as
-the standard form for describing module versions, so that versions can be
-compared to determine which should be considered earlier or later than another.
-A module version like v1.2.3 is introduced by tagging a revision in the
-underlying source repository. Untagged revisions can be referred to
-using a "pseudo-version" like v0.0.0-yyyymmddhhmmss-abcdefabcdef,
-where the time is the commit time in UTC and the final suffix is the prefix
-of the commit hash. The time portion ensures that two pseudo-versions can
-be compared to determine which happened later, the commit hash identifes
-the underlying commit, and the prefix (v0.0.0- in this example) is derived from
-the most recent tagged version in the commit graph before this commit.
-
-There are three pseudo-version forms:
-
-vX.0.0-yyyymmddhhmmss-abcdefabcdef is used when there is no earlier
-versioned commit with an appropriate major version before the target commit.
-(This was originally the only form, so some older go.mod files use this form
-even for commits that do follow tags.)
-
-vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef is used when the most
-recent versioned commit before the target commit is vX.Y.Z-pre.
-
-vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef is used when the most
-recent versioned commit before the target commit is vX.Y.Z.
-
-Pseudo-versions never need to be typed by hand: the go command will accept
-the plain commit hash and translate it into a pseudo-version (or a tagged
-version if available) automatically. This conversion is an example of a
-module query.
-
-Module queries
-
-The go command accepts a "module query" in place of a module version
-both on the command line and in the main module's go.mod file.
-(After evaluating a query found in the main module's go.mod file,
-the go command updates the file to replace the query with its result.)
-
-A fully-specified semantic version, such as "v1.2.3",
-evaluates to that specific version.
-
-A semantic version prefix, such as "v1" or "v1.2",
-evaluates to the latest available tagged version with that prefix.
-
-A semantic version comparison, such as "<v1.2.3" or ">=v1.5.6",
-evaluates to the available tagged version nearest to the comparison target
-(the latest version for < and <=, the earliest version for > and >=).
-
-The string "latest" matches the latest available tagged version,
-or else the underlying source repository's latest untagged revision.
-
-The string "upgrade" is like "latest", but if the module is
-currently required at a later version than the version "latest"
-would select (for example, a newer pre-release version), "upgrade"
-will select the later version instead.
-
-The string "patch" matches the latest available tagged version
-of a module with the same major and minor version numbers as the
-currently required version. If no version is currently required,
-"patch" is equivalent to "latest".
-
-A revision identifier for the underlying source repository, such as
-a commit hash prefix, revision tag, or branch name, selects that
-specific code revision. If the revision is also tagged with a
-semantic version, the query evaluates to that semantic version.
-Otherwise the query evaluates to a pseudo-version for the commit.
-Note that branches and tags with names that are matched by other
-query syntax cannot be selected this way. For example, the query
-"v2" means the latest version starting with "v2", not the branch
-named "v2".
-
-All queries prefer release versions to pre-release versions.
-For example, "<v1.2.3" will prefer to return "v1.2.2"
-instead of "v1.2.3-pre1", even though "v1.2.3-pre1" is nearer
-to the comparison target.
-
-Module versions disallowed by exclude statements in the
-main module's go.mod are considered unavailable and cannot
-be returned by queries.
-
-For example, these commands are all valid:
-
- go get github.com/gorilla/mux@latest # same (@latest is default for 'go get')
- go get github.com/gorilla/mux@v1.6.2 # records v1.6.2
- go get github.com/gorilla/mux@e3702bed2 # records v1.6.2
- go get github.com/gorilla/mux@c856192 # records v0.0.0-20180517173623-c85619274f5d
- go get github.com/gorilla/mux@master # records current meaning of master
-
-Module compatibility and semantic versioning
-
-The go command requires that modules use semantic versions and expects that
-the versions accurately describe compatibility: it assumes that v1.5.4 is a
-backwards-compatible replacement for v1.5.3, v1.4.0, and even v1.0.0.
-More generally the go command expects that packages follow the
-"import compatibility rule", which says:
-
-"If an old package and a new package have the same import path,
-the new package must be backwards compatible with the old package."
-
-Because the go command assumes the import compatibility rule,
-a module definition can only set the minimum required version of one
-of its dependencies: it cannot set a maximum or exclude selected versions.
-Still, the import compatibility rule is not a guarantee: it may be that
-v1.5.4 is buggy and not a backwards-compatible replacement for v1.5.3.
-Because of this, the go command never updates from an older version
-to a newer version of a module unasked.
-
-In semantic versioning, changing the major version number indicates a lack
-of backwards compatibility with earlier versions. To preserve import
-compatibility, the go command requires that modules with major version v2
-or later use a module path with that major version as the final element.
-For example, version v2.0.0 of example.com/m must instead use module path
-example.com/m/v2, and packages in that module would use that path as
-their import path prefix, as in example.com/m/v2/sub/pkg. Including the
-major version number in the module path and import paths in this way is
-called "semantic import versioning". Pseudo-versions for modules with major
-version v2 and later begin with that major version instead of v0, as in
-v2.0.0-20180326061214-4fc5987536ef.
-
-As a special case, module paths beginning with gopkg.in/ continue to use the
-conventions established on that system: the major version is always present,
-and it is preceded by a dot instead of a slash: gopkg.in/yaml.v1
-and gopkg.in/yaml.v2, not gopkg.in/yaml and gopkg.in/yaml/v2.
-
-The go command treats modules with different module paths as unrelated:
-it makes no connection between example.com/m and example.com/m/v2.
-Modules with different major versions can be used together in a build
-and are kept separate by the fact that their packages use different
-import paths.
-
-In semantic versioning, major version v0 is for initial development,
-indicating no expectations of stability or backwards compatibility.
-Major version v0 does not appear in the module path, because those
-versions are preparation for v1.0.0, and v1 does not appear in the
-module path either.
-
-Code written before the semantic import versioning convention
-was introduced may use major versions v2 and later to describe
-the same set of unversioned import paths as used in v0 and v1.
-To accommodate such code, if a source code repository has a
-v2.0.0 or later tag for a file tree with no go.mod, the version is
-considered to be part of the v1 module's available versions
-and is given an +incompatible suffix when converted to a module
-version, as in v2.0.0+incompatible. The +incompatible tag is also
-applied to pseudo-versions derived from such versions, as in
-v2.0.1-0.yyyymmddhhmmss-abcdefabcdef+incompatible.
-
-In general, having a dependency in the build list (as reported by 'go list -m all')
-on a v0 version, pre-release version, pseudo-version, or +incompatible version
-is an indication that problems are more likely when upgrading that
-dependency, since there is no expectation of compatibility for those.
-
-See https://research.swtch.com/vgo-import for more information about
-semantic import versioning, and see https://semver.org/ for more about
-semantic versioning.
-
-Module code layout
-
-For now, see https://research.swtch.com/vgo-module for information
-about how source code in version control systems is mapped to
-module file trees.
-
-Module downloading and verification
-
-The go command can fetch modules from a proxy or connect to source control
-servers directly, according to the setting of the GOPROXY environment
-variable (see 'go help env'). The default setting for GOPROXY is
-"https://proxy.golang.org,direct", which means to try the
-Go module mirror run by Google and fall back to a direct connection
-if the proxy reports that it does not have the module (HTTP error 404 or 410).
-See https://proxy.golang.org/privacy for the service's privacy policy.
-
-If GOPROXY is set to the string "direct", downloads use a direct connection to
-source control servers. Setting GOPROXY to "off" disallows downloading modules
-from any source. Otherwise, GOPROXY is expected to be list of module proxy URLs
-separated by either comma (,) or pipe (|) characters, which control error
-fallback behavior. For each request, the go command tries each proxy in
-sequence. If there is an error, the go command will try the next proxy in the
-list if the error is a 404 or 410 HTTP response or if the current proxy is
-followed by a pipe character, indicating it is safe to fall back on any error.
-
-The GOPRIVATE and GONOPROXY environment variables allow bypassing
-the proxy for selected modules. See 'go help private' for details.
-
-No matter the source of the modules, the go command checks downloads against
-known checksums, to detect unexpected changes in the content of any specific
-module version from one day to the next. This check first consults the current
-module's go.sum file but falls back to the Go checksum database, controlled by
-the GOSUMDB and GONOSUMDB environment variables. See 'go help module-auth'
-for details.
-
-See 'go help goproxy' for details about the proxy protocol and also
-the format of the cached downloaded packages.
-
-Modules and vendoring
-
-When using modules, the go command typically satisfies dependencies by
-downloading modules from their sources and using those downloaded copies
-(after verification, as described in the previous section). Vendoring may
-be used to allow interoperation with older versions of Go, or to ensure
-that all files used for a build are stored together in a single file tree.
-
-The command 'go mod vendor' constructs a directory named vendor in the main
-module's root directory that contains copies of all packages needed to support
-builds and tests of packages in the main module. 'go mod vendor' also
-creates the file vendor/modules.txt that contains metadata about vendored
-packages and module versions. This file should be kept consistent with go.mod:
-when vendoring is used, 'go mod vendor' should be run after go.mod is updated.
-
-If the vendor directory is present in the main module's root directory, it will
-be used automatically if the "go" version in the main module's go.mod file is
-1.14 or higher. Build commands like 'go build' and 'go test' will load packages
-from the vendor directory instead of accessing the network or the local module
-cache. To explicitly enable vendoring, invoke the go command with the flag
--mod=vendor. To disable vendoring, use the flag -mod=mod.
-
-Unlike vendoring in GOPATH, the go command ignores vendor directories in
-locations other than the main module's root directory.
+For a detailed reference on modules, see https://golang.org/ref/mod.
`,
}
@@ -413,87 +34,22 @@ file in its root. When the go command is run, it looks in the current
directory and then successive parent directories to find the go.mod
marking the root of the main (current) module.
-The go.mod file itself is line-oriented, with // comments but
-no /* */ comments. Each line holds a single directive, made up of a
-verb followed by arguments. For example:
-
- module my/thing
- go 1.12
- require other/thing v1.0.2
- require new/thing/v2 v2.3.4
- exclude old/thing v1.2.3
- replace bad/thing v1.4.5 => good/thing v1.4.5
- retract v1.5.6
-
-The verbs are
- module, to define the module path;
- go, to set the expected language version;
- require, to require a particular module at a given version or later;
- exclude, to exclude a particular module version from use;
- replace, to replace a module version with a different module version; and
- retract, to indicate a previously released version should not be used.
-Exclude and replace apply only in the main module's go.mod and are ignored
-in dependencies. See https://golang.org/ref/mod for details.
-
-The leading verb can be factored out of adjacent lines to create a block,
-like in Go imports:
-
- require (
- new/thing/v2 v2.3.4
- old/thing v1.2.3
- )
-
-The go.mod file is designed both to be edited directly and to be
-easily updated by tools. The 'go mod edit' command can be used to
-parse and edit the go.mod file from programs and tools.
-See 'go help mod edit'.
-
-The go command automatically updates go.mod each time it uses the
-module graph, to make sure go.mod always accurately reflects reality
-and is properly formatted. For example, consider this go.mod file:
-
- module M
-
- require (
- A v1
- B v1.0.0
- C v1.0.0
- D v1.2.3
- E dev
- )
-
- exclude D v1.2.3
-
-The update rewrites non-canonical version identifiers to semver form,
-so A's v1 becomes v1.0.0 and E's dev becomes the pseudo-version for the
-latest commit on the dev branch, perhaps v0.0.0-20180523231146-b3f5c0f6e5f1.
-
-The update modifies requirements to respect exclusions, so the
-requirement on the excluded D v1.2.3 is updated to use the next
-available version of D, perhaps D v1.2.4 or D v1.3.0.
+The go.mod file format is described in detail at
+https://golang.org/ref/mod#go-mod-file.
-The update removes redundant or misleading requirements.
-For example, if A v1.0.0 itself requires B v1.2.0 and C v1.0.0,
-then go.mod's requirement of B v1.0.0 is misleading (superseded by
-A's need for v1.2.0), and its requirement of C v1.0.0 is redundant
-(implied by A's need for the same version), so both will be removed.
-If module M contains packages that directly import packages from B or
-C, then the requirements will be kept but updated to the actual
-versions being used.
+To create a new go.mod file, use 'go help init'. For details see
+'go help mod init' or https://golang.org/ref/mod#go-mod-init.
-Finally, the update reformats the go.mod in a canonical formatting, so
-that future mechanical changes will result in minimal diffs.
+To add missing module requirements or remove unneeded requirements,
+use 'go mod tidy'. For details, see 'go help mod tidy' or
+https://golang.org/ref/mod#go-mod-tidy.
-Because the module graph defines the meaning of import statements, any
-commands that load packages also use and therefore update go.mod,
-including go build, go get, go install, go list, go test, go mod graph,
-go mod tidy, and go mod why.
+To add, upgrade, downgrade, or remove a specific module requirement, use
+'go get'. For details, see 'go help module-get' or
+https://golang.org/ref/mod#go-get.
-The expected language version, set by the go directive, determines
-which language features are available when compiling the module.
-Language features available in that version will be available for use.
-Language features removed in earlier versions, or added in later versions,
-will not be available. Note that the language version does not affect
-build tags, which are determined by the Go release being used.
+To make other changes or to parse go.mod as JSON for use by other tools,
+use 'go mod edit'. See 'go help mod edit' or
+https://golang.org/ref/mod#go-mod-edit.
`,
}
diff --git a/libgo/go/cmd/go/internal/modload/import.go b/libgo/go/cmd/go/internal/modload/import.go
index ce5671728e0..182429aee41 100644
--- a/libgo/go/cmd/go/internal/modload/import.go
+++ b/libgo/go/cmd/go/internal/modload/import.go
@@ -31,10 +31,6 @@ type ImportMissingError struct {
Module module.Version
QueryErr error
- // inAll indicates whether Path is in the "all" package pattern,
- // and thus would be added by 'go mod tidy'.
- inAll bool
-
// isStd indicates whether we would expect to find the package in the standard
// library. This is normally true for all dotless import paths, but replace
// directives can cause us to treat the replaced paths as also being in
@@ -58,7 +54,7 @@ func (e *ImportMissingError) Error() string {
if e.QueryErr != nil {
return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr)
}
- if cfg.BuildMod == "mod" {
+ if cfg.BuildMod == "mod" || (cfg.BuildMod == "readonly" && allowMissingModuleImports) {
return "cannot find module providing package " + e.Path
}
@@ -67,16 +63,14 @@ func (e *ImportMissingError) Error() string {
if !modfetch.IsZeroPseudoVersion(e.replaced.Version) {
suggestArg = e.replaced.String()
}
- return fmt.Sprintf("module %s provides package %s and is replaced but not required; try 'go get -d %s' to add it", e.replaced.Path, e.Path, suggestArg)
+ return fmt.Sprintf("module %s provides package %s and is replaced but not required; to add it:\n\tgo get %s", e.replaced.Path, e.Path, suggestArg)
}
suggestion := ""
if !HasModRoot() {
suggestion = ": working directory is not part of a module"
- } else if e.inAll {
- suggestion = "; try 'go mod tidy' to add it"
} else {
- suggestion = fmt.Sprintf("; try 'go get -d %s' to add it", e.Path)
+ suggestion = fmt.Sprintf("; to add it:\n\tgo get %s", e.Path)
}
return fmt.Sprintf("no required module provides package %s%s", e.Path, suggestion)
}
@@ -136,24 +130,57 @@ func (e *AmbiguousImportError) Error() string {
}
// ImportMissingSumError is reported in readonly mode when we need to check
-// if a module in the build list contains a package, but we don't have a sum
-// for its .zip file.
+// if a module contains a package, but we don't have a sum for its .zip file.
+// We might need sums for multiple modules to verify the package is unique.
+//
+// TODO(#43653): consolidate multiple errors of this type into a single error
+// that suggests a 'go get' command for root packages that transtively import
+// packages from modules with missing sums. load.CheckPackageErrors would be
+// a good place to consolidate errors, but we'll need to attach the import
+// stack here.
type ImportMissingSumError struct {
- importPath string
- found, inAll bool
+ importPath string
+ found bool
+ mods []module.Version
+ importer, importerVersion string // optional, but used for additional context
+ importerIsTest bool
}
func (e *ImportMissingSumError) Error() string {
+ var importParen string
+ if e.importer != "" {
+ importParen = fmt.Sprintf(" (imported by %s)", e.importer)
+ }
var message string
if e.found {
- message = fmt.Sprintf("missing go.sum entry needed to verify package %s is provided by exactly one module", e.importPath)
+ message = fmt.Sprintf("missing go.sum entry needed to verify package %s%s is provided by exactly one module", e.importPath, importParen)
} else {
- message = fmt.Sprintf("missing go.sum entry for module providing package %s", e.importPath)
+ message = fmt.Sprintf("missing go.sum entry for module providing package %s%s", e.importPath, importParen)
}
- if e.inAll {
- return message + "; try 'go mod tidy' to add it"
+ var hint string
+ if e.importer == "" {
+ // Importing package is unknown, or the missing package was named on the
+ // command line. Recommend 'go mod download' for the modules that could
+ // provide the package, since that shouldn't change go.mod.
+ args := make([]string, len(e.mods))
+ for i, mod := range e.mods {
+ args[i] = mod.Path
+ }
+ hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
+ } else {
+ // Importing package is known (common case). Recommend 'go get' on the
+ // current version of the importing package.
+ tFlag := ""
+ if e.importerIsTest {
+ tFlag = " -t"
+ }
+ version := ""
+ if e.importerVersion != "" {
+ version = "@" + e.importerVersion
+ }
+ hint = fmt.Sprintf("; to add:\n\tgo get%s %s%s", tFlag, e.importer, version)
}
- return message
+ return message + hint
}
func (e *ImportMissingSumError) ImportPath() string {
@@ -244,7 +271,7 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
// Check each module on the build list.
var dirs []string
var mods []module.Version
- haveSumErr := false
+ var sumErrMods []module.Version
for _, m := range buildList {
if !maybeInModule(path, m.Path) {
// Avoid possibly downloading irrelevant modules.
@@ -257,8 +284,9 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
// We are missing a sum needed to fetch a module in the build list.
// We can't verify that the package is unique, and we may not find
// the package at all. Keep checking other modules to decide which
- // error to report.
- haveSumErr = true
+ // error to report. Multiple sums may be missing if we need to look in
+ // multiple nested modules to resolve the import.
+ sumErrMods = append(sumErrMods, m)
continue
}
// Report fetch error.
@@ -279,8 +307,12 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
if len(mods) > 1 {
return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods}
}
- if haveSumErr {
- return module.Version{}, "", &ImportMissingSumError{importPath: path, found: len(mods) > 0}
+ if len(sumErrMods) > 0 {
+ return module.Version{}, "", &ImportMissingSumError{
+ importPath: path,
+ mods: sumErrMods,
+ found: len(mods) > 0,
+ }
}
if len(mods) == 1 {
return mods[0], dirs[0], nil
@@ -365,7 +397,7 @@ func queryImport(ctx context.Context, path string) (module.Version, error) {
return module.Version{}, &ImportMissingError{Path: path, isStd: true}
}
- if cfg.BuildMod == "readonly" {
+ if cfg.BuildMod == "readonly" && !allowMissingModuleImports {
// In readonly mode, we can't write go.mod, so we shouldn't try to look up
// the module. If readonly mode was enabled explicitly, include that in
// the error message.
@@ -547,7 +579,7 @@ func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, i
mod = r
}
- if cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) {
+ if HasModRoot() && cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) {
return "", false, module.VersionError(mod, &sumMissingError{})
}
diff --git a/libgo/go/cmd/go/internal/modload/import_test.go b/libgo/go/cmd/go/internal/modload/import_test.go
index 22d5b82e211..9420dc56460 100644
--- a/libgo/go/cmd/go/internal/modload/import_test.go
+++ b/libgo/go/cmd/go/internal/modload/import_test.go
@@ -58,10 +58,15 @@ var importTests = []struct {
func TestQueryImport(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
- defer func(old bool) {
- allowMissingModuleImports = old
- }(allowMissingModuleImports)
- AllowMissingModuleImports()
+
+ oldAllowMissingModuleImports := allowMissingModuleImports
+ oldRootMode := RootMode
+ defer func() {
+ allowMissingModuleImports = oldAllowMissingModuleImports
+ RootMode = oldRootMode
+ }()
+ allowMissingModuleImports = true
+ RootMode = NoRoot
ctx := context.Background()
diff --git a/libgo/go/cmd/go/internal/modload/init.go b/libgo/go/cmd/go/internal/modload/init.go
index 3f70d041451..bc8d17e0a5f 100644
--- a/libgo/go/cmd/go/internal/modload/init.go
+++ b/libgo/go/cmd/go/internal/modload/init.go
@@ -15,6 +15,7 @@ import (
"os"
"path"
"path/filepath"
+ "sort"
"strconv"
"strings"
"sync"
@@ -27,6 +28,7 @@ import (
"cmd/go/internal/modfetch"
"cmd/go/internal/mvs"
"cmd/go/internal/search"
+ "cmd/go/internal/str"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
@@ -200,6 +202,8 @@ func Init() {
}
// We're in module mode. Set any global variables that need to be set.
+ cfg.ModulesEnabled = true
+ setDefaultBuildMod()
list := filepath.SplitList(cfg.BuildContext.GOPATH)
if len(list) == 0 || list[0] == "" {
base.Fatalf("missing $GOPATH")
@@ -209,8 +213,6 @@ func Init() {
base.Fatalf("$GOPATH/go.mod exists but should not")
}
- cfg.ModulesEnabled = true
-
if modRoot == "" {
// We're in module mode, but not inside a module.
//
@@ -346,8 +348,8 @@ func die() {
// ensuring requirements are consistent. WriteGoMod should be called later to
// write changes out to disk or report errors in readonly mode.
//
-// As a side-effect, LoadModFile sets a default for cfg.BuildMod if it does not
-// already have an explicit value.
+// As a side-effect, LoadModFile may change cfg.BuildMod to "vendor" if
+// -mod wasn't set explicitly and automatic vendoring should be enabled.
func LoadModFile(ctx context.Context) {
if len(buildList) > 0 {
return
@@ -378,14 +380,14 @@ func LoadModFile(ctx context.Context) {
if f.Module == nil {
// No module declaration. Must add module path.
- base.Fatalf("go: no module declaration in go.mod.\n\tRun 'go mod edit -module=example.com/mod' to specify the module path.")
+ base.Fatalf("go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod")
}
if err := checkModulePathLax(f.Module.Mod.Path); err != nil {
base.Fatalf("go: %v", err)
}
- setDefaultBuildMod()
+ setDefaultBuildMod() // possibly enable automatic vendoring
modFileToBuildList()
if cfg.BuildMod == "vendor" {
readVendorList()
@@ -456,7 +458,7 @@ func CreateModFile(ctx context.Context, modPath string) {
}
}
if !empty {
- fmt.Fprintf(os.Stderr, "go: run 'go mod tidy' to add module requirements and sums\n")
+ fmt.Fprintf(os.Stderr, "go: to add module requirements and sums:\n\tgo mod tidy\n")
}
}
@@ -584,8 +586,8 @@ func modFileToBuildList() {
buildList = list
}
-// setDefaultBuildMod sets a default value for cfg.BuildMod
-// if it is currently empty.
+// setDefaultBuildMod sets a default value for cfg.BuildMod if the -mod flag
+// wasn't provided. setDefaultBuildMod may be called multiple times.
func setDefaultBuildMod() {
if cfg.BuildModExplicit {
// Don't override an explicit '-mod=' argument.
@@ -606,7 +608,7 @@ func setDefaultBuildMod() {
if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
modGo := "unspecified"
- if index.goVersionV != "" {
+ if index != nil && index.goVersionV != "" {
if semver.Compare(index.goVersionV, "v1.14") >= 0 {
// The Go version is at least 1.14, and a vendor directory exists.
// Set -mod=vendor by default.
@@ -845,13 +847,15 @@ func AllowWriteGoMod() {
// MinReqs returns a Reqs with minimal additional dependencies of Target,
// as will be written to go.mod.
func MinReqs() mvs.Reqs {
- var retain []string
+ retain := append([]string{}, additionalExplicitRequirements...)
for _, m := range buildList[1:] {
_, explicit := index.require[m]
if explicit || loaded.direct[m.Path] {
retain = append(retain, m.Path)
}
}
+ sort.Strings(retain)
+ str.Uniq(&retain)
min, err := mvs.Req(Target, retain, &mvsReqs{buildList: buildList})
if err != nil {
base.Fatalf("go: %v", err)
@@ -903,7 +907,7 @@ func WriteGoMod() {
} else if cfg.BuildModReason != "" {
base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason)
} else {
- base.Fatalf("go: updates to go.mod needed; try 'go mod tidy' first")
+ base.Fatalf("go: updates to go.mod needed; to update it:\n\tgo mod tidy")
}
}
@@ -972,9 +976,12 @@ func WriteGoMod() {
// It also contains entries for go.mod files needed for MVS (the version
// of these entries ends with "/go.mod").
//
-// If addDirect is true, the set also includes sums for modules directly
-// required by go.mod, as represented by the index, with replacements applied.
-func keepSums(addDirect bool) map[module.Version]bool {
+// If keepBuildListZips is true, the set also includes sums for zip files for
+// all modules in the build list with replacements applied. 'go get' and
+// 'go mod download' may add sums to this set when adding a requirement on a
+// module without a root package or when downloading a direct or indirect
+// dependency.
+func keepSums(keepBuildListZips bool) map[module.Version]bool {
// Re-derive the build list using the current list of direct requirements.
// Keep the sum for the go.mod of each visited module version (or its
// replacement).
@@ -1003,19 +1010,20 @@ func keepSums(addDirect bool) map[module.Version]bool {
panic(fmt.Sprintf("unexpected error reloading build list: %v", err))
}
+ actualMods := make(map[string]module.Version)
+ for _, m := range buildList[1:] {
+ if r := Replacement(m); r.Path != "" {
+ actualMods[m.Path] = r
+ } else {
+ actualMods[m.Path] = m
+ }
+ }
+
// Add entries for modules in the build list with paths that are prefixes of
// paths of loaded packages. We need to retain sums for modules needed to
// report ambiguous import errors. We use our re-derived build list,
// since the global build list may have been tidied.
if loaded != nil {
- actualMods := make(map[string]module.Version)
- for _, m := range buildList[1:] {
- if r := Replacement(m); r.Path != "" {
- actualMods[m.Path] = r
- } else {
- actualMods[m.Path] = m
- }
- }
for _, pkg := range loaded.pkgs {
if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil {
continue
@@ -1028,17 +1036,13 @@ func keepSums(addDirect bool) map[module.Version]bool {
}
}
- // Add entries for modules directly required by go.mod.
- if addDirect {
- for m := range index.require {
- var kept module.Version
- if r := Replacement(m); r.Path != "" {
- kept = r
- } else {
- kept = m
- }
- keep[kept] = true
- keep[module.Version{Path: kept.Path, Version: kept.Version + "/go.mod"}] = true
+ // Add entries for the zip of each module in the build list.
+ // We might not need all of these (tidy does not add them), but they may be
+ // added by a specific 'go get' or 'go mod download' command to resolve
+ // missing import sum errors.
+ if keepBuildListZips {
+ for _, m := range actualMods {
+ keep[m] = true
}
}
@@ -1058,9 +1062,8 @@ func (r *keepSumReqs) Required(m module.Version) ([]module.Version, error) {
}
func TrimGoSum() {
- // Don't retain sums for direct requirements in go.mod. When TrimGoSum is
- // called, go.mod has not been updated, and it may contain requirements on
- // modules deleted from the build list.
- addDirect := false
- modfetch.TrimGoSum(keepSums(addDirect))
+ // Don't retain sums for the zip file of every module in the build list.
+ // We may not need them all to build the main module's packages.
+ keepBuildListZips := false
+ modfetch.TrimGoSum(keepSums(keepBuildListZips))
}
diff --git a/libgo/go/cmd/go/internal/modload/load.go b/libgo/go/cmd/go/internal/modload/load.go
index 90e990d46c8..6d87acc6d3b 100644
--- a/libgo/go/cmd/go/internal/modload/load.go
+++ b/libgo/go/cmd/go/internal/modload/load.go
@@ -280,11 +280,11 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
checkMultiplePaths()
for _, pkg := range loaded.pkgs {
if pkg.err != nil {
- if pkg.flags.has(pkgInAll) {
- if imErr := (*ImportMissingError)(nil); errors.As(pkg.err, &imErr) {
- imErr.inAll = true
- } else if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
- sumErr.inAll = true
+ if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
+ if importer := pkg.stack; importer != nil {
+ sumErr.importer = importer.path
+ sumErr.importerVersion = importer.mod.Version
+ sumErr.importerIsTest = importer.testOf != nil
}
}
@@ -863,12 +863,21 @@ func loadFromRoots(params loaderParams) *loader {
for _, pkg := range ld.pkgs {
if pkg.mod == Target {
for _, dep := range pkg.imports {
- if dep.mod.Path != "" {
+ if dep.mod.Path != "" && dep.mod.Path != Target.Path && index != nil {
+ _, explicit := index.require[dep.mod]
+ if allowWriteGoMod && cfg.BuildMod == "readonly" && !explicit {
+ // TODO(#40775): attach error to package instead of using
+ // base.Errorf. Ideally, 'go list' should not fail because of this,
+ // but today, LoadPackages calls WriteGoMod unconditionally, which
+ // would fail with a less clear message.
+ base.Errorf("go: %[1]s: package %[2]s imported from implicitly required module; to add missing requirements, run:\n\tgo get %[2]s@%[3]s", pkg.path, dep.path, dep.mod.Version)
+ }
ld.direct[dep.mod.Path] = true
}
}
}
}
+ base.ExitIfErrors()
// If we didn't scan all of the imports from the main module, or didn't use
// imports.AnyTags, then we didn't necessarily load every package that
diff --git a/libgo/go/cmd/go/internal/modload/modfile.go b/libgo/go/cmd/go/internal/modload/modfile.go
index eb05e9f9c91..c6667d0bf79 100644
--- a/libgo/go/cmd/go/internal/modload/modfile.go
+++ b/libgo/go/cmd/go/internal/modload/modfile.go
@@ -446,10 +446,10 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
if actual.Path == "" {
actual = m
}
- if cfg.BuildMod == "readonly" && actual.Version != "" {
+ if HasModRoot() && cfg.BuildMod == "readonly" && actual.Version != "" {
key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
if !modfetch.HaveSum(key) {
- suggestion := fmt.Sprintf("; try 'go mod download %s' to add it", m.Path)
+ suggestion := fmt.Sprintf("; to add it:\n\tgo mod download %s", m.Path)
return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion})
}
}
diff --git a/libgo/go/cmd/go/internal/modload/mvs.go b/libgo/go/cmd/go/internal/modload/mvs.go
index 167d6819b06..31015194f9a 100644
--- a/libgo/go/cmd/go/internal/modload/mvs.go
+++ b/libgo/go/cmd/go/internal/modload/mvs.go
@@ -111,19 +111,3 @@ func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
}
return module.Version{Path: m.Path, Version: "none"}, nil
}
-
-// next returns the next version of m.Path after m.Version.
-// It is only used by the exclusion processing in the Required method,
-// not called directly by MVS.
-func (*mvsReqs) next(m module.Version) (module.Version, error) {
- // TODO(golang.org/issue/38714): thread tracing context through MVS.
- list, err := versions(context.TODO(), m.Path, CheckAllowed)
- if err != nil {
- return module.Version{}, err
- }
- i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) > 0 })
- if i < len(list) {
- return module.Version{Path: m.Path, Version: list[i]}, nil
- }
- return module.Version{Path: m.Path, Version: "none"}, nil
-}
diff --git a/libgo/go/cmd/go/internal/modload/query.go b/libgo/go/cmd/go/internal/modload/query.go
index e35e0fc16e2..8affd179bb2 100644
--- a/libgo/go/cmd/go/internal/modload/query.go
+++ b/libgo/go/cmd/go/internal/modload/query.go
@@ -21,6 +21,7 @@ import (
"cmd/go/internal/imports"
"cmd/go/internal/modfetch"
"cmd/go/internal/search"
+ "cmd/go/internal/str"
"cmd/go/internal/trace"
"golang.org/x/mod/module"
@@ -1005,13 +1006,8 @@ func (rr *replacementRepo) Versions(prefix string) ([]string, error) {
sort.Slice(versions, func(i, j int) bool {
return semver.Compare(versions[i], versions[j]) < 0
})
- uniq := versions[:1]
- for _, v := range versions {
- if v != uniq[len(uniq)-1] {
- uniq = append(uniq, v)
- }
- }
- return uniq, nil
+ str.Uniq(&versions)
+ return versions, nil
}
func (rr *replacementRepo) Stat(rev string) (*modfetch.RevInfo, error) {
diff --git a/libgo/go/cmd/go/internal/modload/vendor.go b/libgo/go/cmd/go/internal/modload/vendor.go
index 80d49053c6c..d8fd91f1fea 100644
--- a/libgo/go/cmd/go/internal/modload/vendor.go
+++ b/libgo/go/cmd/go/internal/modload/vendor.go
@@ -214,6 +214,6 @@ func checkVendorConsistency() {
}
if vendErrors.Len() > 0 {
- base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors)
+ base.Fatalf("go: inconsistent vendoring in %s:%s\n\n\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor", modRoot, vendErrors)
}
}
diff --git a/libgo/go/cmd/go/internal/str/str.go b/libgo/go/cmd/go/internal/str/str.go
index 0413ed8e69e..9106ebf74d5 100644
--- a/libgo/go/cmd/go/internal/str/str.go
+++ b/libgo/go/cmd/go/internal/str/str.go
@@ -96,6 +96,20 @@ func Contains(x []string, s string) bool {
return false
}
+// Uniq removes consecutive duplicate strings from ss.
+func Uniq(ss *[]string) {
+ if len(*ss) <= 1 {
+ return
+ }
+ uniq := (*ss)[:1]
+ for _, s := range *ss {
+ if s != uniq[len(uniq)-1] {
+ uniq = append(uniq, s)
+ }
+ }
+ *ss = uniq
+}
+
func isSpaceByte(c byte) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
diff --git a/libgo/go/cmd/go/internal/test/genflags.go b/libgo/go/cmd/go/internal/test/genflags.go
index 5e83d53980c..30334b0f305 100644
--- a/libgo/go/cmd/go/internal/test/genflags.go
+++ b/libgo/go/cmd/go/internal/test/genflags.go
@@ -9,9 +9,9 @@ package main
import (
"bytes"
"flag"
+ exec "internal/execabs"
"log"
"os"
- "os/exec"
"strings"
"testing"
"text/template"
diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go
index 50fe2dbf393..7fc9e8fbdcd 100644
--- a/libgo/go/cmd/go/internal/test/test.go
+++ b/libgo/go/cmd/go/internal/test/test.go
@@ -11,10 +11,10 @@ import (
"errors"
"fmt"
"go/build"
+ exec "internal/execabs"
"io"
"io/fs"
"os"
- "os/exec"
"path"
"path/filepath"
"regexp"
diff --git a/libgo/go/cmd/go/internal/test/testflag.go b/libgo/go/cmd/go/internal/test/testflag.go
index d2671ff5a79..10e6604da5f 100644
--- a/libgo/go/cmd/go/internal/test/testflag.go
+++ b/libgo/go/cmd/go/internal/test/testflag.go
@@ -325,7 +325,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
if !testC {
buildFlag = "-i"
}
- fmt.Fprintf(os.Stderr, "flag %s is not a 'go test' flag (unknown flags cannot be used with %s)\n", firstUnknownFlag, buildFlag)
+ fmt.Fprintf(os.Stderr, "go test: unknown flag %s cannot be used with %s\n", firstUnknownFlag, buildFlag)
exitWithUsage()
}
diff --git a/libgo/go/cmd/go/internal/tool/tool.go b/libgo/go/cmd/go/internal/tool/tool.go
index 7f4dc868021..95c90ea7c8d 100644
--- a/libgo/go/cmd/go/internal/tool/tool.go
+++ b/libgo/go/cmd/go/internal/tool/tool.go
@@ -8,8 +8,9 @@ package tool
import (
"context"
"fmt"
+ exec "internal/execabs"
"os"
- "os/exec"
+ "os/signal"
"sort"
"strings"
@@ -85,7 +86,19 @@ func runTool(ctx context.Context, cmd *base.Command, args []string) {
Stdout: os.Stdout,
Stderr: os.Stderr,
}
- err := toolCmd.Run()
+ err := toolCmd.Start()
+ if err == nil {
+ c := make(chan os.Signal, 100)
+ signal.Notify(c)
+ go func() {
+ for sig := range c {
+ toolCmd.Process.Signal(sig)
+ }
+ }()
+ err = toolCmd.Wait()
+ signal.Stop(c)
+ close(c)
+ }
if err != nil {
// Only print about the exit status if the command
// didn't even run (not an ExitError) or it didn't exit cleanly
diff --git a/libgo/go/cmd/go/internal/vcs/vcs.go b/libgo/go/cmd/go/internal/vcs/vcs.go
index 4894ecdc356..9feffe07656 100644
--- a/libgo/go/cmd/go/internal/vcs/vcs.go
+++ b/libgo/go/cmd/go/internal/vcs/vcs.go
@@ -8,13 +8,13 @@ import (
"encoding/json"
"errors"
"fmt"
+ exec "internal/execabs"
"internal/lazyregexp"
"internal/singleflight"
"io/fs"
"log"
urlpkg "net/url"
"os"
- "os/exec"
"path/filepath"
"regexp"
"strings"
@@ -729,7 +729,7 @@ func checkGOVCS(vcs *Cmd, root string) error {
if private {
what = "private"
}
- return fmt.Errorf("GOVCS disallows using %s for %s %s", vcs.Cmd, what, root)
+ return fmt.Errorf("GOVCS disallows using %s for %s %s; see 'go help vcs'", vcs.Cmd, what, root)
}
return nil
diff --git a/libgo/go/cmd/go/internal/vet/vetflag.go b/libgo/go/cmd/go/internal/vet/vetflag.go
index ef995ef8353..5bf5cf44467 100644
--- a/libgo/go/cmd/go/internal/vet/vetflag.go
+++ b/libgo/go/cmd/go/internal/vet/vetflag.go
@@ -10,9 +10,9 @@ import (
"errors"
"flag"
"fmt"
+ exec "internal/execabs"
"log"
"os"
- "os/exec"
"path/filepath"
"strings"
diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go
index 7f2617cf1ce..780d639c5d9 100644
--- a/libgo/go/cmd/go/internal/work/build.go
+++ b/libgo/go/cmd/go/internal/work/build.go
@@ -9,9 +9,9 @@ import (
"errors"
"fmt"
"go/build"
+ exec "internal/execabs"
"internal/goroot"
"os"
- "os/exec"
"path"
"path/filepath"
"runtime"
@@ -113,7 +113,10 @@ and test commands:
created with -buildmode=shared.
-mod mode
module download mode to use: readonly, vendor, or mod.
- See 'go help modules' for more.
+ By default, if a vendor directory is present and the go version in go.mod
+ is 1.14 or higher, the go command acts as if -mod=vendor were set.
+ Otherwise, the go command acts as if -mod=readonly were set.
+ See https://golang.org/ref/mod#build-commands for details.
-modcacherw
leave newly-created directories in the module cache read-write
instead of making them read-only.
diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go
index d76988145be..c555d4a9f1e 100644
--- a/libgo/go/cmd/go/internal/work/buildid.go
+++ b/libgo/go/cmd/go/internal/work/buildid.go
@@ -7,8 +7,8 @@ package work
import (
"bytes"
"fmt"
+ exec "internal/execabs"
"os"
- "os/exec"
"strings"
"cmd/go/internal/base"
diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go
index c0b69f9b9e5..f354f3086e4 100644
--- a/libgo/go/cmd/go/internal/work/exec.go
+++ b/libgo/go/cmd/go/internal/work/exec.go
@@ -13,13 +13,13 @@ import (
"encoding/json"
"errors"
"fmt"
+ exec "internal/execabs"
"internal/lazyregexp"
"io"
"io/fs"
"log"
"math/rand"
"os"
- "os/exec"
"path/filepath"
"regexp"
"runtime"
@@ -1166,6 +1166,7 @@ func (b *Builder) vet(ctx context.Context, a *Action) error {
return err
}
+ // TODO(rsc): Why do we pass $GCCGO to go vet?
env := b.cCompilerEnv()
if cfg.BuildToolchainName == "gccgo" {
env = append(env, "GCCGO="+BuildToolchain.compiler())
@@ -2046,6 +2047,9 @@ func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interfa
var buf bytes.Buffer
cmd := exec.Command(cmdline[0], cmdline[1:]...)
+ if cmd.Path != "" {
+ cmd.Args[0] = cmd.Path
+ }
cmd.Stdout = &buf
cmd.Stderr = &buf
cleanup := passLongArgsInResponseFiles(cmd)
@@ -2437,7 +2441,7 @@ func (b *Builder) fcExe() []string {
func (b *Builder) compilerExe(envValue string, def string) []string {
compiler := strings.Fields(envValue)
if len(compiler) == 0 {
- compiler = []string{def}
+ compiler = strings.Fields(def)
}
return compiler
}
@@ -2589,7 +2593,14 @@ func (b *Builder) gccArchArgs() []string {
case "386":
return []string{"-m32"}
case "amd64":
+ if cfg.Goos == "darwin" {
+ return []string{"-arch", "x86_64", "-m64"}
+ }
return []string{"-m64"}
+ case "arm64":
+ if cfg.Goos == "darwin" {
+ return []string{"-arch", "arm64"}
+ }
case "arm":
return []string{"-marm"} // not thumb
case "s390x":
@@ -2721,7 +2732,7 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
for i, f := range cgoLDFLAGS {
flags[i] = strconv.Quote(f)
}
- cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
+ cgoenv = append(cgoenv, "CGO_LDFLAGS="+strings.Join(flags, " "))
}
if cfg.BuildToolchainName == "gccgo" {
diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go
index 793a333663f..36b3f4b05a0 100644
--- a/libgo/go/cmd/go/internal/work/gccgo.go
+++ b/libgo/go/cmd/go/internal/work/gccgo.go
@@ -6,8 +6,8 @@ package work
import (
"fmt"
+ exec "internal/execabs"
"os"
- "os/exec"
"path/filepath"
"strings"
"sync"
@@ -93,6 +93,12 @@ func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg,
args = append(args, "-I", root)
}
}
+ if embedcfg != nil && b.gccSupportsFlag(args[:1], "-fgo-embedcfg=/dev/null") {
+ if err := b.writeFile(objdir+"embedcfg", embedcfg); err != nil {
+ return "", nil, err
+ }
+ args = append(args, "-fgo-embedcfg="+objdir+"embedcfg")
+ }
if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") {
if cfg.BuildTrimpath {