libgo: update to Go1.13

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194698

From-SVN: r275691
This commit is contained in:
Ian Lance Taylor 2019-09-12 23:22:53 +00:00
parent d6ecb707cc
commit 656297e1fe
206 changed files with 3552 additions and 1702 deletions

View File

@ -1,4 +1,4 @@
0950e905939f88c1421f8667ac4dc9e14528471c
ceb1e4f5614b4772eed44f9cf57780e52f44753e
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -1,4 +1,4 @@
60f14fddfee107dedd76c0be6b422a3d8ccc841a
cc8838d645b2b7026c1f3aaceb011775c5ca3a08
The first line of this file holds the git revision number of the
last merge done from the master library sources.

View File

@ -401,6 +401,7 @@ toolexeclibgounicode_DATA = \
# Force them to be built.
noinst_DATA = \
golang.org/x/net/nettest.gox \
internal/cfg.gox \
internal/testenv.gox \
internal/trace.gox \
net/internal/socktest.gox \

View File

@ -856,10 +856,10 @@ toolexeclibgounicode_DATA = \
# Some packages are only needed for tests, so unlike the other
# internal packages nothing will explicitly depend on them.
# Force them to be built.
noinst_DATA = golang.org/x/net/nettest.gox internal/testenv.gox \
internal/trace.gox net/internal/socktest.gox \
os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \
zdefaultcc.go
noinst_DATA = golang.org/x/net/nettest.gox internal/cfg.gox \
internal/testenv.gox internal/trace.gox \
net/internal/socktest.gox os/signal/internal/pty.gox \
runtime/pprof/internal/profile.gox zdefaultcc.go
@LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file =
@LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
runtime_files = \

View File

@ -1 +1 @@
go1.13beta1
go1.13

View File

@ -106,7 +106,6 @@ image/png
index/suffixarray
internal/cpu
internal/fmtsort
internal/oserror
internal/poll
internal/reflectlite
internal/singleflight

View File

@ -811,10 +811,10 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
params := name.FuncType.Params
args := call.Call.Args
// Avoid a crash if the number of arguments is
// less than the number of parameters.
// Avoid a crash if the number of arguments doesn't match
// the number of parameters.
// This will be caught when the generated file is compiled.
if len(args) < len(params) {
if len(args) != len(params) {
return "", false
}
@ -1257,6 +1257,8 @@ func (p *Package) isType(t ast.Expr) bool {
if strings.HasPrefix(t.Name, "_Ctype_") {
return true
}
case *ast.ParenExpr:
return p.isType(t.X)
case *ast.StarExpr:
return p.isType(t.X)
case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,

View File

@ -273,6 +273,35 @@ func (p *Package) writeDefs() {
}
}
// elfImportedSymbols is like elf.File.ImportedSymbols, but it
// includes weak symbols.
//
// A bug in some versions of LLD (at least LLD 8) cause it to emit
// several pthreads symbols as weak, but we need to import those. See
// issue #31912 or https://bugs.llvm.org/show_bug.cgi?id=42442.
//
// When doing external linking, we hand everything off to the external
// linker, which will create its own dynamic symbol tables. For
// internal linking, this may turn weak imports into strong imports,
// which could cause dynamic linking to fail if a symbol really isn't
// defined. However, the standard library depends on everything it
// imports, and this is the primary use of dynamic symbol tables with
// internal linking.
func elfImportedSymbols(f *elf.File) []elf.ImportedSymbol {
syms, _ := f.DynamicSymbols()
var imports []elf.ImportedSymbol
for _, s := range syms {
if (elf.ST_BIND(s.Info) == elf.STB_GLOBAL || elf.ST_BIND(s.Info) == elf.STB_WEAK) && s.Section == elf.SHN_UNDEF {
imports = append(imports, elf.ImportedSymbol{
Name: s.Name,
Library: s.Library,
Version: s.Version,
})
}
}
return imports
}
func dynimport(obj string) {
stdout := os.Stdout
if *dynout != "" {
@ -295,7 +324,7 @@ func dynimport(obj string) {
}
}
}
sym, _ := f.ImportedSymbols()
sym := elfImportedSymbols(f)
for _, s := range sym {
targ := s.Name
if s.Version != "" {

View File

@ -78,6 +78,8 @@
// If the arguments to build are a list of .go files from a single directory,
// build treats them as a list of source files specifying a single package.
//
// When compiling packages, build ignores files that end in '_test.go'.
//
// When compiling a single main package, build writes
// the resulting executable to an output file named after
// the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
@ -88,8 +90,6 @@
// build compiles the packages but discards the resulting object,
// serving only as a check that the packages can be built.
//
// When compiling packages, build ignores files that end in '_test.go'.
//
// The -o flag forces build to write the resulting executable or object
// to the named output file or directory, instead of the default behavior described
// in the last two paragraphs. If the named output is a directory that exists,
@ -566,17 +566,27 @@
// 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 chooses the latest tagged
// 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 chooses the latest tagged pre-release version, such as
// v0.0.1-pre1. If there are no tagged versions at all, get chooses the latest
// known commit.
// 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'.
// 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.
@ -586,12 +596,14 @@
// depending on it as needed.
//
// The version suffix @latest explicitly requests the latest minor release of the
// given path. The suffix @patch requests the latest patch release: if the path
// is already in the build list, the selected version will have the same minor
// version. If the path is not already in the build list, @patch is equivalent
// to @latest. Neither @latest nor @patch will cause 'go get' to downgrade a module
// in the build list if it is required at a newer pre-release version that is
// newer than the latest released version.
// 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 and @patch
// are equivalent to @latest.
//
// 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
@ -1006,6 +1018,7 @@
// Dir string // absolute path to cached source root directory
// Sum string // checksum for path, version (as in go.sum)
// GoModSum string // checksum for go.mod (as in go.sum)
// Latest bool // would @latest resolve to this version?
// }
//
// See 'go help modules' for more about module queries.
@ -1562,6 +1575,9 @@
// GOCACHE
// The directory where the go command will store cached
// information for reuse in future builds.
// GODEBUG
// Enable various debugging facilities. See 'go doc runtime'
// for details.
// GOENV
// The location of the Go environment configuration file.
// Cannot be set using 'go env -w'.
@ -2496,12 +2512,25 @@
// The string "latest" matches the latest available tagged version,
// or else the underlying source repository's latest untagged revision.
//
// 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.
// 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"
@ -2714,9 +2743,11 @@
// 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; use of any other
// database requires giving the public key explicitly. The URL defaults to
// "https://" followed by the database name.
// 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.

View File

@ -3177,6 +3177,12 @@ func TestGoTestFooTestWorks(t *testing.T) {
tg.run("test", "testdata/standalone_test.go")
}
func TestGoTestTestMainSeesTestingFlags(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.run("test", "testdata/standalone_testmain_flag_test.go")
}
// Issue 22388
func TestGoTestMainWithWrongSignature(t *testing.T) {
tg := testgo(t)

View File

@ -173,7 +173,7 @@ func (c *Cache) get(id ActionID) (Entry, error) {
i++
}
tm, err := strconv.ParseInt(string(etime[i:]), 10, 64)
if err != nil || size < 0 {
if err != nil || tm < 0 {
return missing()
}
@ -322,7 +322,7 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify
// in verify mode we are double-checking that the cache entries
// are entirely reproducible. As just noted, this may be unrealistic
// in some cases but the check is also useful for shaking out real bugs.
entry := []byte(fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano()))
entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano())
if verify && allowVerify {
old, err := c.get(id)
if err == nil && (old.OutputID != out || old.Size != size) {
@ -332,7 +332,28 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify
}
}
file := c.fileName(id, "a")
if err := ioutil.WriteFile(file, entry, 0666); err != nil {
// Copy file to cache directory.
mode := os.O_WRONLY | os.O_CREATE
f, err := os.OpenFile(file, mode, 0666)
if err != nil {
return err
}
_, err = f.WriteString(entry)
if err == nil {
// Truncate the file only *after* writing it.
// (This should be a no-op, but truncate just in case of previous corruption.)
//
// This differs from ioutil.WriteFile, which truncates to 0 *before* writing
// via os.O_TRUNC. Truncating only after writing ensures that a second write
// of the same content to the same file is idempotent, and does not — even
// temporarily! — undo the effect of the first write.
err = f.Truncate(int64(len(entry)))
}
if closeErr := f.Close(); err == nil {
err = closeErr
}
if err != nil {
// TODO(bcmills): This Remove potentially races with another go command writing to file.
// Can we eliminate it?
os.Remove(file)

View File

@ -10,6 +10,7 @@ import (
"bytes"
"fmt"
"go/build"
"internal/cfg"
"io/ioutil"
"os"
"path/filepath"
@ -221,61 +222,9 @@ func Getenv(key string) string {
// CanGetenv reports whether key is a valid go/env configuration key.
func CanGetenv(key string) bool {
return strings.Contains(knownEnv, "\t"+key+"\n")
return strings.Contains(cfg.KnownEnv, "\t"+key+"\n")
}
var knownEnv = `
AR
CC
CGO_CFLAGS
CGO_CFLAGS_ALLOW
CGO_CFLAGS_DISALLOW
CGO_CPPFLAGS
CGO_CPPFLAGS_ALLOW
CGO_CPPFLAGS_DISALLOW
CGO_CXXFLAGS
CGO_CXXFLAGS_ALLOW
CGO_CXXFLAGS_DISALLOW
CGO_ENABLED
CGO_FFLAGS
CGO_FFLAGS_ALLOW
CGO_FFLAGS_DISALLOW
CGO_LDFLAGS
CGO_LDFLAGS_ALLOW
CGO_LDFLAGS_DISALLOW
CXX
FC
GCCGO
GO111MODULE
GO386
GOARCH
GOARM
GOBIN
GOCACHE
GOENV
GOEXE
GOFLAGS
GOGCCFLAGS
GOHOSTARCH
GOHOSTOS
GOMIPS
GOMIPS64
GONOPROXY
GONOSUMDB
GOOS
GOPATH
GOPPC64
GOPRIVATE
GOPROXY
GOROOT
GOSUMDB
GOTMPDIR
GOTOOLDIR
GOWASM
GO_EXTLINK_ENABLED
PKG_CONFIG
`
var (
GOROOT = BuildContext.GOROOT
GOBIN = Getenv("GOBIN")

View File

@ -164,8 +164,14 @@ var vcsGit = &vcsCmd{
// See golang.org/issue/9032.
tagSyncDefault: []string{"submodule update --init --recursive"},
scheme: []string{"git", "https", "http", "git+ssh", "ssh"},
pingCmd: "ls-remote -- {scheme}://{repo}",
scheme: []string{"git", "https", "http", "git+ssh", "ssh"},
// Leave out the '--' separator in the ls-remote command: git 2.7.4 does not
// support such a separator for that command, and this use should be safe
// without it because the {scheme} value comes from the predefined list above.
// See golang.org/issue/33836.
pingCmd: "ls-remote {scheme}://{repo}",
remoteRepo: gitRemoteRepo,
}

View File

@ -63,7 +63,7 @@ Args:
// helpSuccess is the help command using as many args as possible that would succeed.
helpSuccess := "go help"
if i > 0 {
helpSuccess = " " + strings.Join(args[:i], " ")
helpSuccess += " " + strings.Join(args[:i], " ")
}
fmt.Fprintf(os.Stderr, "go help %s: unknown help topic. Run '%s'.\n", strings.Join(args, " "), helpSuccess)
base.SetExitStatus(2) // failed at 'go help cmd'

View File

@ -493,6 +493,9 @@ General-purpose environment variables:
GOCACHE
The directory where the go command will store cached
information for reuse in future builds.
GODEBUG
Enable various debugging facilities. See 'go doc runtime'
for details.
GOENV
The location of the Go environment configuration file.
Cannot be set using 'go env -w'.

View File

@ -390,7 +390,7 @@ func runList(cmd *base.Command, args []string) {
if !*listE {
for _, m := range mods {
if m.Error != nil {
base.Errorf("go list -m %s: %v", m.Path, m.Error.Err)
base.Errorf("go list -m: %v", m.Error.Err)
}
}
base.ExitIfErrors()
@ -459,7 +459,7 @@ func runList(cmd *base.Command, args []string) {
}
if pmain != nil {
pkgs = append(pkgs, pmain)
data := pmain.Internal.TestmainGo
data := *pmain.Internal.TestmainGo
h := cache.NewHash("testmain")
h.Write([]byte("testmain\n"))
h.Write(data)

View File

@ -64,7 +64,7 @@ type PackagePublic struct {
Doc string `json:",omitempty"` // package documentation string
Target string `json:",omitempty"` // installed target for this package (may be executable)
Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
Root string `json:",omitempty"` // Go root or Go path dir containing this package
Root string `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package
ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory
ForTest string `json:",omitempty"` // package is only for use in named test
Export string `json:",omitempty"` // file containing export data (set by go list -export)
@ -177,8 +177,7 @@ type PackageInternal struct {
OmitDebug bool // tell linker not to write debug information
GobinSubdir bool // install target would be subdir of GOBIN
BuildInfo string // add this info to package main
TestinginitGo []byte // content for _testinginit.go
TestmainGo []byte // content for _testmain.go
TestmainGo *[]byte // content for _testmain.go
Asmflags []string // -asmflags for this package
Gcflags []string // -gcflags for this package
@ -647,9 +646,14 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd
buildMode = build.ImportComment
}
data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
if data.p.Root == "" && cfg.ModulesEnabled {
if info := ModPackageModuleInfo(path); info != nil {
data.p.Root = info.Dir
}
}
} else if r.err != nil {
data.p = new(build.Package)
data.err = fmt.Errorf("unknown import path %q: %v", r.path, r.err)
data.err = r.err
} else if cfg.ModulesEnabled && path != "unsafe" {
data.p = new(build.Package)
data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)

View File

@ -102,7 +102,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
var stk ImportStack
stk.Push(p.ImportPath + " (test)")
rawTestImports := str.StringList(p.TestImports)
var ptestImportsTesting, pxtestImportsTesting bool
for i, path := range p.TestImports {
p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
@ -117,9 +116,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
}
p.TestImports[i] = p1.ImportPath
imports = append(imports, p1)
if path == "testing" {
ptestImportsTesting = true
}
}
stk.Pop()
stk.Push(p.ImportPath + "_test")
@ -133,9 +129,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
ximports = append(ximports, p1)
}
p.XTestImports[i] = p1.ImportPath
if path == "testing" {
pxtestImportsTesting = true
}
}
stk.Pop()
@ -145,9 +138,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
*ptest = *p
ptest.Error = ptestErr
ptest.ForTest = p.ImportPath
if ptestImportsTesting {
ptest.Internal.TestinginitGo = formatTestinginit(p)
}
ptest.GoFiles = nil
ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
@ -212,9 +202,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
Gccgoflags: p.Internal.Gccgoflags,
},
}
if pxtestImportsTesting {
pxtest.Internal.TestinginitGo = formatTestinginit(pxtest)
}
if pxtestNeedsPtest {
pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest)
}
@ -337,7 +324,9 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
if err != nil && pmain.Error == nil {
pmain.Error = &PackageError{Err: err.Error()}
}
pmain.Internal.TestmainGo = data
if data != nil {
pmain.Internal.TestmainGo = &data
}
return pmain, ptest, pxtest
}
@ -485,15 +474,6 @@ func loadTestFuncs(ptest *Package) (*testFuncs, error) {
return t, err
}
// formatTestinginit returns the content of the _testinginit.go file for p.
func formatTestinginit(p *Package) []byte {
var buf bytes.Buffer
if err := testinginitTmpl.Execute(&buf, p); err != nil {
panic("testinginit template execution failed") // shouldn't be possible
}
return buf.Bytes()
}
// formatTestmain returns the content of the _testmain.go file for t.
func formatTestmain(t *testFuncs) ([]byte, error) {
var buf bytes.Buffer
@ -623,23 +603,6 @@ func checkTestFunc(fn *ast.FuncDecl, arg string) error {
return nil
}
var testinginitTmpl = lazytemplate.New("init", `
package {{.Name}}
import _go_testing "testing"
{{/*
Call testing.Init before any other user initialization code runs.
(This file is passed to the compiler first.)
This provides the illusion of the old behavior where testing flags
were registered as part of the testing package's initialization.
*/}}
var _ = func() bool {
_go_testing.Init()
return true
}()
`)
var testmainTmpl = lazytemplate.New("main", `
// Code generated by 'go test'. DO NOT EDIT.

View File

@ -43,6 +43,7 @@ corresponding to this Go struct:
Dir string // absolute path to cached source root directory
Sum string // checksum for path, version (as in go.sum)
GoModSum string // checksum for go.mod (as in go.sum)
Latest bool // would @latest resolve to this version?
}
See 'go help modules' for more about module queries.
@ -65,6 +66,7 @@ type moduleJSON struct {
Dir string `json:",omitempty"`
Sum string `json:",omitempty"`
GoModSum string `json:",omitempty"`
Latest bool `json:",omitempty"`
}
func runDownload(cmd *base.Command, args []string) {
@ -87,7 +89,8 @@ func runDownload(cmd *base.Command, args []string) {
if info.Replace != nil {
info = info.Replace
}
if info.Version == "" {
if info.Version == "" && info.Error == nil {
// main module
continue
}
m := &moduleJSON{
@ -95,9 +98,38 @@ func runDownload(cmd *base.Command, args []string) {
Version: info.Version,
}
mods = append(mods, m)
if info.Error != nil {
m.Error = info.Error.Err
continue
}
work.Add(m)
}
latest := map[string]string{} // path → version
if *downloadJSON {
// We need to populate the Latest field, but if the main module depends on a
// version newer than latest — or if the version requested on the command
// line is itself newer than latest — that's not trivial to determine from
// the info returned by ListModules. Instead, we issue a separate
// ListModules request for "latest", which should be inexpensive relative to
// downloading the modules.
var latestArgs []string
for _, m := range mods {
if m.Error != "" {
continue
}
latestArgs = append(latestArgs, m.Path+"@latest")
}
if len(latestArgs) > 0 {
for _, info := range modload.ListModules(latestArgs, listU, listVersions) {
if info.Version != "" {
latest[info.Path] = info.Version
}
}
}
}
work.Do(10, func(item interface{}) {
m := item.(*moduleJSON)
var err error
@ -128,6 +160,9 @@ func runDownload(cmd *base.Command, args []string) {
m.Error = err.Error()
return
}
if latest[m.Path] == m.Version {
m.Latest = true
}
})
if *downloadJSON {
@ -144,7 +179,7 @@ func runDownload(cmd *base.Command, args []string) {
} else {
for _, m := range mods {
if m.Error != "" {
base.Errorf("%s@%s: %s\n", m.Path, m.Version, m.Error)
base.Errorf("%s", m.Error)
}
}
base.ExitIfErrors()

View File

@ -341,7 +341,9 @@ func (r *vcsRepo) Stat(rev string) (*RevInfo, error) {
}
func (r *vcsRepo) fetch() {
_, r.fetchErr = Run(r.dir, r.cmd.fetch)
if len(r.cmd.fetch) > 0 {
_, r.fetchErr = Run(r.dir, r.cmd.fetch)
}
}
func (r *vcsRepo) statLocal(rev string) (*RevInfo, error) {

View File

@ -31,7 +31,7 @@ type codeRepo struct {
codeRoot string
// codeDir is the directory (relative to root) at which we expect to find the module.
// If pathMajor is non-empty and codeRoot is not the full modPath,
// then we look in both codeDir and codeDir+modPath
// then we look in both codeDir and codeDir/pathMajor[1:].
codeDir string
// pathMajor is the suffix of modPath that indicates its major version,
@ -192,7 +192,13 @@ func (r *codeRepo) Stat(rev string) (*RevInfo, error) {
codeRev := r.revToRev(rev)
info, err := r.code.Stat(codeRev)
if err != nil {
return nil, err
return nil, &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: rev,
Err: err,
},
}
}
return r.convert(info, rev)
}
@ -248,20 +254,25 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
// exist as required by info2.Version and the module path represented by r.
checkGoMod := func() (*RevInfo, error) {
// If r.codeDir is non-empty, then the go.mod file must exist: the module
// author, not the module consumer, gets to decide how to carve up the repo
// author — not the module consumer, — gets to decide how to carve up the repo
// into modules.
if r.codeDir != "" {
_, _, _, err := r.findDir(info2.Version)
if err != nil {
// TODO: It would be nice to return an error like "not a module".
// Right now we return "missing go.mod", which is a little confusing.
return nil, &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: info2.Version,
Err: notExistError(err.Error()),
},
}
//
// Conversely, if the go.mod file exists, the module author — not the module
// consumer — gets to determine the module's path
//
// r.findDir verifies both of these conditions. Execute it now so that
// r.Stat will correctly return a notExistError if the go.mod location or
// declared module path doesn't match.
_, _, _, err := r.findDir(info2.Version)
if err != nil {
// TODO: It would be nice to return an error like "not a module".
// Right now we return "missing go.mod", which is a little confusing.
return nil, &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: info2.Version,
Err: notExistError(err.Error()),
},
}
}
@ -474,6 +485,11 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
return fmt.Errorf("does not match version-control timestamp (%s)", info.Time.UTC().Format(time.RFC3339))
}
tagPrefix := ""
if r.codeDir != "" {
tagPrefix = r.codeDir + "/"
}
// A pseudo-version should have a precedence just above its parent revisions,
// and no higher. Otherwise, it would be possible for library authors to "pin"
// dependency versions (and bypass the usual minimum version selection) by
@ -499,11 +515,26 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
return fmt.Errorf("major version without preceding tag must be v0, not v1")
}
return nil
}
tagPrefix := ""
if r.codeDir != "" {
tagPrefix = r.codeDir + "/"
} else {
for _, tag := range info.Tags {
versionOnly := strings.TrimPrefix(tag, tagPrefix)
if versionOnly == base {
// The base version is canonical, so if the version from the tag is
// literally equal (not just equivalent), then the tag is canonical too.
//
// We allow pseudo-versions to be derived from non-canonical tags on the
// same commit, so that tags like "v1.1.0+some-metadata" resolve as
// close as possible to the canonical version ("v1.1.0") while still
// enforcing a total ordering ("v1.1.1-0.[…]" with a unique suffix).
//
// However, canonical tags already have a total ordering, so there is no
// reason not to use the canonical tag directly, and we know that the
// canonical tag must already exist because the pseudo-version is
// derived from it. In that case, referring to the revision by a
// pseudo-version derived from its own canonical tag is just confusing.
return fmt.Errorf("tag (%s) found on revision %s is already canonical, so should not be replaced with a pseudo-version derived from that tag", tag, rev)
}
}
}
tags, err := r.code.Tags(tagPrefix + base)
@ -571,6 +602,10 @@ func (r *codeRepo) versionToRev(version string) (rev string, err error) {
return r.revToRev(version), nil
}
// findDir locates the directory within the repo containing the module.
//
// If r.pathMajor is non-empty, this can be either r.codeDir or — if a go.mod
// file exists — r.codeDir/r.pathMajor[1:].
func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err error) {
rev, err = r.versionToRev(version)
if err != nil {

View File

@ -83,6 +83,26 @@ var codeRepoTests = []codeRepoTest{
"pkg/p.go",
},
},
{
vcs: "git",
path: "github.com/rsc/vgotest1",
rev: "v0.0.0-20180219231006-80d85c5d4d17",
version: "v0.0.0-20180219231006-80d85c5d4d17",
name: "80d85c5d4d17598a0e9055e7c175a32b415d6128",
short: "80d85c5d4d17",
time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC),
zip: []string{
"LICENSE",
"README.md",
"pkg/p.go",
},
},
{
vcs: "git",
path: "github.com/rsc/vgotest1",
rev: "v0.0.1-0.20180219231006-80d85c5d4d17",
err: `github.com/rsc/vgotest1@v0.0.1-0.20180219231006-80d85c5d4d17: invalid pseudo-version: tag (v0.0.0) found on revision 80d85c5d4d17 is already canonical, so should not be replaced with a pseudo-version derived from that tag`,
},
{
vcs: "git",
path: "github.com/rsc/vgotest1",
@ -105,7 +125,7 @@ var codeRepoTests = []codeRepoTest{
name: "45f53230a74ad275c7127e117ac46914c8126160",
short: "45f53230a74a",
time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC),
ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
err: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
},
{
vcs: "git",
@ -136,15 +156,14 @@ var codeRepoTests = []codeRepoTest{
},
},
{
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
rev: "45f53230a",
version: "v2.0.0",
name: "45f53230a74ad275c7127e117ac46914c8126160",
short: "45f53230a74a",
time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC),
gomoderr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
rev: "45f53230a",
version: "v2.0.0",
name: "45f53230a74ad275c7127e117ac46914c8126160",
short: "45f53230a74a",
time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC),
err: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
},
{
vcs: "git",
@ -154,7 +173,7 @@ var codeRepoTests = []codeRepoTest{
name: "80d85c5d4d17598a0e9055e7c175a32b415d6128",
short: "80d85c5d4d17",
time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC),
ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17",
err: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17",
},
{
vcs: "git",
@ -210,24 +229,24 @@ var codeRepoTests = []codeRepoTest{
gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n",
},
{
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.3",
version: "v2.0.3",
name: "f18795870fb14388a21ef3ebc1d75911c8694f31",
short: "f18795870fb1",
time: time.Date(2018, 2, 19, 23, 16, 4, 0, time.UTC),
gomoderr: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3",
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.3",
version: "v2.0.3",
name: "f18795870fb14388a21ef3ebc1d75911c8694f31",
short: "f18795870fb1",
time: time.Date(2018, 2, 19, 23, 16, 4, 0, time.UTC),
err: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3",
},
{
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.4",
version: "v2.0.4",
name: "1f863feb76bc7029b78b21c5375644838962f88d",
short: "1f863feb76bc",
time: time.Date(2018, 2, 20, 0, 3, 38, 0, time.UTC),
gomoderr: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4",
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.4",
version: "v2.0.4",
name: "1f863feb76bc7029b78b21c5375644838962f88d",
short: "1f863feb76bc",
time: time.Date(2018, 2, 20, 0, 3, 38, 0, time.UTC),
err: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4",
},
{
vcs: "git",
@ -504,6 +523,7 @@ func TestCodeRepo(t *testing.T) {
tt.name = remap(tt.name, m)
tt.short = remap(tt.short, m)
tt.rev = remap(tt.rev, m)
tt.err = remap(tt.err, m)
tt.gomoderr = remap(tt.gomoderr, m)
tt.ziperr = remap(tt.ziperr, m)
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
@ -515,7 +535,7 @@ func TestCodeRepo(t *testing.T) {
}
var hgmap = map[string]string{
"github.com/rsc/vgotest1/": "vcs-test.golang.org/hg/vgotest1.hg/",
"github.com/rsc/vgotest1": "vcs-test.golang.org/hg/vgotest1.hg",
"f18795870fb14388a21ef3ebc1d75911c8694f31": "a9ad6d1d14eb544f459f446210c7eb3b009807c6",
"ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9": "f1fc0f22021b638d073d31c752847e7bf385def7",
"b769f2de407a4db81af9c5de0a06016d60d2ea09": "92c7eb888b4fac17f1c6bd2e1060a1b881a3b832",
@ -631,15 +651,30 @@ var latestTests = []struct {
err: "no commits",
},
{
vcs: "git",
path: "github.com/rsc/vgotest1",
version: "v0.0.0-20180219223237-a08abb797a67",
vcs: "git",
path: "github.com/rsc/vgotest1",
err: `github.com/rsc/vgotest1@v0.0.0-20180219223237-a08abb797a67: invalid version: go.mod has post-v0 module path "github.com/vgotest1/v2" at revision a08abb797a67`,
},
{
vcs: "git",
path: "github.com/rsc/vgotest1/v2",
err: `github.com/rsc/vgotest1/v2@v2.0.0-20180219223237-a08abb797a67: invalid version: github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision a08abb797a67`,
},
{
vcs: "git",
path: "github.com/rsc/vgotest1/subdir",
err: "github.com/rsc/vgotest1/subdir@v0.0.0-20180219223237-a08abb797a67: invalid version: missing github.com/rsc/vgotest1/subdir/go.mod at revision a08abb797a67",
},
{
vcs: "git",
path: "vcs-test.golang.org/git/commit-after-tag.git",
version: "v1.0.1-0.20190715211727-b325d8217783",
},
{
vcs: "git",
path: "vcs-test.golang.org/git/no-tags.git",
version: "v0.0.0-20190715212047-e706ba1d9f6d",
},
{
vcs: "mod",
path: "swtch.com/testmod",

View File

@ -701,9 +701,11 @@ to use and optionally its public key and URL, as in:
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; use of any other
database requires giving the public key explicitly. The URL defaults to
"https://" followed by the database name.
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.

View File

@ -345,7 +345,9 @@ func (p *proxyRepo) Stat(rev string) (*RevInfo, error) {
func (p *proxyRepo) Latest() (*RevInfo, error) {
data, err := p.getBytes("@latest")
if err != nil {
// TODO return err if not 404
if !errors.Is(err, os.ErrNotExist) {
return nil, p.versionError("", err)
}
return p.latest()
}
info := new(RevInfo)

View File

@ -240,7 +240,7 @@ func lookup(proxy, path string) (r Repo, err error) {
var (
errModVendor = errors.New("module lookup disabled by -mod=vendor")
errProxyOff = errors.New("module lookup disabled by GOPROXY=off")
errProxyOff = notExistError("module lookup disabled by GOPROXY=off")
errNoproxy error = notExistError("disabled by GOPRIVATE/GONOPROXY")
errUseProxy error = notExistError("path does not match GOPRIVATE/GONOPROXY")
)

View File

@ -60,7 +60,17 @@ func dbDial() (dbName string, db *sumweb.Conn, err error) {
// $GOSUMDB can be "key" or "key url",
// and the key can be a full verifier key
// or a host on our list of known keys.
key := strings.Fields(cfg.GOSUMDB)
// Special case: sum.golang.google.cn
// is an alias, reachable inside mainland China,
// for sum.golang.org. If there are more
// of these we should add a map like knownGOSUMDB.
gosumdb := cfg.GOSUMDB
if gosumdb == "sum.golang.google.cn" {
gosumdb = "sum.golang.org https://sum.golang.google.cn"
}
key := strings.Fields(gosumdb)
if len(key) >= 1 {
if k := knownGOSUMDB[key[0]]; k != "" {
key[0] = k
@ -232,10 +242,10 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error {
}
// ReadCache reads cached lookups or tiles from
// GOPATH/pkg/mod/download/cache/sumdb,
// GOPATH/pkg/mod/cache/download/sumdb,
// which will be deleted by "go clean -modcache".
func (*dbClient) ReadCache(file string) ([]byte, error) {
targ := filepath.Join(PkgMod, "download/cache/sumdb", file)
targ := filepath.Join(PkgMod, "cache/download/sumdb", file)
data, err := lockedfile.Read(targ)
// lockedfile.Write does not atomically create the file with contents.
// There is a moment between file creation and locking the file for writing,
@ -249,7 +259,7 @@ func (*dbClient) ReadCache(file string) ([]byte, error) {
// WriteCache updates cached lookups or tiles.
func (*dbClient) WriteCache(file string, data []byte) {
targ := filepath.Join(PkgMod, "download/cache/sumdb", file)
targ := filepath.Join(PkgMod, "cache/download/sumdb", file)
os.MkdirAll(filepath.Dir(targ), 0777)
lockedfile.Write(targ, bytes.NewReader(data), 0666)
}

View File

@ -39,17 +39,27 @@ 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 chooses the latest tagged
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 chooses the latest tagged pre-release version, such as
v0.0.1-pre1. If there are no tagged versions at all, get chooses the latest
known commit.
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'.
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.
@ -59,12 +69,14 @@ 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
given path. The suffix @patch requests the latest patch release: if the path
is already in the build list, the selected version will have the same minor
version. If the path is not already in the build list, @patch is equivalent
to @latest. Neither @latest nor @patch will cause 'go get' to downgrade a module
in the build list if it is required at a newer pre-release version that is
newer than the latest released version.
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 and @patch
are equivalent to @latest.
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
@ -178,7 +190,7 @@ func (v *upgradeFlag) Set(s string) error {
s = ""
}
if s == "true" {
s = "latest"
s = "upgrade"
}
*v = upgradeFlag(s)
return nil
@ -202,8 +214,9 @@ type getArg struct {
// if there is no "@"). path specifies the modules or packages to get.
path string
// vers is the part of the argument after "@" (or "" if there is no "@").
// vers specifies the module version to get.
// vers is the part of the argument after "@" or an implied
// "upgrade" or "patch" if there is no "@". vers specifies the
// module version to get.
vers string
}
@ -249,7 +262,7 @@ func runGet(cmd *base.Command, args []string) {
}
switch getU {
case "", "latest", "patch":
case "", "upgrade", "patch":
// ok
default:
base.Fatalf("go get: unknown upgrade flag -u=%s", getU)
@ -283,11 +296,11 @@ func runGet(cmd *base.Command, args []string) {
// Parse command-line arguments and report errors. The command-line
// arguments are of the form path@version or simply path, with implicit
// @latest. path@none is "downgrade away".
// @upgrade. path@none is "downgrade away".
var gets []getArg
var queries []*query
for _, arg := range search.CleanPatterns(args) {
// Argument is module query path@vers, or else path with implicit @latest.
// Argument is path or path@vers.
path := arg
vers := ""
if i := strings.Index(arg, "@"); i >= 0 {
@ -298,10 +311,14 @@ func runGet(cmd *base.Command, args []string) {
continue
}
// If the user runs 'go get -u=patch some/module', update some/module to a
// patch release, not a minor version.
if vers == "" && getU != "" {
vers = string(getU)
// If no version suffix is specified, assume @upgrade.
// If -u=patch was specified, assume @patch instead.
if vers == "" {
if getU != "" {
vers = string(getU)
} else {
vers = "upgrade"
}
}
gets = append(gets, getArg{raw: arg, path: path, vers: vers})
@ -358,7 +375,7 @@ func runGet(cmd *base.Command, args []string) {
// The argument is a package path.
if pkgs := modload.TargetPackages(path); len(pkgs) != 0 {
// The path is in the main module. Nothing to query.
if vers != "" && vers != "latest" && vers != "patch" {
if vers != "upgrade" && vers != "patch" {
base.Errorf("go get %s: can't request explicit version of path in main module", arg)
}
continue
@ -376,8 +393,8 @@ func runGet(cmd *base.Command, args []string) {
continue
}
// If we're querying "latest" or "patch", we need to know the current
// version of the module. For "latest", we want to avoid accidentally
// If we're querying "upgrade" or "patch", we need to know the current
// version of the module. For "upgrade", we want to avoid accidentally
// downgrading from a newer prerelease. For "patch", we need to query
// the correct minor version.
// Here, we check if "path" is the name of a module in the build list
@ -718,7 +735,7 @@ func runQueries(cache map[querySpec]*query, queries []*query, modOnly map[string
return byPath
}
// getQuery evaluates the given package path, version pair
// getQuery evaluates the given (package or module) path and version
// to determine the underlying module version being requested.
// If forceModulePath is set, getQuery must interpret path
// as a module path.
@ -736,34 +753,51 @@ func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (mo
base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set")
}
if vers == "" || vers == "patch" && prevM.Version == "" {
vers = "latest"
}
if forceModulePath || !strings.Contains(path, "...") {
// If the query must be a module path, try only that module path.
if forceModulePath {
if path == modload.Target.Path {
if vers != "latest" {
return module.Version{}, fmt.Errorf("can't get a specific version of the main module")
}
}
// If the path doesn't contain a wildcard, try interpreting it as a module path.
info, err := modload.Query(path, vers, prevM.Version, modload.Allowed)
if err == nil {
return module.Version{Path: path, Version: info.Version}, nil
}
// If the query fails, and the path must be a real module, report the query error.
if forceModulePath {
return module.Version{}, err
// If the query was "upgrade" or "patch" and the current version has been
// replaced, check to see whether the error was for that same version:
// if so, the version was probably replaced because it is invalid,
// and we should keep that replacement without complaining.
if vers == "upgrade" || vers == "patch" {
var vErr *module.InvalidVersionError
if errors.As(err, &vErr) && vErr.Version == prevM.Version && modload.Replacement(prevM).Path != "" {
return prevM, nil
}
}
}
// Otherwise, try a package path or pattern.
results, err := modload.QueryPattern(path, vers, modload.Allowed)
if err != nil {
return module.Version{}, err
}
// If the query may be either a package or a module, try it as a package path.
// If it turns out to only exist as a module, we can detect the resulting
// PackageNotInModuleError and avoid a second round-trip through (potentially)
// all of the configured proxies.
results, err := modload.QueryPattern(path, vers, modload.Allowed)
if err != nil {
// If the path doesn't contain a wildcard, check whether it was actually a
// module path instead. If so, return that.
if !strings.Contains(path, "...") {
var modErr *modload.PackageNotInModuleError
if errors.As(err, &modErr) && modErr.Mod.Path == path {
return modErr.Mod, nil
}
}
return module.Version{}, err
}
return results[0].Mod, nil
}
@ -893,13 +927,23 @@ func (u *upgrader) Upgrade(m module.Version) (module.Version, error) {
// which may return a pseudoversion for the latest commit.
// Query "latest" returns the newest tagged version or the newest
// prerelease version if there are no non-prereleases, or repo.Latest
// if there aren't any tagged versions. Since we're providing the previous
// version, Query will confirm the latest version is actually newer
// and will return the current version if not.
// if there aren't any tagged versions.
// If we're querying "upgrade" or "patch", Query will compare the current
// version against the chosen version and will return the current version
// if it is newer.
info, err := modload.Query(m.Path, string(getU), m.Version, modload.Allowed)
if err != nil {
// Report error but return m, to let version selection continue.
// (Reporting the error will fail the command at the next base.ExitIfErrors.)
// Special case: if the error is for m.Version itself and m.Version has a
// replacement, then keep it and don't report the error: the fact that the
// version is invalid is likely the reason it was replaced to begin with.
var vErr *module.InvalidVersionError
if errors.As(err, &vErr) && vErr.Version == m.Version && modload.Replacement(m).Path != "" {
return m, nil
}
// Special case: if the error is "no matching versions" then don't
// even report the error. Because Query does not consider pseudo-versions,
// it may happen that we have a pseudo-version but during -u=patch

View File

@ -79,7 +79,7 @@ func addUpdate(m *modinfo.ModulePublic) {
return
}
if info, err := Query(m.Path, "latest", m.Version, Allowed); err == nil && semver.Compare(info.Version, m.Version) > 0 {
if info, err := Query(m.Path, "upgrade", m.Version, Allowed); err == nil && semver.Compare(info.Version, m.Version) > 0 {
m.Update = &modinfo.ModulePublic{
Path: m.Path,
Version: info.Version,

View File

@ -231,12 +231,25 @@ evaluates to the available tagged version nearest to the comparison target
The string "latest" matches the latest available tagged version,
or else the underlying source repository's latest untagged revision.
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.
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"

View File

@ -22,6 +22,7 @@ import (
"cmd/go/internal/par"
"cmd/go/internal/search"
"cmd/go/internal/semver"
"cmd/go/internal/str"
)
type ImportMissingError struct {
@ -35,6 +36,9 @@ type ImportMissingError struct {
func (e *ImportMissingError) Error() string {
if e.Module.Path == "" {
if str.HasPathPrefix(e.ImportPath, "cmd") {
return fmt.Sprintf("package %s is not in GOROOT (%s)", e.ImportPath, filepath.Join(cfg.GOROOT, "src", e.ImportPath))
}
return "cannot find module providing package " + e.ImportPath
}
return "missing module for import: " + e.Module.Path + "@" + e.Module.Version + " provides " + e.ImportPath
@ -74,6 +78,9 @@ func Import(path string) (m module.Version, dir string, err error) {
dir := filepath.Join(cfg.GOROOT, "src", path)
return module.Version{}, dir, nil
}
if str.HasPathPrefix(path, "cmd") {
return module.Version{}, "", &ImportMissingError{ImportPath: path}
}
// -mod=vendor is special.
// Everything must be in the main module or the main module's vendor directory.

View File

@ -5,6 +5,7 @@
package modload
import (
"errors"
"fmt"
"os"
"strings"
@ -70,9 +71,7 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic {
mods = append(mods, &modinfo.ModulePublic{
Path: path,
Version: vers,
Error: &modinfo.ModuleError{
Err: err.Error(),
},
Error: modinfoError(path, vers, err),
})
continue
}
@ -116,19 +115,15 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic {
mods = append(mods, moduleInfo(module.Version{Path: arg, Version: info.Version}, false))
} else {
mods = append(mods, &modinfo.ModulePublic{
Path: arg,
Error: &modinfo.ModuleError{
Err: err.Error(),
},
Path: arg,
Error: modinfoError(arg, "", err),
})
}
continue
}
mods = append(mods, &modinfo.ModulePublic{
Path: arg,
Error: &modinfo.ModuleError{
Err: fmt.Sprintf("module %q is not a known dependency", arg),
},
Path: arg,
Error: modinfoError(arg, "", errors.New("not a known dependency")),
})
} else {
fmt.Fprintf(os.Stderr, "warning: pattern %q matched no module dependencies\n", arg)
@ -138,3 +133,21 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic {
return mods
}
// modinfoError wraps an error to create an error message in
// modinfo.ModuleError with minimal redundancy.
func modinfoError(path, vers string, err error) *modinfo.ModuleError {
var nerr *NoMatchingVersionError
var merr *module.ModuleError
if errors.As(err, &nerr) {
// NoMatchingVersionError contains the query, so we don't mention the
// query again in ModuleError.
err = &module.ModuleError{Path: path, Err: err}
} else if !errors.As(err, &merr) {
// If the error does not contain path and version, wrap it in a
// module.ModuleError.
err = &module.ModuleError{Path: path, Version: vers, Err: err}
}
return &modinfo.ModuleError{Err: err.Error()}
}

View File

@ -100,11 +100,31 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match {
dir = filepath.Clean(dir)
}
// golang.org/issue/32917: We should resolve a relative path to a
// package path only if the relative path actually contains the code
// for that package.
if !dirContainsPackage(dir) {
// If we're outside of a module, ensure that the failure mode
// indicates that.
ModRoot()
// If the directory is local but does not exist, don't return it
// while loader is iterating, since this might trigger a fetch.
// After loader is done iterating, we still need to return the
// path, so that "go list -e" produces valid output.
if !iterating {
// We don't have a valid path to resolve to, so report the
// unresolved path.
m.Pkgs = append(m.Pkgs, pkg)
}
continue
}
// Note: The checks for @ here are just to avoid misinterpreting
// the module cache directories (formerly GOPATH/src/mod/foo@v1.5.2/bar).
// It's not strictly necessary but helpful to keep the checks.
if modRoot != "" && dir == modRoot {
pkg = Target.Path
pkg = targetPrefix
} else if modRoot != "" && strings.HasPrefix(dir, modRoot+string(filepath.Separator)) && !strings.Contains(dir[len(modRoot):], "@") {
suffix := filepath.ToSlash(dir[len(modRoot):])
if strings.HasPrefix(suffix, "/vendor/") {
@ -121,7 +141,13 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match {
continue
}
} else {
pkg = Target.Path + suffix
modPkg := targetPrefix + suffix
if _, ok := dirInModule(modPkg, targetPrefix, modRoot, true); ok {
pkg = modPkg
} else if !iterating {
ModRoot()
base.Errorf("go: directory %s is outside main module", base.ShortPath(dir))
}
}
} else if sub := search.InDir(dir, cfg.GOROOTsrc); sub != "" && sub != "." && !strings.Contains(sub, "@") {
pkg = filepath.ToSlash(sub)
@ -134,16 +160,6 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match {
base.Errorf("go: directory %s outside available modules", base.ShortPath(dir))
}
}
info, err := os.Stat(dir)
if err != nil || !info.IsDir() {
// If the directory is local but does not exist, don't return it
// while loader is iterating, since this would trigger a fetch.
// After loader is done iterating, we still need to return the
// path, so that "go list -e" produces valid output.
if iterating {
continue
}
}
m.Pkgs = append(m.Pkgs, pkg)
}
@ -247,14 +263,30 @@ func pathInModuleCache(dir string) string {
return ""
}
// warnPattern returns list, the result of matching pattern,
// but if list is empty then first it prints a warning about
// the pattern not matching any packages.
func warnPattern(pattern string, list []string) []string {
if len(list) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
var dirContainsPackageCache sync.Map // absolute dir → bool
func dirContainsPackage(dir string) bool {
isPkg, ok := dirContainsPackageCache.Load(dir)
if !ok {
_, err := cfg.BuildContext.ImportDir(dir, 0)
if err == nil {
isPkg = true
} else {
if fi, statErr := os.Stat(dir); statErr != nil || !fi.IsDir() {
// A non-directory or inaccessible directory is not a Go package.
isPkg = false
} else if _, noGo := err.(*build.NoGoError); noGo {
// A directory containing no Go source files is not a Go package.
isPkg = false
} else {
// An error other than *build.NoGoError indicates that the package exists
// but has some other problem (such as a syntax error).
isPkg = true
}
}
isPkg, _ = dirContainsPackageCache.LoadOrStore(dir, isPkg)
}
return list
return isPkg.(bool)
}
// ImportFromFiles adds modules to the build list as needed
@ -355,11 +387,13 @@ func loadAll(testAll bool) []string {
var paths []string
for _, pkg := range loaded.pkgs {
if e, ok := pkg.err.(*ImportMissingError); ok && e.Module.Path == "" {
continue // Package doesn't actually exist.
if pkg.err != nil {
base.Errorf("%s: %v", pkg.stackText(), pkg.err)
continue
}
paths = append(paths, pkg.path)
}
base.ExitIfErrors()
return paths
}
@ -1108,7 +1142,9 @@ func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) {
return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line"))
}
if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path {
return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: unexpected module path %q", mpath))
return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod:
module declares its path as: %s
but was required as: %s`, mpath, mod.Path))
}
if f.Go != nil {
r.versions.LoadOrStore(mod, f.Go.Version)

View File

@ -28,9 +28,10 @@ import (
// tagged version, with non-prereleases preferred over prereleases.
// If there are no tagged versions in the repo, latest returns the most
// recent commit.
// - the literal string "upgrade", equivalent to "latest" except that if
// current is a newer version, current will be returned (see below).
// - the literal string "patch", denoting the latest available tagged version
// with the same major and minor number as current. If current is "",
// "patch" is equivalent to "latest".
// with the same major and minor number as current (see below).
// - v1, denoting the latest available tagged version v1.x.x.
// - v1.2, denoting the latest available tagged version v1.2.x.
// - v1.2.3, a semantic version string denoting that tagged version.
@ -39,11 +40,12 @@ import (
// with non-prereleases preferred over prereleases.
// - a repository commit identifier or tag, denoting that commit.
//
// current is optional, denoting the current version of the module.
// If query is "latest" or "patch", current will be returned if it is a newer
// semantic version or if it is a chronologically later pseudoversion. This
// prevents accidental downgrades from newer prerelease or development
// versions.
// current denotes the current version of the module; it may be "" if the
// current version is unknown or should not be considered. If query is
// "upgrade" or "patch", current will be returned if it is a newer
// semantic version or a chronologically later pseudo-version than the
// version that would otherwise be chosen. This prevents accidental downgrades
// from newer pre-release or development versions.
//
// If the allowed function is non-nil, Query excludes any versions for which
// allowed returns false.
@ -81,6 +83,10 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version)
ok = allowed
mayUseLatest = true
case query == "upgrade":
ok = allowed
mayUseLatest = true
case query == "patch":
if current == "" {
ok = allowed
@ -202,9 +208,9 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version)
return nil, err
}
// For "latest" and "patch", make sure we don't accidentally downgrade
// For "upgrade" and "patch", make sure we don't accidentally downgrade
// from a newer prerelease or from a chronologically newer pseudoversion.
if current != "" && (query == "latest" || query == "patch") {
if current != "" && (query == "upgrade" || query == "patch") {
currentTime, err := modfetch.PseudoVersionTime(current)
if semver.Compare(rev.Version, current) < 0 || (err == nil && rev.Time.Before(currentTime)) {
return repo.Stat(current)
@ -374,10 +380,10 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q
}
r.Packages = match(r.Mod, root, isLocal)
if len(r.Packages) == 0 {
return r, &packageNotInModuleError{
mod: r.Mod,
query: query,
pattern: pattern,
return r, &PackageNotInModuleError{
Mod: r.Mod,
Query: query,
Pattern: pattern,
}
}
return r, nil
@ -440,30 +446,31 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string)
wg.Wait()
// Classify the results. In case of failure, identify the error that the user
// is most likely to find helpful.
// is most likely to find helpful: the most useful class of error at the
// longest matching path.
var (
noPackage *PackageNotInModuleError
noVersion *NoMatchingVersionError
noPackage *packageNotInModuleError
notExistErr error
)
for _, r := range results {
switch rErr := r.err.(type) {
case nil:
found = append(found, r.QueryResult)
case *PackageNotInModuleError:
if noPackage == nil {
noPackage = rErr
}
case *NoMatchingVersionError:
if noVersion == nil {
noVersion = rErr
}
case *packageNotInModuleError:
if noPackage == nil {
noPackage = rErr
}
default:
if errors.Is(rErr, os.ErrNotExist) {
if notExistErr == nil {
notExistErr = rErr
}
} else {
} else if err == nil {
err = r.err
}
}
@ -503,37 +510,37 @@ type NoMatchingVersionError struct {
func (e *NoMatchingVersionError) Error() string {
currentSuffix := ""
if (e.query == "latest" || e.query == "patch") && e.current != "" {
if (e.query == "upgrade" || e.query == "patch") && e.current != "" {
currentSuffix = fmt.Sprintf(" (current version is %s)", e.current)
}
return fmt.Sprintf("no matching versions for query %q", e.query) + currentSuffix
}
// A packageNotInModuleError indicates that QueryPattern found a candidate
// A PackageNotInModuleError indicates that QueryPattern found a candidate
// module at the requested version, but that module did not contain any packages
// matching the requested pattern.
//
// NOTE: packageNotInModuleError MUST NOT implement Is(os.ErrNotExist).
// NOTE: PackageNotInModuleError MUST NOT implement Is(os.ErrNotExist).
//
// If the module came from a proxy, that proxy had to return a successful status
// code for the versions it knows about, and thus did not have the opportunity
// to return a non-400 status code to suppress fallback.
type packageNotInModuleError struct {
mod module.Version
query string
pattern string
type PackageNotInModuleError struct {
Mod module.Version
Query string
Pattern string
}
func (e *packageNotInModuleError) Error() string {
func (e *PackageNotInModuleError) Error() string {
found := ""
if e.query != e.mod.Version {
found = fmt.Sprintf(" (%s)", e.mod.Version)
if e.Query != e.Mod.Version {
found = fmt.Sprintf(" (%s)", e.Mod.Version)
}
if strings.Contains(e.pattern, "...") {
return fmt.Sprintf("module %s@%s%s found, but does not contain packages matching %s", e.mod.Path, e.query, found, e.pattern)
if strings.Contains(e.Pattern, "...") {
return fmt.Sprintf("module %s@%s%s found, but does not contain packages matching %s", e.Mod.Path, e.Query, found, e.Pattern)
}
return fmt.Sprintf("module %s@%s%s found, but does not contain package %s", e.mod.Path, e.query, found, e.pattern)
return fmt.Sprintf("module %s@%s%s found, but does not contain package %s", e.Mod.Path, e.Query, found, e.Pattern)
}
// ModuleHasRootPackage returns whether module m contains a package m.Path.

View File

@ -100,7 +100,7 @@ var queryTests = []struct {
{path: queryRepo, query: ">=v0.0.0", vers: "v0.0.0"},
{path: queryRepo, query: "v0.0.1", vers: "v0.0.1"},
{path: queryRepo, query: "v0.0.1+foo", vers: "v0.0.1"},
{path: queryRepo, query: "v0.0.99", err: `unknown revision v0.0.99`},
{path: queryRepo, query: "v0.0.99", err: `vcs-test.golang.org/git/querytest.git@v0.0.99: invalid version: unknown revision v0.0.99`},
{path: queryRepo, query: "v0", vers: "v0.3.0"},
{path: queryRepo, query: "v0.1", vers: "v0.1.2"},
{path: queryRepo, query: "v0.2", err: `no matching versions for query "v0.2"`},
@ -112,15 +112,17 @@ var queryTests = []struct {
// unconditionally).
{path: queryRepo, query: "42abcb6df8ee", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
{path: queryRepo, query: "v1.9.10-pre2+wrongmetadata", err: `unknown revision v1.9.10-pre2+wrongmetadata`},
{path: queryRepo, query: "v1.9.10-pre2", err: `unknown revision v1.9.10-pre2`},
{path: queryRepo, query: "v1.9.10-pre2+wrongmetadata", err: `vcs-test.golang.org/git/querytest.git@v1.9.10-pre2+wrongmetadata: invalid version: unknown revision v1.9.10-pre2+wrongmetadata`},
{path: queryRepo, query: "v1.9.10-pre2", err: `vcs-test.golang.org/git/querytest.git@v1.9.10-pre2: invalid version: unknown revision v1.9.10-pre2`},
{path: queryRepo, query: "latest", vers: "v1.9.9"},
{path: queryRepo, query: "latest", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"},
{path: queryRepo, query: "latest", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
{path: queryRepo, query: "latest", current: "v0.0.0-20190513201126-42abcb6df8ee", vers: "v0.0.0-20190513201126-42abcb6df8ee"},
{path: queryRepo, query: "latest", allow: "NOMATCH", err: `no matching versions for query "latest"`},
{path: queryRepo, query: "latest", current: "v1.9.9", allow: "NOMATCH", err: `no matching versions for query "latest" (current version is v1.9.9)`},
{path: queryRepo, query: "latest", current: "v1.99.99", err: `unknown revision v1.99.99`},
{path: queryRepo, query: "latest", current: "v1.9.10-pre1", vers: "v1.9.9"},
{path: queryRepo, query: "upgrade", vers: "v1.9.9"},
{path: queryRepo, query: "upgrade", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"},
{path: queryRepo, query: "upgrade", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
{path: queryRepo, query: "upgrade", current: "v0.0.0-20190513201126-42abcb6df8ee", vers: "v0.0.0-20190513201126-42abcb6df8ee"},
{path: queryRepo, query: "upgrade", allow: "NOMATCH", err: `no matching versions for query "upgrade"`},
{path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `no matching versions for query "upgrade" (current version is v1.9.9)`},
{path: queryRepo, query: "upgrade", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`},
{path: queryRepo, query: "patch", current: "", vers: "v1.9.9"},
{path: queryRepo, query: "patch", current: "v0.1.0", vers: "v0.1.2"},
{path: queryRepo, query: "patch", current: "v1.9.0", vers: "v1.9.9"},
@ -159,8 +161,11 @@ var queryTests = []struct {
{path: queryRepoV2, query: "v2.6.0-pre1", vers: "v2.6.0-pre1"},
{path: queryRepoV2, query: "latest", vers: "v2.5.5"},
{path: queryRepoV3, query: "e0cf3de987e6", vers: "v3.0.0-20180704024501-e0cf3de987e6"},
{path: queryRepoV3, query: "latest", vers: "v3.0.0-20180704024501-e0cf3de987e6"},
// e0cf3de987e6 is the latest commit on the master branch, and it's actually
// v1.19.10-pre1, not anything resembling v3: attempting to query it as such
// should fail.
{path: queryRepoV3, query: "e0cf3de987e6", err: `vcs-test.golang.org/git/querytest.git/v3@v3.0.0-20180704024501-e0cf3de987e6: invalid version: go.mod has non-.../v3 module path "vcs-test.golang.org/git/querytest.git" (and .../v3/go.mod does not exist) at revision e0cf3de987e6`},
{path: queryRepoV3, query: "latest", err: `no matching versions for query "latest"`},
{path: emptyRepo, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"},
{path: emptyRepo, query: ">v0.0.0", err: `no matching versions for query ">v0.0.0"`},
@ -180,7 +185,10 @@ func TestQuery(t *testing.T) {
ok, _ := path.Match(allow, m.Version)
return ok
}
tt := tt
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.query+"/"+tt.current+"/"+allow, func(t *testing.T) {
t.Parallel()
info, err := Query(tt.path, tt.query, tt.current, allowed)
if tt.err != "" {
if err == nil {

View File

@ -216,8 +216,8 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m
}
}
// Construct the list by traversing the graph again, replacing older
// modules with required minimum versions.
// The final list is the minimum version of each module found in the graph.
if v := min[target.Path]; v != target.Version {
// TODO(jayconrod): there is a special case in modload.mvsReqs.Max
// that prevents us from selecting a newer version of a module
@ -228,19 +228,18 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m
}
list := []module.Version{target}
listed := map[string]bool{target.Path: true}
for i := 0; i < len(list); i++ {
n := modGraph[list[i]]
for path, vers := range min {
if path != target.Path {
list = append(list, module.Version{Path: path, Version: vers})
}
n := modGraph[module.Version{Path: path, Version: vers}]
required := n.required
for _, r := range required {
v := min[r.Path]
if r.Path != target.Path && reqs.Max(v, r.Version) != v {
panic(fmt.Sprintf("mistake: version %q does not satisfy requirement %+v", v, r)) // TODO: Don't panic.
}
if !listed[r.Path] {
list = append(list, module.Version{Path: r.Path, Version: v})
listed[r.Path] = true
}
}
}
@ -289,12 +288,12 @@ func Req(target module.Version, list []module.Version, base []string, reqs Reqs)
}
// Walk modules in reverse post-order, only adding those not implied already.
have := map[string]string{}
have := map[module.Version]bool{}
walk = func(m module.Version) error {
if v, ok := have[m.Path]; ok && reqs.Max(m.Version, v) == v {
if have[m] {
return nil
}
have[m.Path] = m.Version
have[m] = true
for _, m1 := range reqCache[m] {
walk(m1)
}
@ -322,7 +321,7 @@ func Req(target module.Version, list []module.Version, base []string, reqs Reqs)
// Older version.
continue
}
if have[m.Path] != m.Version {
if !have[m] {
min = append(min, m)
walk(m)
}

View File

@ -29,7 +29,7 @@ D5: E2
G1: C4
A2: B1 C4 D4
build A: A B1 C2 D4 E2 F1
upgrade* A: A B1 C4 D5 E2 G1
upgrade* A: A B1 C4 D5 E2 F1 G1
upgrade A C4: A B1 C4 D4 E2 F1 G1
downgrade A2 D2: A2 C4 D2
@ -38,7 +38,7 @@ A: B1 C2
B1: D3
C2: B2
B2:
build A: A B2 C2
build A: A B2 C2 D3
# Cross-dependency between D and E.
# No matter how it arises, should get result of merging all build lists via max,
@ -157,7 +157,18 @@ D1: E2
E1: D2
build A: A B C D2 E2
# Upgrade from B1 to B2 should drop the transitive dep on D.
# golang.org/issue/31248:
# Even though we select X2, the requirement on I1
# via X1 should be preserved.
name: cross8
M: A1 B1
A1: X1
B1: X2
X1: I1
X2:
build M: M A1 B1 I1 X2
# Upgrade from B1 to B2 should not drop the transitive dep on D.
name: drop
A: B1 C1
B1: D1
@ -165,14 +176,14 @@ B2:
C2:
D2:
build A: A B1 C1 D1
upgrade* A: A B2 C2
upgrade* A: A B2 C2 D2
name: simplify
A: B1 C1
B1: C2
C1: D1
C2:
build A: A B1 C2
build A: A B1 C2 D1
name: up1
A: B1 C1
@ -254,8 +265,9 @@ build A: A B1
upgrade A B2: A B2
upgrade* A: A B3
# golang.org/issue/29773:
# Requirements of older versions of the target
# must not be carried over.
# must be carried over.
name: cycle2
A: B1
A1: C1
@ -265,8 +277,8 @@ B2: A2
C1: A2
C2:
D2:
build A: A B1
upgrade* A: A B2
build A: A B1 C1 D1
upgrade* A: A B2 C2 D2
# Requirement minimization.
@ -283,6 +295,14 @@ H1: G1
req A: G1
req A G: G1
req A H: H1
name: req3
M: A1 B1
A1: X1
B1: X2
X1: I1
X2:
req M: A1 B1
`
func Test(t *testing.T) {

View File

@ -843,7 +843,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
if !cfg.BuildN {
// writeTestmain writes _testmain.go,
// using the test description gathered in t.
if err := ioutil.WriteFile(testDir+"_testmain.go", pmain.Internal.TestmainGo, 0666); err != nil {
if err := ioutil.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
return nil, nil, nil, err
}
}
@ -1250,6 +1250,15 @@ func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bo
return false
}
if a.Package.Root == "" {
// Caching does not apply to tests outside of any module, GOPATH, or GOROOT.
if cache.DebugTest {
fmt.Fprintf(os.Stderr, "testcache: caching disabled for package outside of module root, GOPATH, or GOROOT: %s\n", a.Package.ImportPath)
}
c.disableCache = true
return false
}
var cacheArgs []string
for _, arg := range testArgs {
i := strings.Index(arg, "=")
@ -1437,8 +1446,8 @@ func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error)
if !filepath.IsAbs(name) {
name = filepath.Join(pwd, name)
}
if !inDir(name, a.Package.Root) {
// Do not recheck files outside the GOPATH or GOROOT root.
if a.Package.Root == "" || !inDir(name, a.Package.Root) {
// Do not recheck files outside the module, GOPATH, or GOROOT root.
break
}
fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name))
@ -1446,8 +1455,8 @@ func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error)
if !filepath.IsAbs(name) {
name = filepath.Join(pwd, name)
}
if !inDir(name, a.Package.Root) {
// Do not recheck files outside the GOPATH or GOROOT root.
if a.Package.Root == "" || !inDir(name, a.Package.Root) {
// Do not recheck files outside the module, GOPATH, or GOROOT root.
break
}
fh, err := hashOpen(name)

View File

@ -103,6 +103,11 @@ func (x *elfExe) ReadData(addr, size uint64) ([]byte, error) {
}
func (x *elfExe) DataStart() uint64 {
for _, s := range x.f.Sections {
if s.Name == ".go.buildinfo" {
return s.Addr
}
}
for _, p := range x.f.Progs {
if p.Type == elf.PT_LOAD && p.Flags&(elf.PF_X|elf.PF_W) == elf.PF_W {
return p.Vaddr
@ -208,7 +213,13 @@ func (x *machoExe) ReadData(addr, size uint64) ([]byte, error) {
}
func (x *machoExe) DataStart() uint64 {
// Assume data is first non-empty writable segment.
// Look for section named "__go_buildinfo".
for _, sec := range x.f.Sections {
if sec.Name == "__go_buildinfo" {
return sec.Addr
}
}
// Try the first non-empty writable segment.
const RW = 3
for _, load := range x.f.Loads {
seg, ok := load.(*macho.Segment)

View File

@ -30,6 +30,8 @@ along with their dependencies, but it does not install the results.
If the arguments to build are a list of .go files from a single directory,
build treats them as a list of source files specifying a single package.
When compiling packages, build ignores files that end in '_test.go'.
When compiling a single main package, build writes
the resulting executable to an output file named after
the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
@ -40,8 +42,6 @@ When compiling multiple packages or a single non-main package,
build compiles the packages but discards the resulting object,
serving only as a check that the packages can be built.
When compiling packages, build ignores files that end in '_test.go'.
The -o flag forces build to write the resulting executable or object
to the named output file or directory, instead of the default behavior described
in the last two paragraphs. If the named output is a directory that exists,

View File

@ -203,8 +203,9 @@ func (b *Builder) toolID(name string) string {
// On the development branch, use the content ID part of the build ID.
id = contentID(f[len(f)-1])
} else {
// For a release, the output is like: "compile version go1.9.1". Use the whole line.
id = f[2]
// For a release, the output is like: "compile version go1.9.1 X:framepointer".
// Use the whole line.
id = strings.TrimSpace(line)
}
b.id.Lock()

View File

@ -542,15 +542,6 @@ func (b *Builder) build(a *Action) (err error) {
}
}
// Write out the _testinginit.go file for any test packages that import "testing".
if a.Package.Internal.TestinginitGo != nil {
initfile := objdir + "_testinginit.go"
if err := b.writeFile(initfile, a.Package.Internal.TestinginitGo); err != nil {
return err
}
gofiles = append([]string{initfile}, gofiles...)
}
// Run cgo.
if a.Package.UsesCgo() || a.Package.UsesSwig() {
// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.

View File

@ -1,19 +1,16 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package flag_test
import (
"flag"
"log"
"testing"
)
var v = flag.Int("v", 0, "v flag")
// Run this as go test pkg -args -v=7
// Run this as go test pkg -v=7
func TestVFlagIsSet(t *testing.T) {
if *v != 7 {
t.Fatal("v flag not set")
log.Fatal("v flag not set")
}
}

View File

@ -1,7 +1,7 @@
example.com/badchain/c v1.1.0
-- .mod --
module example.com/badchain/wrong
module badchain.example.com/c
-- .info --
{"Version":"v1.1.0"}
-- c.go --

View File

@ -1,4 +1,5 @@
env GO111MODULE=off
env GODEBUG=gocachetest=1
[!gc] skip
[short] skip # clears cache, rebuilds too much
@ -32,7 +33,7 @@ stderr 'main.go:2.* can inline main' # from compiler
stderr '\d+ symbols' # from linker
# Running a test should run the compiler, linker, and the test the first time.
go test -v -x -gcflags=-m -ldflags=-v p_test.go
go test -v -x -gcflags=-m -ldflags=-v p
stderr 'compile( |\.exe"?)'
stderr 'p_test.go:.*can inline Test' # from compile of p_test
stderr 'testmain\.go:.*inlin' # from compile of testmain
@ -42,7 +43,7 @@ stderr 'p\.test( |\.exe"?)'
stdout 'TEST' # from test
# ... but not the second, even though it still prints the compiler, linker, and test output.
go test -v -x -gcflags=-m -ldflags=-v p_test.go
go test -v -x -gcflags=-m -ldflags=-v p
! stderr 'compile( |\.exe"?)'
stderr 'p_test.go:.*can inline Test' # from compile of p_test
stderr 'testmain\.go:.*inlin' # from compile of testmain
@ -60,7 +61,7 @@ func f(x *int) *int { return x }
package main
func main() {}
-- p_test.go --
-- p/p_test.go --
package p
import "testing"
func Test(t *testing.T) {println("TEST")}

View File

@ -0,0 +1,16 @@
env GO111MODULE=on
# Regression test for golang.org/issue/31031:
# Importing or loading a non-existent package in cmd/ should print
# a clear error in module mode.
! go list cmd/unknown
stderr '^can''t load package: package cmd/unknown: package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$'
go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go
stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$'
-- x.go --
package x
import _ "cmd/unknown"

View File

@ -3,6 +3,7 @@
env GO111MODULE=on
[short] skip
# Check when module x is inside GOPATH/src.
go doc y
stdout 'Package y is.*alphabet'
stdout 'import "x/y"'
@ -16,13 +17,25 @@ stdout 'Hello returns a greeting'
go doc quote
stdout 'Package quote collects pithy sayings.'
# Double-check go doc y when y is not in GOPATH/src.
env GOPATH=$WORK/altgopath
# Double-check when module x is outside GOPATH/src.
env GOPATH=$WORK/emptygopath
go doc x/y
stdout 'Package y is.*alphabet'
go doc y
stdout 'Package y is.*alphabet'
# Triple-check when module x is outside GOPATH/src,
# but other packages with same import paths are in GOPATH/src.
# Since go doc is running in module mode here, packages in active module
# should be preferred over packages in GOPATH. See golang.org/issue/28992.
env GOPATH=$WORK/gopath2
go doc x/y
! stdout 'Package y is.*GOPATH'
stdout 'Package y is.*alphabet'
go doc rsc.io/quote
! stdout 'Package quote is located in a GOPATH workspace.'
stdout 'Package quote collects pithy sayings.'
-- go.mod --
module x
require rsc.io/quote v1.5.2
@ -33,3 +46,13 @@ package y
-- x.go --
package x
-- $WORK/gopath2/src/x/y/y.go --
// Package y is located in a GOPATH workspace.
package y
-- $WORK/gopath2/src/rsc.io/quote/quote.go --
// Package quote is located in a GOPATH workspace.
package quote
// Hello is located in a GOPATH workspace.
func Hello() string { return "" }

View File

@ -0,0 +1,36 @@
env GO111MODULE=on
# golang.org/issue/32917 and golang.org/issue/28459: 'go build' and 'go test'
# in an empty directory should refer to the path '.' and should not attempt
# to resolve an external module.
cd dir
! go get .
stderr 'go get \.: path .* is not a package in module rooted at .*[/\\]dir$'
! go list
! stderr 'cannot find module providing package'
stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$'
cd subdir
! go list
! stderr 'cannot find module providing package'
stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$'
cd ..
# golang.org/issue/30590: if a package is found in the filesystem
# but is not in the main module, the error message should not say
# "cannot find module providing package", and we shouldn't try
# to find a module providing the package.
! go list ./othermodule
! stderr 'cannot find module providing package'
stderr 'go: directory othermodule is outside main module'
-- dir/go.mod --
module example.com
go 1.13
-- dir/subdir/README --
There are no Go source files in this directory.
-- dir/othermodule/go.mod --
module example.com/othermodule
go 1.13
-- dir/othermodule/om.go --
package othermodule

View File

@ -17,6 +17,7 @@ stderr 'this.domain.is.invalid'
stdout '"Error": ".*this.domain.is.invalid.*"'
# download -json with version should print JSON
# and download the .info file for the 'latest' version.
go mod download -json 'rsc.io/quote@<=v1.5.0'
stdout '^\t"Path": "rsc.io/quote"'
stdout '^\t"Version": "v1.5.0"'
@ -27,13 +28,14 @@ stdout '^\t"Sum": "h1:6fJa6E\+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE="' # hash of
stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="'
! stdout '"Error"'
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
# download queries above should not have added to go.mod.
go list -m all
! stdout rsc.io
# add to go.mod so we can test non-query downloads
go mod edit -require rsc.io/quote@v1.5.2
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
@ -83,6 +85,16 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip
go mod download -json rsc.io/quote@v1.5.1
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip
# download reports errors encountered when locating modules
! go mod download bad/path
stderr '^module bad/path: not a known dependency$'
! go mod download bad/path@latest
stderr '^bad/path@latest: malformed module path "bad/path": missing dot in first path element$'
! go mod download rsc.io/quote@v1.999.999
stderr '^rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$'
! go mod download -json bad/path
stdout '^\t"Error": "module bad/path: not a known dependency"'
# allow go mod download without go.mod
env GO111MODULE=auto
rm go.mod

View File

@ -0,0 +1,20 @@
env GO111MODULE=on
# If the module is the latest version of itself,
# the Latest field should be set.
go mod download -json rsc.io/quote@v1.5.2
stdout '"Latest":\s*true'
# If the module is older than latest, the field should be unset.
go mod download -json rsc.io/quote@v1.5.1
! stdout '"Latest":'
# If the module is newer than "latest", the field should be unset...
go mod download -json rsc.io/quote@v1.5.3-pre1
! stdout '"Latest":'
# ...even if that version is also what is required by the main module.
go mod init example.com
go mod edit -require rsc.io/quote@v1.5.3-pre1
go mod download -json rsc.io/quote@v1.5.3-pre1
! stdout '"Latest":'

View File

@ -34,11 +34,11 @@ stderr 'import lookup disabled'
! go build -mod=readonly ./nonexist
! stderr 'import lookup disabled'
stderr 'unknown import path "m/nonexist": cannot find package'
stderr '^can.t load package: package ./nonexist: cannot find package "." in:\n\t'$WORK'[/\\]gopath[/\\]src[/\\]x[/\\]nonexist$'
! go build -mod=readonly ./go.mod
! stderr 'import lookup disabled'
stderr 'unknown import path "m/go.mod": cannot find package'
stderr 'can.t load package: package ./go.mod: cannot find package'
-- x/go.mod --
module m

View File

@ -0,0 +1,10 @@
env GO111MODULE=on
[!net] skip
env GOPROXY=https://proxy.golang.org,direct
env GOSUMDB=off
go get -x -v -d golang.org/x/tools/cmd/goimports
stderr '# get https://proxy.golang.org/golang.org/x/tools/@latest'
! stderr '# get https://golang.org'

View File

@ -4,13 +4,19 @@ env GO111MODULE=on
# @patch and @latest within the main module refer to the current version.
# The main module won't be upgraded, but missing dependencies will be added.
cp go.mod.orig go.mod
go get -d rsc.io/x@latest
go get -d rsc.io/x
grep 'rsc.io/quote v1.5.2' go.mod
go get -d rsc.io/x@upgrade
grep 'rsc.io/quote v1.5.2' go.mod
cp go.mod.orig go.mod
go get -d rsc.io/x@patch
grep 'rsc.io/quote v1.5.2' go.mod
cp go.mod.orig go.mod
# The main module cannot be updated to @latest, which is a specific version.
! go get -d rsc.io/x@latest
stderr '^go get rsc.io/x@latest: can.t request explicit version of path in main module$'
# The main module cannot be updated to a specific version.
! go get rsc.io/x@v0.1.0
stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$'

View File

@ -1,6 +1,7 @@
env GO111MODULE=on
# Download modules to avoid stderr chatter
go mod download example.com@v1.0.0
go mod download example.com/newcycle/a@v1.0.0
go mod download example.com/newcycle/a@v1.0.1
go mod download example.com/newcycle/b@v1.0.0
@ -10,5 +11,6 @@ go mod init m
cmp stderr stderr-expected
-- stderr-expected --
go: finding example.com/newcycle v1.0.0
go get: inconsistent versions:
example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1 (not example.com/newcycle/a@v1.0.0)

View File

@ -10,11 +10,11 @@ grep 'require rsc.io/quote' go.mod
cp go.mod.orig go.mod
! go get -d rsc.io/quote/x...
stderr 'go get rsc.io/quote/x...: module rsc.io/quote@latest \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x...'
stderr 'go get rsc.io/quote/x...: module rsc.io/quote@upgrade \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x...'
! grep 'require rsc.io/quote' go.mod
! go get -d rsc.io/quote/x/...
stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@latest \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x/...'
stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@upgrade \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x/...'
! grep 'require rsc.io/quote' go.mod
# If a pattern matches no packages within a module, the module should not

View File

@ -2,19 +2,26 @@
[!exec:svn] skip
env GO111MODULE=on
env GOPROXY=direct # obtain llvm.org directory, not via svn.
env GOPROXY=direct
env GOSUMDB=off
# Attempting to get a module zip using svn should fail with a reasonable
# message instead of a panic.
# TODO(golang.org/issue/26092): Really, it shouldn't fail at all.
! go get -d llvm.org/llvm/bindings/go/llvm
! go get -d vcs-test.golang.org/svn/hello.svn
stderr 'ReadZip not implemented for svn'
! go install .
stderr 'ReadZip not implemented for svn'
# Attempting to get a nonexistent module using svn should fail with a
# reasonable message instead of a panic.
! go get -d vcs-test.golang.org/svn/nonexistent.svn
! stderr panic
stderr 'go get vcs-test.golang.org/svn/nonexistent.svn: no matching versions for query "upgrade"'
-- go.mod --
module golang/go/issues/28943/main
-- main.go --
package main
import _ "llvm.org/llvm/bindings/go/llvm"
import _ "vcs-test.golang.org/svn/hello.svn"
func main() {}

View File

@ -9,18 +9,33 @@ env GO111MODULE=on
# The v0.1.1 pseudo-version is semantically higher than the latest tag.
# The v0.0.0 pseudo-version is chronologically newer.
# 'get -u' should not downgrade to the (lower) tagged version.
# Start at v0.1.1-0.20190429073117-b5426c86b553
go get -d example.com/pseudoupgrade@b5426c8
go list -m -u all
stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$'
# 'get -u' should not downgrade to the (lower) tagged version.
go get -d -u
go list -m -u all
stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$'
# 'get example.com/pseudoupgrade@latest' should not downgrade to
# the (lower) tagged version.
go get -d example.com/pseudoupgrade@latest
# 'get example.com/pseudoupgrade@upgrade' should not downgrade.
go get -d example.com/pseudoupgrade@upgrade
go list -m all
stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$'
# 'get example.com/pseudoupgrade' should not downgrade.
# This is equivalent to 'get example.com/pseudoupgrade@upgrade'.
go get -d example.com/pseudoupgrade
go list -m all
stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$'
# 'get example.com/pseudoupgrade@latest' should downgrade.
# @latest should not consider the current version.
go get -d example.com/pseudoupgrade@latest
go list -m all
stdout '^example.com/pseudoupgrade v0.1.0$'
# We should observe the same behavior with the newer pseudo-version.
go get -d example.com/pseudoupgrade@v0.0.0-20190430073000-30950c05d534
@ -29,12 +44,21 @@ go get -d -u
go list -m -u all
stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$'
# 'get example.com/pseudoupgrade@latest' should not downgrade to the
# chronologically older tagged version.
go get -d example.com/pseudoupgrade@latest
# 'get example.com/pseudoupgrade@upgrade should not downgrade.
go get -d example.com/pseudoupgrade@upgrade
go list -m -u all
stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$'
# 'get example.com/pseudoupgrade' should not downgrade.
go get -d example.com/pseudoupgrade
go list -m -u all
stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$'
# 'get example.com/pseudoupgrade@latest' should downgrade.
go get -d example.com/pseudoupgrade@latest
go list -m -u all
stdout '^example.com/pseudoupgrade v0.1.0$'
-- go.mod --
module x

View File

@ -62,15 +62,31 @@ import (
"go/build"
"log"
"os"
"path/filepath"
"strings"
)
func main() {
p, err := build.Import(os.Args[1], os.Args[2], 0)
// build.Import should support relative and absolute source dir paths.
path := os.Args[1]
srcDir := os.Args[2]
p1, err := build.Import(path, srcDir, 0)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n%s\n", p.Dir, strings.Join(p.GoFiles, " "))
absSrcDir, err := filepath.Abs(srcDir)
if err != nil {
log.Fatal(err)
}
p2, err := build.Import(path, absSrcDir, 0)
if err != nil {
log.Fatal(err)
}
if p1.Dir != p2.Dir {
log.Fatalf("different packages loaded with relative and absolute paths:\n\t%s\n\t%s", p1.Dir, p2.Dir)
}
fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " "))
}
-- $GOPATH/other/go.mod --

View File

@ -0,0 +1,81 @@
env GO111MODULE=on
# golang.org/issue/31248: module requirements imposed by dependency versions
# older than the selected version must still be taken into account.
env GOFLAGS=-mod=readonly
# Indirect dependencies required via older-than-selected versions must exist in
# the module graph, but do not need to be listed explicitly in the go.mod file
# (since they are implied).
go mod graph
stdout i@v0.1.0
# The modules must also appear in the build list, not just the graph.
go list -m all
stdout '^i v0.1.0'
# The packages provided by those dependencies must resolve.
go list all
stdout '^i$'
-- go.mod --
module main
go 1.13
require (
a v0.0.0
b v0.0.0
c v0.0.0
)
// Apply replacements so that the test can be self-contained.
// (It's easier to see all of the modules here than to go
// rooting around in testdata/mod.)
replace (
a => ./a
b => ./b
c => ./c
x v0.1.0 => ./x1
x v0.2.0 => ./x2
i => ./i
)
-- main.go --
package main
import (
_ "a"
_ "b"
_ "c"
)
func main() {}
-- a/go.mod --
module a
go 1.13
require x v0.1.0
-- a/a.go --
package a
-- b/go.mod --
module b
go 1.13
require x v0.2.0
-- b/b.go --
package b
-- c/go.mod --
module c
go 1.13
-- c/c.go --
package c
import _ "i"
-- x1/go.mod --
module x
go1.13
require i v0.1.0
-- x2/go.mod --
module x
go1.13
-- i/go.mod --
-- i/i.go --
package i

View File

@ -0,0 +1,65 @@
env GO111MODULE=on
# Regression test for golang.org/issue/29773: 'go list -m' was not following
# dependencies through older versions of the main module.
go list -f '{{with .Module}}{{.Path}}{{with .Version}} {{.}}{{end}}{{end}}' all
cmp stdout pkgmods.txt
go list -m all
cmp stdout mods.txt
go mod graph
cmp stdout graph.txt
-- go.mod --
module golang.org/issue/root
go 1.12
replace (
golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0
golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0
golang.org/issue/root v0.1.0 => ./root-v0.1.0
)
require golang.org/issue/mirror v0.1.0
-- root.go --
package root
import _ "golang.org/issue/mirror"
-- mirror-v0.1.0/go.mod --
module golang.org/issue/mirror
require golang.org/issue/root v0.1.0
-- mirror-v0.1.0/mirror.go --
package mirror
import _ "golang.org/issue/pkg"
-- pkg-v0.1.0/go.mod --
module golang.org/issue/pkg
-- pkg-v0.1.0/pkg.go --
package pkg
-- root-v0.1.0/go.mod --
module golang.org/issue/root
require golang.org/issue/pkg v0.1.0
-- pkgmods.txt --
golang.org/issue/mirror v0.1.0
golang.org/issue/pkg v0.1.0
golang.org/issue/root
-- mods.txt --
golang.org/issue/root
golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0
golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0
-- graph.txt --
golang.org/issue/root golang.org/issue/mirror@v0.1.0
golang.org/issue/mirror@v0.1.0 golang.org/issue/root@v0.1.0
golang.org/issue/root@v0.1.0 golang.org/issue/pkg@v0.1.0

View File

@ -0,0 +1,60 @@
env GO111MODULE=on
# golang.org/issue/31248: loading the build list must not add explicit entries
# for indirect dependencies already implied by older-than-selected versions
# already in the build list.
cp go.mod.orig go.mod
go mod tidy
cmp go.mod go.mod.orig
cp go.mod.orig go.mod
go list -m all
cmp go.mod go.mod.orig
-- go.mod.orig --
module main
go 1.13
require a v0.0.0
replace (
a v0.0.0 => ./a
b v0.0.0 => ./b
i v0.0.0 => ./i
x v0.1.0 => ./x1
x v0.2.0 => ./x2
)
-- main.go --
package main
import _ "a"
func main() {}
-- a/go.mod --
module a
go 1.13
require (
x v0.2.0
b v0.0.0
)
-- a/a.go --
package a
-- b/go.mod --
module b
go 1.13
require x v0.1.0
-- x1/go.mod --
module x
go 1.13
require (
b v0.0.0
i v0.0.0
)
-- x2/go.mod --
module x
go 1.13
-- i/go.mod --
module i
go 1.13

View File

@ -134,6 +134,19 @@ cd ..
go list -m golang.org/x/text
stdout 'golang.org/x/text v0.0.0-0.20170915032832-14c0d48ead0c => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c'
# A 'replace' directive can replace an invalid 'latest' version, and
# should suppress errors for that version in 'go get -u'
cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@v1.999999.0
go mod edit -replace golang.org/x/text@v1.999999.0=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c
cd outside
! go get -d golang.org/x/text@upgrade
stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999999.0: reading golang.org/x/text/go.mod at revision v1.999999.0: unknown revision v1.999999.0'
cd ..
go get -d golang.org/x/text@upgrade
go list -m golang.org/x/text
stdout 'golang.org/x/text v1.999999.0 => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c'
# A pseudo-version derived from a non-ancestor tag is invalid.
cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c
@ -144,6 +157,16 @@ cd ..
! go list -m golang.org/x/text
stderr 'golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)'
# A pseudo-version derived from a canonical tag on the same revision is invalid.
cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac
cd outside
! go list -m golang.org/x/text
stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag'
cd ..
! go list -m golang.org/x/text
stderr 'golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag'
# A +incompatible suffix is not allowed on a version that is actually compatible.
cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c+incompatible
@ -165,15 +188,15 @@ go list -m github.com/pierrec/lz4
stdout 'github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1'
cd ..
# A +incompatible version for a module that has an explicit go.mod file is invalid.
# A +incompatible pseudo-version for a module that has an explicit go.mod file is invalid.
cp go.mod.orig go.mod
go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190131084431-473cd7ce01a1+incompatible
go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d+incompatible
cd outside
! go list -m github.com/pierrec/lz4
stderr 'go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190131084431-473cd7ce01a1\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
stderr 'go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
cd ..
! go list -m github.com/pierrec/lz4
stderr 'github.com/pierrec/lz4@v2.0.9-0.20190131084431-473cd7ce01a1\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
stderr 'github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
# A +incompatible pseudo-version is valid for a revision of the module
# that lacks a go.mod file.

View File

@ -34,12 +34,12 @@ go list rsc.io/quote/buggy
# rsc.io/quote/buggy should not be listable as a module
go list -m -e -f '{{.Error.Err}}' nonexist rsc.io/quote/buggy
stdout '^module "nonexist" is not a known dependency'
stdout '^module "rsc.io/quote/buggy" is not a known dependency'
stdout '^module nonexist: not a known dependency$'
stdout '^module rsc.io/quote/buggy: not a known dependency$'
! go list -m nonexist rsc.io/quote/buggy
stderr '^go list -m nonexist: module "nonexist" is not a known dependency'
stderr '^go list -m rsc.io/quote/buggy: module "rsc.io/quote/buggy" is not a known dependency'
stderr '^go list -m: module nonexist: not a known dependency'
stderr '^go list -m: module rsc.io/quote/buggy: not a known dependency'
# Module loader does not interfere with list -e (golang.org/issue/24149).
go list -e -f '{{.Error.Err}}' database

View File

@ -0,0 +1,41 @@
env GO111MODULE=on
[short] skip
# Regression test for golang.org/issue/29667:
# spurious 'failed to cache compiled Go files' errors.
# This test failed reliably when run with -count=10
# on a Linux workstation.
env GOCACHE=$WORK/gocache
mkdir $GOCACHE
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
wait
-- go.mod --
module sandbox/bar
-- bar.go --
package bar
import "C"

View File

@ -12,9 +12,10 @@ stdout ^math$
go list -f '{{.ImportPath}}' .
stdout ^x$
! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
stderr 'unknown import path "rsc.io/quote": cannot find package'
stderr '^can.t load package: package '$WORK'[/\\]gopath/pkg/mod/rsc.io/quote@v1.5.2: can only use path@version syntax with .go get.'
go list -e -f '{{with .Error}}{{.}}{{end}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
stdout 'unknown import path "rsc.io/quote": cannot find package'
stdout '^package '$WORK'[/\\]gopath/pkg/mod/rsc.io/quote@v1.5.2: can only use path@version syntax with .go get.'
go mod download rsc.io/quote@v1.5.2
go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
stdout '^rsc.io/quote$'

View File

@ -0,0 +1,24 @@
env GO111MODULE=on
env GOPROXY=direct
env GOSUMDB=off
[!net] skip
[!exec:git] skip
# golang.org/issue/33099: if an import path ends in a major-version suffix,
# ensure that 'direct' mode can resolve the package to the module.
# For a while, (*modfetch.codeRepo).Stat was not checking for a go.mod file,
# which would produce a hard error at the subsequent call to GoMod.
go list all
-- go.mod --
module example.com
go 1.13
-- main.go --
package main
import _ "vcs-test.golang.org/git/v3pkg.git/v3"
func main() {}

View File

@ -6,7 +6,7 @@ env GO111MODULE=on
go mod download
! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
stderr 'outside available modules'
stderr 'can only use path@version syntax with .go get.'
go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.1
stdout 'rsc.io/quote'

View File

@ -1,8 +1,28 @@
env GO111MODULE=on
# If the current version is not latest, 'go list -u' should include its upgrade.
go list -m -u all
stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]'
# If the current version is latest, 'go list -u' should omit the upgrade.
go get -d rsc.io/quote@v1.5.2
go list -m -u all
stdout 'rsc.io/quote v1.5.2$'
# If the current version is newer than latest, 'go list -u' should
# omit the upgrade.
go get -d rsc.io/quote@v1.5.3-pre1
go list -m -u all
stdout 'rsc.io/quote v1.5.3-pre1$'
# If the current build list has a higher version and the user asks about
# a lower one, -u should report the upgrade for the lower one
# but leave the build list unchanged.
go list -m -u rsc.io/quote@v1.5.1
stdout 'rsc.io/quote v1.5.1 \[v1.5.2\]$'
go list -m -u rsc.io/quote
stdout 'rsc.io/quote v1.5.3-pre1$'
-- go.mod --
module x
require rsc.io/quote v1.2.0

View File

@ -57,19 +57,29 @@ import (
func Test(t *testing.T) {}
-- update-main-expected --
go get: example.com/badchain/c@v1.0.0 updating to
example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong"
example.com/badchain/c@v1.1.0: parsing go.mod:
module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c
-- update-a-expected --
go get: example.com/badchain/a@v1.1.0 requires
example.com/badchain/b@v1.1.0 requires
example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong"
example.com/badchain/c@v1.1.0: parsing go.mod:
module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c
-- list-expected --
go: example.com/badchain/a@v1.1.0 requires
example.com/badchain/b@v1.1.0 requires
example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong"
example.com/badchain/c@v1.1.0: parsing go.mod:
module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c
-- list-missing-expected --
go: m/use imports
example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong"
example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod:
module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c
-- list-missing-test-expected --
go: m/testuse tested by
m/testuse.test imports
example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong"
example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod:
module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c

View File

@ -22,7 +22,7 @@ go list -m rsc.io/quote@<v1.5.4
stdout 'rsc.io/quote v1.5.2$'
! go list -m rsc.io/quote@>v1.5.3
stderr 'go list -m rsc.io/quote: no matching versions for query ">v1.5.3"'
stderr 'go list -m: module rsc.io/quote: no matching versions for query ">v1.5.3"'
go list -m -e -f '{{.Error.Err}}' rsc.io/quote@>v1.5.3
stdout 'no matching versions for query ">v1.5.3"'

View File

@ -28,6 +28,20 @@ go list -m example.com/join/...
! stdout 'example.com/join/subpkg'
stdout 'example.com/join v1.1.0'
# If the proxy provides an empty @v/list but rejects @latest with
# some other explicit error (for example, a "permission denied" error),
# that error should be reported to the user (and override a successful
# result for other possible module paths).
#
# Depending on how the specific platform enforces permissions, the 'go get' may
# fail either due to the intended permission error or due to a parse error.
# We accept either failure message.
env GOPROXY=file:///$WORK/gatekeeper
chmod 0000 $WORK/gatekeeper/example.com/join/subpkg/@latest
cp go.mod.orig go.mod
! go get -d example.com/join/subpkg
stderr 'go get example.com/join/subpkg: module example.com/join/subpkg: (invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)'
-- go.mod.orig --
module example.com/othermodule
go 1.13
@ -50,3 +64,10 @@ v1.0.0-does-not-exist
v1.1.0
-- $WORK/notfound/example.com/join/@v/v1.1.0.info --
{"Version": "v1.1.0"}
-- $WORK/gatekeeper/example.com/join/subpkg/@v/list --
-- $WORK/gatekeeper/example.com/join/subpkg/@latest --
ERROR: Latest version is forbidden.
-- $WORK/gatekeeper/example.com/join/@v/list --
v1.1.0
-- $WORK/gatekeeper/example.com/join/@v/v1.1.0.info --
{"Version": "v1.1.0"}

View File

@ -9,8 +9,8 @@ env dbname=localhost.localdev/sumdb
cp go.mod.orig go.mod
env GOSUMDB=$sumdb' '$proxy/sumdb-wrong
! go get -d rsc.io/quote
stderr 'verifying rsc.io/quote@v1.5.2/go.mod: checksum mismatch'
stderr 'downloaded: h1:LzX7'
stderr 'verifying rsc.io/quote@v1.5.2: checksum mismatch'
stderr 'downloaded: h1:3fEy'
stderr 'localhost.localdev/sumdb: h1:wrong'
stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.'
! go get -d rsc.io/sampler

View File

@ -28,7 +28,7 @@ cp go.mod.orig go.mod
rm go.sum
env GOPROXY=off
go get -d rsc.io/quote@v1.5.2 # using cache
rm $GOPATH/pkg/mod/download/cache/sumdb/localhost.localdev/sumdb/lookup/rsc.io/quote@v1.5.2
rm $GOPATH/pkg/mod/cache/download/sumdb/localhost.localdev/sumdb/lookup/rsc.io/quote@v1.5.2
go get -d rsc.io/quote@v1.5.2 # using go.sum
# fetch fails once we lose access to both cache and go.sum

View File

@ -2,6 +2,7 @@
env GO111MODULE=on
env GOSUMDB=
env GOPATH=$WORK/gopath1
# With a file-based proxy with an empty checksum directory,
# downloading a new module should fail, even if a subsequent
@ -18,11 +19,20 @@ stderr '^verifying golang.org/x/text.*: Not Found'
[!windows] env GOPROXY=file://$WORK/emptyproxy,https://proxy.golang.org
go get -d golang.org/x/text@v0.3.2
# After a successful sumdb lookup, the lookup can be repeated
# using the download cache as a proxy.
cp supported $GOPATH/pkg/mod/cache/download/sumdb/sum.golang.org/supported
[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download,file:///$WORK/sumproxy
[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download,file://$WORK/sumproxy
env GOPATH=$WORK/gopath2
rm go.sum
go get -d -x -v golang.org/x/text@v0.3.2
# Once the checksum is present in the go.sum file,
# an empty file-based sumdb can be used in conjunction with
# a fallback module mirror.
grep golang.org/x/text go.sum
go clean -modcache
env GOPATH=$WORK/gopath3
[windows] env GOPROXY=file:///$WORK/sumproxy
[!windows] env GOPROXY=file://$WORK/sumproxy
! go get -d golang.org/x/text@v0.3.2
@ -30,6 +40,8 @@ go clean -modcache
[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org
go get -d golang.org/x/text@v0.3.2
-- supported --
-- go.mod --
module example.com
go 1.13

View File

@ -14,31 +14,39 @@ stdout '^sum.golang.org$'
[!exec:git] skip
env GOSUMDB=sum.golang.org
env GOPROXY=direct
go get -d rsc.io/quote
go get -d rsc.io/quote@v1.5.2
cp go.sum saved.sum
# download from proxy.golang.org with go.sum entry already
go clean -modcache
env GOSUMDB=
env GOPROXY=
go get -x -d rsc.io/quote
go get -x -d rsc.io/quote@v1.5.2
! stderr github
stderr proxy.golang.org/rsc.io/quote
! stderr sum.golang.org/tile
! stderr sum.golang.org/lookup/rsc.io/quote
cmp go.sum saved.sum
# download again, using checksum database to validate new go.sum lines
# Download again.
# Should use the checksum database to validate new go.sum lines,
# but not need to fetch any new data from the proxy.
rm go.sum
go get -x -d rsc.io/quote
go get -x -d rsc.io/quote@v1.5.2
! stderr github
stderr proxy.golang.org/rsc.io/quote
! stderr proxy.golang.org/rsc.io/quote
stderr sum.golang.org/tile
stderr sum.golang.org/lookup/rsc.io/quote
cmp go.sum saved.sum
# test fallback to direct
env TESTGOPROXY404=1
go get -x -d rsc.io/quote
go clean -modcache
rm go.sum
go get -x -d rsc.io/quote@v1.5.2
stderr 'proxy.golang.org.*404 testing'
stderr github.com/rsc
cmp go.sum saved.sum
-- go.mod --
module m

View File

@ -6,14 +6,14 @@ env GOPROXY GONOPROXY GOSUMDB GONOSUMDB
# basic fetch (through proxy) works
cp go.mod.orig go.mod
go get -d rsc.io/fortune@v1.0.0 # note: must use test proxy, does not exist in real world
rm $GOPATH/pkg/mod/download/cache/sumdb # rm sumdb cache but NOT package download cache
rm $GOPATH/pkg/mod/cache/download/sumdb # rm sumdb cache but NOT package download cache
rm go.sum
# can fetch by explicit URL
cp go.mod.orig go.mod
env GOSUMDB=$sumdb' '$proxy/sumdb-direct
go get -d rsc.io/fortune@v1.0.0
rm $GOPATH/pkg/mod/download/cache/sumdb
rm $GOPATH/pkg/mod/cache/download/sumdb
rm go.sum
# direct access fails (because localhost.localdev does not exist)
@ -25,7 +25,7 @@ env GOSUMDB=$sumdb
env GOPROXY=direct
! go get -d rsc.io/fortune@v1.0.0
stderr 'verifying.*localhost.localdev'
rm $GOPATH/pkg/mod/download/cache/sumdb
rm $GOPATH/pkg/mod/cache/download/sumdb
rm go.sum
# proxy 404 falls back to direct access (which fails)
@ -34,7 +34,7 @@ env GOSUMDB=$sumdb
env GOPROXY=$proxy/sumdb-404
! go get -d rsc.io/fortune@v1.0.0
stderr 'verifying.*localhost.localdev'
rm $GOPATH/pkg/mod/download/cache/sumdb
rm $GOPATH/pkg/mod/cache/download/sumdb
rm go.sum
# proxy non-200/404/410 stops direct access
@ -43,7 +43,7 @@ env GOSUMDB=$sumdb
env GOPROXY=$proxy/sumdb-503
! go get -d rsc.io/fortune@v1.0.0
stderr '503 Service Unavailable'
rm $GOPATH/pkg/mod/download/cache/sumdb
rm $GOPATH/pkg/mod/cache/download/sumdb
rm go.sum
-- go.mod.orig --

View File

@ -0,0 +1,77 @@
[short] skip
env GO111MODULE=on
env GOCACHE=$WORK/gocache
env GODEBUG=gocachetest=1
# The first run of a test should not be cached.
# The second run should be.
go test -run=WriteTmp .
! stdout '(cached)'
go test -run=WriteTmp .
stdout '(cached)'
# 'go test' without arguments should never be cached.
go test -run=WriteTmp
! stdout '(cached)'
go test -run=WriteTmp
! stdout '(cached)'
# We should never cache a test run from command-line files.
go test -run=WriteTmp ./foo_test.go
! stdout '(cached)'
go test -run=WriteTmp ./foo_test.go
! stdout '(cached)'
[!exec:sleep] stop
# The go command refuses to cache access to files younger than 2s, so sleep that long.
exec sleep 2
# Touching a file that the test reads from within its testdata should invalidate the cache.
go test -run=ReadTestdata .
! stdout '(cached)'
go test -run=ReadTestdata .
stdout '(cached)'
cp testdata/bar.txt testdata/foo.txt
go test -run=ReadTestdata .
! stdout '(cached)'
-- go.mod --
module golang.org/issue/29111/foo
-- foo.go --
package foo
-- testdata/foo.txt --
foo
-- testdata/bar.txt --
bar
-- foo_test.go --
package foo_test
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestWriteTmp(t *testing.T) {
dir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
err = ioutil.WriteFile(filepath.Join(dir, "x"), nil, 0666)
if err != nil {
t.Fatal(err)
}
}
func TestReadTestdata(t *testing.T) {
_, err := ioutil.ReadFile("testdata/foo.txt")
if err != nil {
t.Fatal(err)
}
}

View File

@ -0,0 +1,39 @@
env GO111MODULE=on
# Regression test for golang.org/issue/27063:
# 'go mod tidy' and 'go mod vendor' should not hide loading errors.
! go mod tidy
stderr '^issue27063 imports\n\tnonexist: malformed module path "nonexist": missing dot in first path element'
stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com'
stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist'
! go mod vendor
stderr '^issue27063 imports\n\tnonexist: malformed module path "nonexist": missing dot in first path element'
stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com'
stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist'
-- go.mod --
module issue27063
go 1.13
require issue27063/other v0.0.0
replace issue27063/other => ./other
-- x.go --
package main
import (
"nonexist"
"nonexist.example.com"
"issue27063/other"
)
func main() {}
-- other/go.mod --
module issue27063/other
-- other/other.go --
package other
import "other.example.com/nonexist"

View File

@ -171,12 +171,6 @@ package m
import _ "appengine"
import _ "appengine/datastore"
-- nonexistent.go --
// +build alternatereality
package m
import _ "nonexistent.rsc.io"
-- mypkg/go.mod --
module me
-- mypkg/mydir/d.go --

View File

@ -0,0 +1,15 @@
env GO111MODULE=on
go mod init foo
go test
stdout ^ok\s+foo
env GO111MODULE=off
go test
stdout ^ok\s+
! stdout ^ok\s+(cache)$
-- main_test.go --
package main
import "testing"
func TestF(t *testing.T) {}

View File

@ -1,86 +0,0 @@
# Tests for automatic testing.Init calls when using 'go test'.
env GO111MODULE=on
# A TestMain should be able to access testing flags if it calls flag.Parse
# without needing to use testing.Init.
# Test code can use the name 'testing' without colliding with generated
# testinginit code.
# Tests running under 'go test' should observe that testing.Init is called
# before any user package initialization code runs.
go test
stdout TestMain
stdout TestInit
stdout TestExt
-- go.mod --
module m
-- init_test.go --
package testinitflag
import (
"flag"
"fmt"
"os"
Testing "testing"
)
func testFlagsInitialized() bool {
found := false
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "test.count" {
found = true
}
})
return found
}
var testing int
var testingInitAtInitialization = testFlagsInitialized()
func TestInit(t *Testing.T) {
if !testingInitAtInitialization {
t.Fatal("testing.Init not called before package initialization")
}
fmt.Printf("TestInit\n")
}
func TestMain(m *Testing.M) {
fmt.Printf("TestMain\n")
flag.Parse()
if !testFlagsInitialized() {
fmt.Println("testing flags not registered")
os.Exit(1)
}
os.Exit(m.Run())
}
-- external_test.go --
package testinitflag_test
import (
"flag"
"fmt"
Testing "testing"
)
func testFlagsInitialized() bool {
found := false
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "test.count" {
found = true
}
})
return found
}
var testing int
var testingInitAtInitialization = testFlagsInitialized()
func TestExt(t *Testing.T) {
fmt.Printf("TestExt\n")
if !testingInitAtInitialization {
t.Fatal("testing.Init not called before package initialization")
}
}

View File

@ -8,5 +8,12 @@ go version -m fortune.exe
stdout '^\tpath\trsc.io/fortune'
stdout '^\tmod\trsc.io/fortune\tv1.0.0'
go build -buildmode=pie -o external.exe rsc.io/fortune
go version external.exe
stdout '^external.exe: .+'
go version -m external.exe
stdout '^\tpath\trsc.io/fortune'
stdout '^\tmod\trsc.io/fortune\tv1.0.0'
-- go.mod --
module m

View File

@ -0,0 +1,29 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package standalone_testmain_flag_test
import (
"flag"
"fmt"
"os"
"testing"
)
func TestMain(m *testing.M) {
// A TestMain should be able to access testing flags if it calls
// flag.Parse without needing to use testing.Init.
flag.Parse()
found := false
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "test.count" {
found = true
}
})
if !found {
fmt.Println("testing flags not registered")
os.Exit(1)
}
os.Exit(m.Run())
}

View File

@ -0,0 +1,186 @@
package p
const (
// 0-octals
_ = 0
_ = 0123
_ = 0123456
_ = 0_123
_ = 0123_456
// decimals
_ = 1
_ = 1234
_ = 1234567
_ = 1_234
_ = 1_234_567
// hexadecimals
_ = 0x0
_ = 0x1234
_ = 0xcafef00d
_ = 0x0
_ = 0x1234
_ = 0xCAFEf00d
_ = 0x_0
_ = 0x_1234
_ = 0x_CAFE_f00d
// octals
_ = 0o0
_ = 0o1234
_ = 0o01234567
_ = 0o0
_ = 0o1234
_ = 0o01234567
_ = 0o_0
_ = 0o_1234
_ = 0o0123_4567
_ = 0o_0
_ = 0o_1234
_ = 0o0123_4567
// binaries
_ = 0b0
_ = 0b1011
_ = 0b00101101
_ = 0b0
_ = 0b1011
_ = 0b00101101
_ = 0b_0
_ = 0b10_11
_ = 0b_0010_1101
// decimal floats
_ = 0.
_ = 123.
_ = 0123.
_ = .0
_ = .123
_ = .0123
_ = 0e0
_ = 123e+0
_ = 0123e-1
_ = 0e-0
_ = 123e+0
_ = 0123e123
_ = 0.e+1
_ = 123.e-10
_ = 0123.e123
_ = .0e-1
_ = .123e+10
_ = .0123e123
_ = 0.0
_ = 123.123
_ = 0123.0123
_ = 0.0e1
_ = 123.123e-10
_ = 0123.0123e+456
_ = 1_2_3.
_ = 0_123.
_ = 0_0e0
_ = 1_2_3e0
_ = 0_123e0
_ = 0e-0_0
_ = 1_2_3e+0
_ = 0123e1_2_3
_ = 0.e+1
_ = 123.e-1_0
_ = 01_23.e123
_ = .0e-1
_ = .123e+10
_ = .0123e123
_ = 1_2_3.123
_ = 0123.01_23
// hexadecimal floats
_ = 0x0.p+0
_ = 0xdeadcafe.p-10
_ = 0x1234.p123
_ = 0x.1p-0
_ = 0x.deadcafep2
_ = 0x.1234p+10
_ = 0x0p0
_ = 0xdeadcafep+1
_ = 0x1234p-10
_ = 0x0.0p0
_ = 0xdead.cafep+1
_ = 0x12.34p-10
_ = 0xdead_cafep+1
_ = 0x_1234p-10
_ = 0x_dead_cafe.p-10
_ = 0x12_34.p1_2_3
_ = 0x1_2_3_4.p-1_2_3
// imaginaries
_ = 0i
_ = 0i
_ = 8i
_ = 0i
_ = 123i
_ = 123i
_ = 56789i
_ = 1234i
_ = 1234567i
_ = 0i
_ = 0i
_ = 8i
_ = 0i
_ = 123i
_ = 123i
_ = 56_789i
_ = 1_234i
_ = 1_234_567i
_ = 0.i
_ = 123.i
_ = 0123.i
_ = 000123.i
_ = 0e0i
_ = 123e0i
_ = 0123e0i
_ = 000123e0i
_ = 0.e+1i
_ = 123.e-1_0i
_ = 01_23.e123i
_ = 00_01_23.e123i
_ = 0b1010i
_ = 0b1010i
_ = 0o660i
_ = 0o660i
_ = 0xabcDEFi
_ = 0xabcDEFi
_ = 0xabcDEFp0i
_ = 0xabcDEFp0i
)

View File

@ -0,0 +1,186 @@
package p
const (
// 0-octals
_ = 0
_ = 0123
_ = 0123456
_ = 0_123
_ = 0123_456
// decimals
_ = 1
_ = 1234
_ = 1234567
_ = 1_234
_ = 1_234_567
// hexadecimals
_ = 0x0
_ = 0x1234
_ = 0xcafef00d
_ = 0X0
_ = 0X1234
_ = 0XCAFEf00d
_ = 0X_0
_ = 0X_1234
_ = 0X_CAFE_f00d
// octals
_ = 0o0
_ = 0o1234
_ = 0o01234567
_ = 0O0
_ = 0O1234
_ = 0O01234567
_ = 0o_0
_ = 0o_1234
_ = 0o0123_4567
_ = 0O_0
_ = 0O_1234
_ = 0O0123_4567
// binaries
_ = 0b0
_ = 0b1011
_ = 0b00101101
_ = 0B0
_ = 0B1011
_ = 0B00101101
_ = 0b_0
_ = 0b10_11
_ = 0b_0010_1101
// decimal floats
_ = 0.
_ = 123.
_ = 0123.
_ = .0
_ = .123
_ = .0123
_ = 0e0
_ = 123e+0
_ = 0123E-1
_ = 0e-0
_ = 123E+0
_ = 0123E123
_ = 0.e+1
_ = 123.E-10
_ = 0123.e123
_ = .0e-1
_ = .123E+10
_ = .0123E123
_ = 0.0
_ = 123.123
_ = 0123.0123
_ = 0.0e1
_ = 123.123E-10
_ = 0123.0123e+456
_ = 1_2_3.
_ = 0_123.
_ = 0_0e0
_ = 1_2_3e0
_ = 0_123e0
_ = 0e-0_0
_ = 1_2_3E+0
_ = 0123E1_2_3
_ = 0.e+1
_ = 123.E-1_0
_ = 01_23.e123
_ = .0e-1
_ = .123E+10
_ = .0123E123
_ = 1_2_3.123
_ = 0123.01_23
// hexadecimal floats
_ = 0x0.p+0
_ = 0Xdeadcafe.p-10
_ = 0x1234.P123
_ = 0x.1p-0
_ = 0X.deadcafep2
_ = 0x.1234P+10
_ = 0x0p0
_ = 0Xdeadcafep+1
_ = 0x1234P-10
_ = 0x0.0p0
_ = 0Xdead.cafep+1
_ = 0x12.34P-10
_ = 0Xdead_cafep+1
_ = 0x_1234P-10
_ = 0X_dead_cafe.p-10
_ = 0x12_34.P1_2_3
_ = 0X1_2_3_4.P-1_2_3
// imaginaries
_ = 0i
_ = 00i
_ = 08i
_ = 0000000000i
_ = 0123i
_ = 0000000123i
_ = 0000056789i
_ = 1234i
_ = 1234567i
_ = 0i
_ = 0_0i
_ = 0_8i
_ = 0_000_000_000i
_ = 0_123i
_ = 0_000_000_123i
_ = 0_000_056_789i
_ = 1_234i
_ = 1_234_567i
_ = 0.i
_ = 123.i
_ = 0123.i
_ = 000123.i
_ = 0e0i
_ = 123e0i
_ = 0123E0i
_ = 000123E0i
_ = 0.e+1i
_ = 123.E-1_0i
_ = 01_23.e123i
_ = 00_01_23.e123i
_ = 0b1010i
_ = 0B1010i
_ = 0o660i
_ = 0O660i
_ = 0xabcDEFi
_ = 0XabcDEFi
_ = 0xabcDEFP0i
_ = 0XabcDEFp0i
)

View File

@ -8,6 +8,11 @@ import (
"math"
)
import (
"fmt"
"math"
)
import (
"fmt"

View File

@ -8,6 +8,9 @@ import (
"io"
)
import("fmt"
"math")
import (
"fmt"

View File

@ -0,0 +1,11 @@
//gofmt -r=a&&b!=2->a
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 18987.
package p
const _ = x != 1

View File

@ -0,0 +1,11 @@
//gofmt -r=a&&b!=2->a
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 18987.
package p
const _ = x != 1 && x != 2

View File

@ -0,0 +1,24 @@
package q
import "p"
type _ = int
type a = struct{ x int }
type b = p.B
type (
_ = chan<- int
aa = interface{}
bb = p.BB
)
// TODO(gri) We may want to put the '=' into a separate column if
// we have mixed (regular and alias) type declarations in a group.
type (
_ chan<- int
_ = chan<- int
aa0 interface{}
aaa = interface{}
bb0 p.BB
bbb = p.BB
)

View File

@ -0,0 +1,24 @@
package q
import "p"
type _ = int
type a = struct{ x int }
type b = p.B
type (
_ = chan<- int
aa = interface{}
bb = p.BB
)
// TODO(gri) We may want to put the '=' into a separate column if
// we have mixed (regular and alias) type declarations in a group.
type (
_ chan<- int
_ = chan<- int
aa0 interface{}
aaa = interface{}
bb0 p.BB
bbb = p.BB
)

View File

@ -86,6 +86,10 @@ func (versionFlag) Set(s string) error {
name = name[strings.LastIndex(name, `/`)+1:]
name = name[strings.LastIndex(name, `\`)+1:]
name = strings.TrimSuffix(name, ".exe")
// If there's an active experiment, include that,
// to distinguish go1.10.2 with an experiment
// from go1.10.2 without an experiment.
p := Expstring()
if p == DefaultExpstring() {
p = ""
@ -101,12 +105,6 @@ func (versionFlag) Set(s string) error {
// build ID of the binary, so that if the compiler is changed and
// rebuilt, we notice and rebuild all packages.
if s == "full" {
// If there's an active experiment, include that,
// to distinguish go1.10.2 with an experiment
// from go1.10.2 without an experiment.
if x := Expstring(); x != "" {
p += " " + x
}
if strings.HasPrefix(Version, "devel") {
p += " buildID=" + buildID
}

View File

@ -49,7 +49,6 @@ package context
import (
"errors"
"internal/oserror"
"internal/reflectlite"
"sync"
"time"
@ -163,9 +162,6 @@ type deadlineExceededError struct{}
func (deadlineExceededError) Error() string { return "context deadline exceeded" }
func (deadlineExceededError) Timeout() bool { return true }
func (deadlineExceededError) Temporary() bool { return true }
func (deadlineExceededError) Is(target error) bool {
return target == oserror.ErrTimeout || target == oserror.ErrTemporary
}
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.

View File

@ -5,10 +5,8 @@
package context
import (
"errors"
"fmt"
"math/rand"
"os"
"runtime"
"strings"
"sync"
@ -649,7 +647,4 @@ func XTestDeadlineExceededSupportsTimeout(t testingT) {
if !i.Timeout() {
t.Fatal("wrong value for timeout")
}
if !errors.Is(DeadlineExceeded, os.ErrTimeout) {
t.Fatal("errors.Is(DeadlineExceeded, os.ErrTimeout) = false, want true")
}
}

View File

@ -555,7 +555,7 @@ func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int
}
// DecryptOAEP decrypts ciphertext using RSA-OAEP.
//
// OAEP is parameterised by a hash function that is used as a random oracle.
// Encryption and decryption of a given message must use the same hash function
// and sha256.New() is a reasonable choice.

View File

@ -23,11 +23,14 @@ import (
)
const (
VersionSSL30 = 0x0300
VersionTLS10 = 0x0301
VersionTLS11 = 0x0302
VersionTLS12 = 0x0303
VersionTLS13 = 0x0304
// Deprecated: SSLv3 is cryptographically broken, and will be
// removed in Go 1.14. See golang.org/issue/32716.
VersionSSL30 = 0x0300
)
const (
@ -791,6 +794,10 @@ var supportedVersions = []uint16{
func (c *Config) supportedVersions(isClient bool) []uint16 {
versions := make([]uint16, 0, len(supportedVersions))
for _, v := range supportedVersions {
// TLS 1.0 is the default minimum version.
if (c == nil || c.MinVersion == 0) && v < VersionTLS10 {
continue
}
if c != nil && c.MinVersion != 0 && v < c.MinVersion {
continue
}

View File

@ -77,6 +77,20 @@ func TestRejectBadProtocolVersion(t *testing.T) {
}, "unsupported versions")
}
func TestSSLv3OptIn(t *testing.T) {
config := testConfig.Clone()
config.MinVersion = 0
testClientHelloFailure(t, config, &clientHelloMsg{
vers: VersionSSL30,
random: make([]byte, 32),
}, "unsupported versions")
testClientHelloFailure(t, config, &clientHelloMsg{
vers: VersionTLS12,
supportedVersions: []uint16{VersionSSL30},
random: make([]byte, 32),
}, "unsupported versions")
}
func TestNoSuiteOverlap(t *testing.T) {
clientHello := &clientHelloMsg{
vers: VersionTLS10,

View File

@ -222,28 +222,65 @@ func tempFile(contents string) string {
// localListener is set up by TestMain and used by localPipe to create Conn
// pairs like net.Pipe, but connected by an actual buffered TCP connection.
var localListener struct {
sync.Mutex
net.Listener
mu sync.Mutex
addr net.Addr
ch chan net.Conn
}
const localFlakes = 0 // change to 1 or 2 to exercise localServer/localPipe handling of mismatches
func localServer(l net.Listener) {
for n := 0; ; n++ {
c, err := l.Accept()
if err != nil {
return
}
if localFlakes == 1 && n%2 == 0 {
c.Close()
continue
}
localListener.ch <- c
}
}
func localPipe(t testing.TB) (net.Conn, net.Conn) {
localListener.Lock()
defer localListener.Unlock()
c := make(chan net.Conn)
go func() {
conn, err := localListener.Accept()
localListener.mu.Lock()
defer localListener.mu.Unlock()
addr := localListener.addr
Dialing:
// We expect a rare mismatch, but probably not 5 in a row.
for i := 0; i < 5; i++ {
tooSlow := time.NewTimer(1 * time.Second)
defer tooSlow.Stop()
c1, err := net.Dial(addr.Network(), addr.String())
if err != nil {
t.Errorf("Failed to accept local connection: %v", err)
t.Fatalf("localPipe: %v", err)
}
if localFlakes == 2 && i == 0 {
c1.Close()
continue
}
for {
select {
case <-tooSlow.C:
t.Logf("localPipe: timeout waiting for %v", c1.LocalAddr())
c1.Close()
continue Dialing
case c2 := <-localListener.ch:
if c2.RemoteAddr().String() == c1.LocalAddr().String() {
return c1, c2
}
t.Logf("localPipe: unexpected connection: %v != %v", c2.RemoteAddr(), c1.LocalAddr())
c2.Close()
}
}
c <- conn
}()
addr := localListener.Addr()
c1, err := net.Dial(addr.Network(), addr.String())
if err != nil {
t.Fatalf("Failed to dial local connection: %v", err)
}
c2 := <-c
return c1, c2
t.Fatalf("localPipe: failed to connect")
panic("unreachable")
}
// zeroSource is an io.Reader that returns an unlimited number of zero bytes.
@ -293,8 +330,10 @@ func runMain(m *testing.M) int {
fmt.Fprintf(os.Stderr, "Failed to open local listener: %v", err)
os.Exit(1)
}
localListener.Listener = l
defer localListener.Close()
localListener.ch = make(chan net.Conn)
localListener.addr = l.Addr()
defer l.Close()
go localServer(l)
if err := checkOpenSSLVersion(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v", err)

View File

@ -359,50 +359,6 @@ func TestVerifyHostname(t *testing.T) {
}
}
func TestVerifyHostnameResumed(t *testing.T) {
t.Run("TLSv12", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS13) })
}
func testVerifyHostnameResumed(t *testing.T, version uint16) {
testenv.MustHaveExternalNetwork(t)
config := &Config{
MaxVersion: version,
ClientSessionCache: NewLRUClientSessionCache(32),
}
for i := 0; i < 2; i++ {
c, err := DialWithDialer(&net.Dialer{
Timeout: 10 * time.Second,
}, "tcp", "mail.google.com:https", config)
if err != nil {
t.Fatalf("Dial #%d: %v", i, err)
}
cs := c.ConnectionState()
if i > 0 && !cs.DidResume {
t.Fatalf("Subsequent connection unexpectedly didn't resume")
}
if cs.Version != version {
t.Fatalf("Unexpectedly negotiated version %x", cs.Version)
}
if cs.VerifiedChains == nil {
t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i)
}
if err := c.VerifyHostname("mail.google.com"); err != nil {
t.Fatalf("verify mail.google.com #%d: %v", i, err)
}
// Have the server send some data so session tickets are delivered.
c.SetDeadline(time.Now().Add(5 * time.Second))
if _, err := io.WriteString(c, "HEAD / HTTP/1.0\n\n"); err != nil {
t.Fatal(err)
}
if _, err := c.Read(make([]byte, 1)); err != nil {
t.Fatal(err)
}
c.Close()
}
}
func TestConnCloseBreakingWrite(t *testing.T) {
ln := newLocalListener(t)
defer ln.Close()

View File

@ -171,6 +171,11 @@ type Symbol struct {
Info, Other byte
Section SectionIndex
Value, Size uint64
// Version and Library are present only for the dynamic symbol
// table.
Version string
Library string
}
/*
@ -1321,12 +1326,23 @@ func (f *File) Symbols() ([]Symbol, error) {
// DynamicSymbols returns the dynamic symbol table for f. The symbols
// will be listed in the order they appear in f.
//
// If f has a symbol version table, the returned Symbols will have
// initialized Version and Library fields.
//
// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
// After retrieving the symbols as symtab, an externally supplied index x
// corresponds to symtab[x-1], not symtab[x].
func (f *File) DynamicSymbols() ([]Symbol, error) {
sym, _, err := f.getSymbols(SHT_DYNSYM)
return sym, err
sym, str, err := f.getSymbols(SHT_DYNSYM)
if err != nil {
return nil, err
}
if f.gnuVersionInit(str) {
for i := range sym {
sym[i].Library, sym[i].Version = f.gnuVersion(i)
}
}
return sym, nil
}
type ImportedSymbol struct {
@ -1349,7 +1365,8 @@ func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
for i, s := range sym {
if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
all = append(all, ImportedSymbol{Name: s.Name})
f.gnuVersion(i, &all[len(all)-1])
sym := &all[len(all)-1]
sym.Library, sym.Version = f.gnuVersion(i)
}
}
return all, nil
@ -1362,11 +1379,16 @@ type verneed struct {
// gnuVersionInit parses the GNU version tables
// for use by calls to gnuVersion.
func (f *File) gnuVersionInit(str []byte) {
func (f *File) gnuVersionInit(str []byte) bool {
if f.gnuNeed != nil {
// Already initialized
return true
}
// Accumulate verneed information.
vn := f.SectionByType(SHT_GNU_VERNEED)
if vn == nil {
return
return false
}
d, _ := vn.Data()
@ -1421,17 +1443,18 @@ func (f *File) gnuVersionInit(str []byte) {
// Versym parallels symbol table, indexing into verneed.
vs := f.SectionByType(SHT_GNU_VERSYM)
if vs == nil {
return
return false
}
d, _ = vs.Data()
f.gnuNeed = need
f.gnuVersym = d
return true
}
// gnuVersion adds Library and Version information to sym,
// which came from offset i of the symbol table.
func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
func (f *File) gnuVersion(i int) (library string, version string) {
// Each entry is two bytes.
i = (i + 1) * 2
if i >= len(f.gnuVersym) {
@ -1442,8 +1465,7 @@ func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
return
}
n := &f.gnuNeed[j]
sym.Library = n.File
sym.Version = n.Name
return n.File, n.Name
}
// ImportedLibraries returns the names of all libraries

View File

@ -819,6 +819,8 @@ var dynamicSymbolsGolden = map[string][]Symbol{
Section: 0x0,
Value: 0x0,
Size: 0x18C,
Version: "GLIBC_2.2.5",
Library: "libc.so.6",
},
Symbol{
Name: "__libc_start_main",
@ -827,6 +829,8 @@ var dynamicSymbolsGolden = map[string][]Symbol{
Section: 0x0,
Value: 0x0,
Size: 0x1C2,
Version: "GLIBC_2.2.5",
Library: "libc.so.6",
},
},
"testdata/go-relocation-test-clang-x86.obj": {},

Some files were not shown because too many files have changed in this diff Show More