Commit 0b3c2eed by Ian Lance Taylor

libgo: update to Go1.14rc1 release

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/218017
parent 17edb331
3e46519cee5c916a9b39480fbac13f4ffc6a93b0 f368afbbd466941dcc6717412d7182e122b40c93
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
a5bfd9da1d1b24f326399b6b75558ded14514f23 a068054af141c01df5a4519844f4b77273605f4e
The first line of this file holds the git revision number of the The first line of this file holds the git revision number of the
last merge done from the master library sources. last merge done from the master library sources.
...@@ -907,7 +907,7 @@ ...@@ -907,7 +907,7 @@
// Main bool // is this the main module? // Main bool // is this the main module?
// Indirect bool // is this module only an indirect dependency of main module? // Indirect bool // is this module only an indirect dependency of main module?
// Dir string // directory holding files for this module, if any // Dir string // directory holding files for this module, if any
// GoMod string // path to go.mod file for this module, if any // GoMod string // path to go.mod file used when loading this module, if any
// GoVersion string // go version used in module // GoVersion string // go version used in module
// Error *ModuleError // error loading module // Error *ModuleError // error loading module
// } // }
...@@ -916,6 +916,9 @@ ...@@ -916,6 +916,9 @@
// Err string // the error itself // Err string // the error itself
// } // }
// //
// The file GoMod refers to may be outside the module directory if the
// module is in the module cache or if the -modfile flag is used.
//
// The default output is to print the module path and then // The default output is to print the module path and then
// information about the version and replacement if any. // information about the version and replacement if any.
// For example, 'go list -m all' might print: // For example, 'go list -m all' might print:
...@@ -1020,7 +1023,9 @@ ...@@ -1020,7 +1023,9 @@
// execution. The "go mod download" command is useful mainly for pre-filling // execution. The "go mod download" command is useful mainly for pre-filling
// the local cache or to compute the answers for a Go module proxy. // the local cache or to compute the answers for a Go module proxy.
// //
// By default, download reports errors to standard error but is otherwise silent. // By default, download writes nothing to standard output. It may print progress
// messages and errors to standard error.
//
// The -json flag causes download to print a sequence of JSON objects // The -json flag causes download to print a sequence of JSON objects
// to standard output, describing each downloaded module (or failure), // to standard output, describing each downloaded module (or failure),
// corresponding to this Go struct: // corresponding to this Go struct:
...@@ -2346,14 +2351,15 @@ ...@@ -2346,14 +2351,15 @@
// //
// Module support // Module support
// //
// Go 1.13 includes support for Go modules. Module-aware mode is active by default // The go command includes support for Go modules. Module-aware mode is active
// whenever a go.mod file is found in, or in a parent of, the current directory. // by default whenever a go.mod file is found in the current directory or in
// any parent directory.
// //
// The quickest way to take advantage of module support is to check out your // The quickest way to take advantage of module support is to check out your
// repository, create a go.mod file (described in the next section) there, and run // repository, create a go.mod file (described in the next section) there, and run
// go commands from within that file tree. // go commands from within that file tree.
// //
// For more fine-grained control, Go 1.13 continues to respect // For more fine-grained control, the go command continues to respect
// a temporary environment variable, GO111MODULE, which can be set to one // a temporary environment variable, GO111MODULE, which can be set to one
// of three string values: off, on, or auto (the default). // of three string values: off, on, or auto (the default).
// If GO111MODULE=on, then the go command requires the use of modules, // If GO111MODULE=on, then the go command requires the use of modules,
......
...@@ -178,7 +178,9 @@ func runClean(cmd *base.Command, args []string) { ...@@ -178,7 +178,9 @@ func runClean(cmd *base.Command, args []string) {
} }
} }
if err != nil { if err != nil {
base.Errorf("go clean -testcache: %v", err) if _, statErr := os.Stat(dir); !os.IsNotExist(statErr) {
base.Errorf("go clean -testcache: %v", err)
}
} }
} }
} }
......
...@@ -211,7 +211,7 @@ applied to a Go struct, but now a Module struct: ...@@ -211,7 +211,7 @@ applied to a Go struct, but now a Module struct:
Main bool // is this the main module? Main bool // is this the main module?
Indirect bool // is this module only an indirect dependency of main module? Indirect bool // is this module only an indirect dependency of main module?
Dir string // directory holding files for this module, if any Dir string // directory holding files for this module, if any
GoMod string // path to go.mod file for this module, if any GoMod string // path to go.mod file used when loading this module, if any
GoVersion string // go version used in module GoVersion string // go version used in module
Error *ModuleError // error loading module Error *ModuleError // error loading module
} }
...@@ -220,6 +220,9 @@ applied to a Go struct, but now a Module struct: ...@@ -220,6 +220,9 @@ applied to a Go struct, but now a Module struct:
Err string // the error itself Err string // the error itself
} }
The file GoMod refers to may be outside the module directory if the
module is in the module cache or if the -modfile flag is used.
The default output is to print the module path and then The default output is to print the module path and then
information about the version and replacement if any. information about the version and replacement if any.
For example, 'go list -m all' might print: For example, 'go list -m all' might print:
...@@ -387,15 +390,24 @@ func runList(cmd *base.Command, args []string) { ...@@ -387,15 +390,24 @@ func runList(cmd *base.Command, args []string) {
modload.InitMod() // Parses go.mod and sets cfg.BuildMod. modload.InitMod() // Parses go.mod and sets cfg.BuildMod.
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
const actionDisabledFormat = "go list -m: can't %s using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)"
if *listVersions {
base.Fatalf(actionDisabledFormat, "determine available versions")
}
if *listU {
base.Fatalf(actionDisabledFormat, "determine available upgrades")
}
for _, arg := range args { for _, arg := range args {
// In vendor mode, the module graph is incomplete: it contains only the // In vendor mode, the module graph is incomplete: it contains only the
// explicit module dependencies and the modules that supply packages in // explicit module dependencies and the modules that supply packages in
// the import graph. Reject queries that imply more information than that. // the import graph. Reject queries that imply more information than that.
if arg == "all" { if arg == "all" {
base.Fatalf("go list -m: can't compute 'all' using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)") base.Fatalf(actionDisabledFormat, "compute 'all'")
} }
if strings.Contains(arg, "...") { if strings.Contains(arg, "...") {
base.Fatalf("go list -m: can't match module patterns using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)") base.Fatalf(actionDisabledFormat, "match module patterns")
} }
} }
} }
......
...@@ -30,7 +30,9 @@ The go command will automatically download modules as needed during ordinary ...@@ -30,7 +30,9 @@ The go command will automatically download modules as needed during ordinary
execution. The "go mod download" command is useful mainly for pre-filling execution. The "go mod download" command is useful mainly for pre-filling
the local cache or to compute the answers for a Go module proxy. the local cache or to compute the answers for a Go module proxy.
By default, download reports errors to standard error but is otherwise silent. By default, download writes nothing to standard output. It may print progress
messages and errors to standard error.
The -json flag causes download to print a sequence of JSON objects The -json flag causes download to print a sequence of JSON objects
to standard output, describing each downloaded module (or failure), to standard output, describing each downloaded module (or failure),
corresponding to this Go struct: corresponding to this Go struct:
......
...@@ -13,7 +13,6 @@ import ( ...@@ -13,7 +13,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"time"
"cmd/go/internal/base" "cmd/go/internal/base"
"cmd/go/internal/cfg" "cmd/go/internal/cfg"
...@@ -28,8 +27,6 @@ import ( ...@@ -28,8 +27,6 @@ import (
var PkgMod string // $GOPATH/pkg/mod; set by package modload var PkgMod string // $GOPATH/pkg/mod; set by package modload
const logFindingDelay = 1 * time.Second
func cacheDir(path string) (string, error) { func cacheDir(path string) (string, error) {
if PkgMod == "" { if PkgMod == "" {
return "", fmt.Errorf("internal error: modfetch.PkgMod not set") return "", fmt.Errorf("internal error: modfetch.PkgMod not set")
...@@ -140,11 +137,6 @@ func (r *cachingRepo) Versions(prefix string) ([]string, error) { ...@@ -140,11 +137,6 @@ func (r *cachingRepo) Versions(prefix string) ([]string, error) {
err error err error
} }
c := r.cache.Do("versions:"+prefix, func() interface{} { c := r.cache.Do("versions:"+prefix, func() interface{} {
logTimer := time.AfterFunc(logFindingDelay, func() {
fmt.Fprintf(os.Stderr, "go: finding versions for %s\n", r.path)
})
defer logTimer.Stop()
list, err := r.r.Versions(prefix) list, err := r.r.Versions(prefix)
return cached{list, err} return cached{list, err}
}).(cached) }).(cached)
...@@ -167,11 +159,6 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { ...@@ -167,11 +159,6 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) {
return cachedInfo{info, nil} return cachedInfo{info, nil}
} }
logTimer := time.AfterFunc(logFindingDelay, func() {
fmt.Fprintf(os.Stderr, "go: finding %s %s\n", r.path, rev)
})
defer logTimer.Stop()
info, err = r.r.Stat(rev) info, err = r.r.Stat(rev)
if err == nil { if err == nil {
// If we resolved, say, 1234abcde to v0.0.0-20180604122334-1234abcdef78, // If we resolved, say, 1234abcde to v0.0.0-20180604122334-1234abcdef78,
...@@ -199,11 +186,6 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { ...@@ -199,11 +186,6 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) {
func (r *cachingRepo) Latest() (*RevInfo, error) { func (r *cachingRepo) Latest() (*RevInfo, error) {
c := r.cache.Do("latest:", func() interface{} { c := r.cache.Do("latest:", func() interface{} {
logTimer := time.AfterFunc(logFindingDelay, func() {
fmt.Fprintf(os.Stderr, "go: finding %s latest\n", r.path)
})
defer logTimer.Stop()
info, err := r.r.Latest() info, err := r.r.Latest()
// Save info for likely future Stat call. // Save info for likely future Stat call.
......
...@@ -682,8 +682,11 @@ func (r *gitRepo) RecentTag(rev, prefix, major string) (tag string, err error) { ...@@ -682,8 +682,11 @@ func (r *gitRepo) RecentTag(rev, prefix, major string) (tag string, err error) {
semtag := line[len(prefix):] semtag := line[len(prefix):]
// Consider only tags that are valid and complete (not just major.minor prefixes). // Consider only tags that are valid and complete (not just major.minor prefixes).
if c := semver.Canonical(semtag); c != "" && strings.HasPrefix(semtag, c) && (major == "" || semver.Major(c) == major) { // NOTE: Do not replace the call to semver.Compare with semver.Max.
highest = semver.Max(highest, semtag) // We want to return the actual tag, not a canonicalized version of it,
// and semver.Max currently canonicalizes (see golang.org/issue/32700).
if c := semver.Canonical(semtag); c != "" && strings.HasPrefix(semtag, c) && (major == "" || semver.Major(c) == major) && semver.Compare(semtag, highest) > 0 {
highest = semtag
} }
} }
......
...@@ -191,22 +191,6 @@ func (r *codeRepo) appendIncompatibleVersions(list, incompatible []string) ([]st ...@@ -191,22 +191,6 @@ func (r *codeRepo) appendIncompatibleVersions(list, incompatible []string) ([]st
return list, nil return list, nil
} }
// We assume that if the latest release of any major version has a go.mod
// file, all subsequent major versions will also have go.mod files (and thus
// be ineligible for use as +incompatible versions).
// If we're wrong about a major version, users will still be able to 'go get'
// specific higher versions explicitly — they just won't affect 'latest' or
// appear in 'go list'.
//
// Conversely, we assume that if the latest release of any major version lacks
// a go.mod file, all versions also lack go.mod files. If we're wrong, we may
// include a +incompatible version that isn't really valid, but most
// operations won't try to use that version anyway.
//
// These optimizations bring
// 'go list -versions -m github.com/openshift/origin' down from 1m58s to 0m37s.
// That's still not great, but a substantial improvement.
versionHasGoMod := func(v string) (bool, error) { versionHasGoMod := func(v string) (bool, error) {
_, err := r.code.ReadFile(v, "go.mod", codehost.MaxGoMod) _, err := r.code.ReadFile(v, "go.mod", codehost.MaxGoMod)
if err == nil { if err == nil {
...@@ -241,32 +225,41 @@ func (r *codeRepo) appendIncompatibleVersions(list, incompatible []string) ([]st ...@@ -241,32 +225,41 @@ func (r *codeRepo) appendIncompatibleVersions(list, incompatible []string) ([]st
} }
} }
var lastMajor string var (
lastMajor string
lastMajorHasGoMod bool
)
for i, v := range incompatible { for i, v := range incompatible {
major := semver.Major(v) major := semver.Major(v)
if major == lastMajor {
list = append(list, v+"+incompatible")
continue
}
rem := incompatible[i:] if major != lastMajor {
j := sort.Search(len(rem), func(j int) bool { rem := incompatible[i:]
return semver.Major(rem[j]) != major j := sort.Search(len(rem), func(j int) bool {
}) return semver.Major(rem[j]) != major
latestAtMajor := rem[j-1] })
latestAtMajor := rem[j-1]
ok, err := versionHasGoMod(latestAtMajor)
if err != nil { var err error
return nil, err lastMajor = major
} lastMajorHasGoMod, err = versionHasGoMod(latestAtMajor)
if ok { if err != nil {
// This major version has a go.mod file, so it is not allowed as return nil, err
// +incompatible. Subsequent major versions are likely to also have }
// go.mod files, so stop here.
break
} }
lastMajor = major if lastMajorHasGoMod {
// The latest release of this major version has a go.mod file, so it is
// not allowed as +incompatible. It would be confusing to include some
// minor versions of this major version as +incompatible but require
// semantic import versioning for others, so drop all +incompatible
// versions for this major version.
//
// If we're wrong about a minor version in the middle, users will still be
// able to 'go get' specific tags for that version explicitly — they just
// won't appear in 'go list' or as the results for queries with inequality
// bounds.
continue
}
list = append(list, v+"+incompatible") list = append(list, v+"+incompatible")
} }
...@@ -708,7 +701,7 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e ...@@ -708,7 +701,7 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e
return "", "", nil, fmt.Errorf("reading %s/%s at revision %s: %v", r.pathPrefix, file1, rev, err1) return "", "", nil, fmt.Errorf("reading %s/%s at revision %s: %v", r.pathPrefix, file1, rev, err1)
} }
mpath1 := modfile.ModulePath(gomod1) mpath1 := modfile.ModulePath(gomod1)
found1 := err1 == nil && isMajor(mpath1, r.pathMajor) found1 := err1 == nil && (isMajor(mpath1, r.pathMajor) || r.canReplaceMismatchedVersionDueToBug(mpath1))
var file2 string var file2 string
if r.pathMajor != "" && r.codeRoot != r.modPath && !strings.HasPrefix(r.pathMajor, ".") { if r.pathMajor != "" && r.codeRoot != r.modPath && !strings.HasPrefix(r.pathMajor, ".") {
...@@ -817,6 +810,17 @@ func isMajor(mpath, pathMajor string) bool { ...@@ -817,6 +810,17 @@ func isMajor(mpath, pathMajor string) bool {
return pathMajor[1:] == mpathMajor[1:] return pathMajor[1:] == mpathMajor[1:]
} }
// canReplaceMismatchedVersionDueToBug reports whether versions of r
// could replace versions of mpath with otherwise-mismatched major versions
// due to a historical bug in the Go command (golang.org/issue/34254).
func (r *codeRepo) canReplaceMismatchedVersionDueToBug(mpath string) bool {
// The bug caused us to erroneously accept unversioned paths as replacements
// for versioned gopkg.in paths.
unversioned := r.pathMajor == ""
replacingGopkgIn := strings.HasPrefix(mpath, "gopkg.in/")
return unversioned && replacingGopkgIn
}
func (r *codeRepo) GoMod(version string) (data []byte, err error) { func (r *codeRepo) GoMod(version string) (data []byte, err error) {
if version != module.CanonicalVersion(version) { if version != module.CanonicalVersion(version) {
return nil, fmt.Errorf("version %s is not canonical", version) return nil, fmt.Errorf("version %s is not canonical", version)
......
...@@ -112,7 +112,7 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { ...@@ -112,7 +112,7 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic {
} }
if HasModRoot() { if HasModRoot() {
info.Dir = ModRoot() info.Dir = ModRoot()
info.GoMod = filepath.Join(info.Dir, "go.mod") info.GoMod = ModFilePath()
if modFile.Go != nil { if modFile.Go != nil {
info.GoVersion = modFile.Go.Version info.GoVersion = modFile.Go.Version
} }
......
...@@ -21,14 +21,15 @@ which source files are used in a given build. ...@@ -21,14 +21,15 @@ which source files are used in a given build.
Module support Module support
Go 1.13 includes support for Go modules. Module-aware mode is active by default The go command includes support for Go modules. Module-aware mode is active
whenever a go.mod file is found in, or in a parent of, the current directory. by default whenever a go.mod file is found in the current directory or in
any parent directory.
The quickest way to take advantage of module support is to check out your The quickest way to take advantage of module support is to check out your
repository, create a go.mod file (described in the next section) there, and run repository, create a go.mod file (described in the next section) there, and run
go commands from within that file tree. go commands from within that file tree.
For more fine-grained control, Go 1.13 continues to respect For more fine-grained control, the go command continues to respect
a temporary environment variable, GO111MODULE, which can be set to one a temporary environment variable, GO111MODULE, which can be set to one
of three string values: off, on, or auto (the default). of three string values: off, on, or auto (the default).
If GO111MODULE=on, then the go command requires the use of modules, If GO111MODULE=on, then the go command requires the use of modules,
......
...@@ -203,7 +203,12 @@ func Import(path string) (m module.Version, dir string, err error) { ...@@ -203,7 +203,12 @@ func Import(path string) (m module.Version, dir string, err error) {
latest := map[string]string{} // path -> version latest := map[string]string{} // path -> version
for _, r := range modFile.Replace { for _, r := range modFile.Replace {
if maybeInModule(path, r.Old.Path) { if maybeInModule(path, r.Old.Path) {
latest[r.Old.Path] = semver.Max(r.Old.Version, latest[r.Old.Path]) // Don't use semver.Max here; need to preserve +incompatible suffix.
v := latest[r.Old.Path]
if semver.Compare(r.Old.Version, v) > 0 {
v = r.Old.Version
}
latest[r.Old.Path] = v
} }
} }
...@@ -264,6 +269,8 @@ func Import(path string) (m module.Version, dir string, err error) { ...@@ -264,6 +269,8 @@ func Import(path string) (m module.Version, dir string, err error) {
return module.Version{}, "", &ImportMissingError{Path: path} return module.Version{}, "", &ImportMissingError{Path: path}
} }
fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path)
candidates, err := QueryPackage(path, "latest", Allowed) candidates, err := QueryPackage(path, "latest", Allowed)
if err != nil { if err != nil {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
......
...@@ -1324,6 +1324,21 @@ func fetch(mod module.Version) (dir string, isLocal bool, err error) { ...@@ -1324,6 +1324,21 @@ func fetch(mod module.Version) (dir string, isLocal bool, err error) {
if !filepath.IsAbs(dir) { if !filepath.IsAbs(dir) {
dir = filepath.Join(ModRoot(), dir) dir = filepath.Join(ModRoot(), dir)
} }
// Ensure that the replacement directory actually exists:
// dirInModule does not report errors for missing modules,
// so if we don't report the error now, later failures will be
// very mysterious.
if _, err := os.Stat(dir); err != nil {
if os.IsNotExist(err) {
// Semantically the module version itself “exists” — we just don't
// have its source code. Remove the equivalence to os.ErrNotExist,
// and make the message more concise while we're at it.
err = fmt.Errorf("replacement directory %s does not exist", r.Path)
} else {
err = fmt.Errorf("replacement directory %s: %w", r.Path, err)
}
return dir, true, module.VersionError(mod, err)
}
return dir, true, nil return dir, true, nil
} }
mod = r mod = r
......
...@@ -79,7 +79,7 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) ...@@ -79,7 +79,7 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version)
if current != "" && !semver.IsValid(current) { if current != "" && !semver.IsValid(current) {
return nil, fmt.Errorf("invalid previous version %q", current) return nil, fmt.Errorf("invalid previous version %q", current)
} }
if cfg.BuildMod != "" && cfg.BuildMod != "mod" { if cfg.BuildMod == "vendor" {
return nil, errQueryDisabled return nil, errQueryDisabled
} }
if allowed == nil { if allowed == nil {
......
...@@ -64,7 +64,7 @@ var queryTests = []struct { ...@@ -64,7 +64,7 @@ var queryTests = []struct {
git add go.mod git add go.mod
git commit -m v1 go.mod git commit -m v1 go.mod
git tag start git tag start
for i in v0.0.0-pre1 v0.0.0 v0.0.1 v0.0.2 v0.0.3 v0.1.0 v0.1.1 v0.1.2 v0.3.0 v1.0.0 v1.1.0 v1.9.0 v1.9.9 v1.9.10-pre1 v1.9.10-pre2+metadata; do for i in v0.0.0-pre1 v0.0.0 v0.0.1 v0.0.2 v0.0.3 v0.1.0 v0.1.1 v0.1.2 v0.3.0 v1.0.0 v1.1.0 v1.9.0 v1.9.9 v1.9.10-pre1 v1.9.10-pre2+metadata unversioned; do
echo before $i >status echo before $i >status
git add status git add status
git commit -m "before $i" status git commit -m "before $i" status
...@@ -107,6 +107,7 @@ var queryTests = []struct { ...@@ -107,6 +107,7 @@ var queryTests = []struct {
{path: queryRepo, query: "v0.2", err: `no matching versions for query "v0.2"`}, {path: queryRepo, query: "v0.2", err: `no matching versions for query "v0.2"`},
{path: queryRepo, query: "v0.0", vers: "v0.0.3"}, {path: queryRepo, query: "v0.0", vers: "v0.0.3"},
{path: queryRepo, query: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, {path: queryRepo, query: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
{path: queryRepo, query: "ed5ffdaa", vers: "v1.9.10-pre2.0.20191220134614-ed5ffdaa1f5e"},
// golang.org/issue/29262: The major version for for a module without a suffix // golang.org/issue/29262: The major version for for a module without a suffix
// should be based on the most recent tag (v1 as appropriate, not v0 // should be based on the most recent tag (v1 as appropriate, not v0
...@@ -162,10 +163,14 @@ var queryTests = []struct { ...@@ -162,10 +163,14 @@ var queryTests = []struct {
{path: queryRepoV2, query: "v2.6.0-pre1", vers: "v2.6.0-pre1"}, {path: queryRepoV2, query: "v2.6.0-pre1", vers: "v2.6.0-pre1"},
{path: queryRepoV2, query: "latest", vers: "v2.5.5"}, {path: queryRepoV2, query: "latest", vers: "v2.5.5"},
// e0cf3de987e6 is the latest commit on the master branch, and it's actually // Commit e0cf3de987e6 is actually v1.19.10-pre1, not anything resembling v3,
// v1.19.10-pre1, not anything resembling v3: attempting to query it as such // and it has a go.mod file with a non-v3 module path. Attempting to query it
// should fail. // as the v3 module 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: "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`},
// The querytest repo does not have any commits tagged with major version 3,
// and the latest commit in the repo has a go.mod file specifying a non-v3 path.
// That should prevent us from resolving any version for the /v3 path.
{path: queryRepoV3, query: "latest", err: `no matching versions for query "latest"`}, {path: queryRepoV3, query: "latest", err: `no matching versions for query "latest"`},
{path: emptyRepo, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"}, {path: emptyRepo, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"},
......
...@@ -227,8 +227,8 @@ func (a *Action) trimpath() string { ...@@ -227,8 +227,8 @@ func (a *Action) trimpath() string {
// For "go build -trimpath", rewrite package source directory // For "go build -trimpath", rewrite package source directory
// to a file system-independent path (just the import path). // to a file system-independent path (just the import path).
if cfg.BuildTrimpath { if cfg.BuildTrimpath {
if m := a.Package.Module; m != nil { if m := a.Package.Module; m != nil && m.Version != "" {
rewrite += ";" + m.Dir + "=>" + m.Path + "@" + m.Version rewrite += ";" + a.Package.Dir + "=>" + m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path)
} else { } else {
rewrite += ";" + a.Package.Dir + "=>" + a.Package.ImportPath rewrite += ";" + a.Package.Dir + "=>" + a.Package.ImportPath
} }
......
package x
import _ "appengine"
import _ "nonexistent.rsc.io" // domain does not exist
package flag_test
import (
"flag"
"log"
"testing"
)
var v = flag.Int("v", 0, "v flag")
// Run this as go test pkg -v=7
func TestVFlagIsSet(t *testing.T) {
if *v != 7 {
log.Fatal("v flag not set")
}
}
package x // important! not an import comment
...@@ -40,7 +40,7 @@ Scripts also have access to these other environment variables: ...@@ -40,7 +40,7 @@ Scripts also have access to these other environment variables:
goversion=<current Go version; for example, 1.12> goversion=<current Go version; for example, 1.12>
:=<OS-specific path list separator> :=<OS-specific path list separator>
The scripts supporting files are unpacked relative to $GOPATH/src (aka $WORK/gopath/src) The scripts' supporting files are unpacked relative to $GOPATH/src (aka $WORK/gopath/src)
and then the script begins execution in that directory as well. Thus the example above runs and then the script begins execution in that directory as well. Thus the example above runs
in $WORK/gopath/src with GOPATH=$WORK/gopath and $WORK/gopath/src/hello.go in $WORK/gopath/src with GOPATH=$WORK/gopath and $WORK/gopath/src/hello.go
containing the listed contents. containing the listed contents.
......
...@@ -9,6 +9,13 @@ go clean -testcache ...@@ -9,6 +9,13 @@ go clean -testcache
go test x_test.go go test x_test.go
! stdout 'cached' ! stdout 'cached'
# golang.org/issue/29100: 'go clean -testcache' should succeed
# if the cache directory doesn't exist at all.
# It should not write a testexpire.txt file, since there are no
# test results that need to be invalidated in the first place.
env GOCACHE=$WORK/nonexistent
go clean -testcache
! exists $WORK/nonexistent
-- x/x_test.go -- -- x/x_test.go --
package x_test package x_test
...@@ -16,4 +23,4 @@ import ( ...@@ -16,4 +23,4 @@ import (
"testing" "testing"
) )
func TestMain(t *testing.T) { func TestMain(t *testing.T) {
} }
\ No newline at end of file
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
# See: https://github.com/golang/go/issues/8912 # See: https://github.com/golang/go/issues/8912
[linux] [ppc64] skip [linux] [ppc64] skip
# External linking is not supported on linux/riscv64.
# See: https://github.com/golang/go/issues/36739
[linux] [riscv64] skip
# External linking is not supported on darwin/386 (10.14+). # External linking is not supported on darwin/386 (10.14+).
# See: https://github.com/golang/go/issues/31751 # See: https://github.com/golang/go/issues/31751
[darwin] [386] skip [darwin] [386] skip
......
...@@ -33,7 +33,7 @@ grep 'rsc.io/quote v1.5.1$' go.mod ...@@ -33,7 +33,7 @@ grep 'rsc.io/quote v1.5.1$' go.mod
# 'go get all' should consider test dependencies with or without -t. # 'go get all' should consider test dependencies with or without -t.
cp go.mod.empty go.mod cp go.mod.empty go.mod
go get all go get -d all
grep 'rsc.io/quote v1.5.2$' go.mod grep 'rsc.io/quote v1.5.2$' go.mod
-- go.mod.empty -- -- go.mod.empty --
......
...@@ -75,12 +75,14 @@ go: example.com/badchain/a@v1.1.0 requires ...@@ -75,12 +75,14 @@ go: example.com/badchain/a@v1.1.0 requires
module declares its path as: badchain.example.com/c module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c but was required as: example.com/badchain/c
-- list-missing-expected -- -- list-missing-expected --
go: finding module for package example.com/badchain/c
go: found example.com/badchain/c in example.com/badchain/c v1.1.0 go: found example.com/badchain/c in example.com/badchain/c v1.1.0
go: m/use imports go: m/use imports
example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod:
module declares its path as: badchain.example.com/c module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c but was required as: example.com/badchain/c
-- list-missing-test-expected -- -- list-missing-test-expected --
go: finding module for package example.com/badchain/c
go: found example.com/badchain/c in example.com/badchain/c v1.1.0 go: found example.com/badchain/c in example.com/badchain/c v1.1.0
go: m/testuse tested by go: m/testuse tested by
m/testuse.test imports m/testuse.test imports
......
...@@ -34,6 +34,11 @@ go list all ...@@ -34,6 +34,11 @@ go list all
go clean -modcache go clean -modcache
go list all go list all
# -mod=readonly must not cause 'go list -m' to fail.
# (golang.org/issue/36478)
go list -m all
! stderr 'cannot query module'
# -mod=readonly should reject inconsistent go.mod files # -mod=readonly should reject inconsistent go.mod files
# (ones that would be rewritten). # (ones that would be rewritten).
go mod edit -require rsc.io/sampler@v1.2.0 go mod edit -require rsc.io/sampler@v1.2.0
......
...@@ -15,10 +15,28 @@ env GOSUMDB=off ...@@ -15,10 +15,28 @@ env GOSUMDB=off
# Replacing gopkg.in/[…].vN with a repository with a root go.mod file # Replacing gopkg.in/[…].vN with a repository with a root go.mod file
# specifying […].vN and a compatible version should succeed, even if # specifying […].vN and a compatible version should succeed, even if
# the replacement path is not a gopkg.in path. # the replacement path is not a gopkg.in path.
cd dot-to-dot cd 4-to-4
go list gopkg.in/src-d/go-git.v4 go list -m gopkg.in/src-d/go-git.v4
-- dot-to-dot/go.mod -- # Previous versions of the "go" command accepted v0 and v1 pseudo-versions
# as replacements for gopkg.in/[…].v4.
# As a special case, we continue to accept those.
cd ../4-to-0
go list -m gopkg.in/src-d/go-git.v4
cd ../4-to-1
go list -m gopkg.in/src-d/go-git.v4
cd ../4-to-incompatible
go list -m gopkg.in/src-d/go-git.v4
# A mismatched gopkg.in path should not be able to replace a different major version.
cd ../3-to-gomod-4
! go list -m gopkg.in/src-d/go-git.v3
stderr '^go: gopkg\.in/src-d/go-git\.v3@v3.0.0-20190801152248-0d1a009cbb60: invalid version: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$'
-- 4-to-4/go.mod --
module golang.org/issue/34254 module golang.org/issue/34254
go 1.13 go 1.13
...@@ -26,3 +44,36 @@ go 1.13 ...@@ -26,3 +44,36 @@ go 1.13
require gopkg.in/src-d/go-git.v4 v4.13.1 require gopkg.in/src-d/go-git.v4 v4.13.1
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1 replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1
-- 4-to-1/go.mod --
module golang.org/issue/34254
go 1.13
require gopkg.in/src-d/go-git.v4 v4.13.1
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v1.0.1-0.20190801152248-0d1a009cbb60
-- 4-to-0/go.mod --
module golang.org/issue/34254
go 1.13
require gopkg.in/src-d/go-git.v4 v4.13.1
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v0.0.0-20190801152248-0d1a009cbb60
-- 4-to-incompatible/go.mod --
module golang.org/issue/34254
go 1.13
require gopkg.in/src-d/go-git.v4 v4.13.1
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v4.6.0+incompatible
-- 3-to-gomod-4/go.mod --
module golang.org/issue/34254
go 1.13
require gopkg.in/src-d/go-git.v3 v3.2.0
// This replacement has a go.mod file declaring its path to be
// gopkg.in/src-d/go-git.v4, so it cannot be used as a replacement for v3.
replace gopkg.in/src-d/go-git.v3 v3.2.0 => gopkg.in/src-d/go-git.v3 v3.0.0-20190801152248-0d1a009cbb60
...@@ -28,7 +28,8 @@ stdout 'example.com/v v1.12.0 => ./v12' ...@@ -28,7 +28,8 @@ stdout 'example.com/v v1.12.0 => ./v12'
cd fail cd fail
! go list all ! go list all
stdout 'localhost.fail' stdout 'localhost.fail'
stderr '^can.t load package: m.go:3:8: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' stderr '^can''t load package: m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$'
stderr '^can''t load package: m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$'
-- go.mod -- -- go.mod --
module example.com/m module example.com/m
...@@ -54,6 +55,10 @@ replace ( ...@@ -54,6 +55,10 @@ replace (
example.com/v => ./v example.com/v => ./v
) )
replace (
example.com/i v2.0.0+incompatible => ./i2
)
-- m.go -- -- m.go --
package main package main
import ( import (
...@@ -61,6 +66,7 @@ import ( ...@@ -61,6 +66,7 @@ import (
_ "example.com/x/v3" _ "example.com/x/v3"
_ "example.com/y/z/w" _ "example.com/y/z/w"
_ "example.com/v" _ "example.com/v"
_ "example.com/i"
) )
func main() {} func main() {}
...@@ -115,10 +121,18 @@ module v.localhost ...@@ -115,10 +121,18 @@ module v.localhost
-- v/v.go -- -- v/v.go --
package v package v
-- i2/go.mod --
module example.com/i
-- i2/i.go --
package i
-- fail/m.go -- -- fail/m.go --
package main package main
import _ "w" import (
_ "w"
_ "nonexist"
)
func main() {} func main() {}
...@@ -127,3 +141,4 @@ module localhost.fail ...@@ -127,3 +141,4 @@ module localhost.fail
replace w => ../w replace w => ../w
replace nonexist v0.1.0 => ../nonexist
env GO111MODULE=on
go list -e -f '{{.Incomplete}}' runbad1.go
stdout true
! go run runbad1.go
stderr 'use of internal package m/x/internal not allowed'
go list -e -f '{{.Incomplete}}' runbad2.go
stdout true
! go run runbad2.go
stderr 'use of internal package m/x/internal/y not allowed'
go list -e -f '{{.Incomplete}}' runok.go
stdout false
go run runok.go
-- go.mod --
module m
-- x/internal/internal.go --
package internal
-- x/internal/y/y.go --
package y
-- internal/internal.go --
package internal
-- internal/z/z.go --
package z
-- runbad1.go --
package main
import _ "m/x/internal"
func main() {}
-- runbad2.go --
package main
import _ "m/x/internal/y"
func main() {}
-- runok.go --
package main
import _ "m/internal"
import _ "m/internal/z"
func main() {}
...@@ -38,6 +38,12 @@ stdout 'src[\\/]vendor[\\/]x' ...@@ -38,6 +38,12 @@ stdout 'src[\\/]vendor[\\/]x'
go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m x go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m x
stdout '^v1.0.0 $' stdout '^v1.0.0 $'
# -mod=vendor should cause 'go list' flags that look up versions to fail.
! go list -mod=vendor -versions -m x
stderr '^go list -m: can''t determine available versions using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)$'
! go list -mod=vendor -u -m x
stderr '^go list -m: can''t determine available upgrades using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)$'
# 'go list -mod=vendor -m' on a transitive dependency that does not # 'go list -mod=vendor -m' on a transitive dependency that does not
# provide vendored packages should give a helpful error rather than # provide vendored packages should give a helpful error rather than
# 'not a known dependency'. # 'not a known dependency'.
......
...@@ -11,6 +11,15 @@ cp go.sum go.sum.orig ...@@ -11,6 +11,15 @@ cp go.sum go.sum.orig
go mod init example.com/m go mod init example.com/m
grep example.com/m go.alt.mod grep example.com/m go.alt.mod
# 'go env GOMOD' should print the path to the real file.
# 'go env' does not recognize the '-modfile' flag.
go env GOMOD
stdout '^\$WORK[/\\]gopath[/\\]src[/\\]go.mod$'
# 'go list -m' should print the effective go.mod file as GoMod though.
go list -m -f '{{.GoMod}}'
stdout '^go.alt.mod$'
# go mod edit should operate on the alternate file # go mod edit should operate on the alternate file
go mod edit -require rsc.io/quote@v1.5.2 go mod edit -require rsc.io/quote@v1.5.2
grep rsc.io/quote go.alt.mod grep rsc.io/quote go.alt.mod
......
env GO111MODULE=off env GO111MODULE=off
! go test badtest/... ! go test badtest/badexec
! stdout ^ok ! stdout ^ok
stdout ^FAIL\tbadtest/badexec stdout ^FAIL\tbadtest/badexec
! go test badtest/badsyntax
! stdout ^ok
stdout ^FAIL\tbadtest/badsyntax stdout ^FAIL\tbadtest/badsyntax
! go test badtest/badvar
! stdout ^ok
stdout ^FAIL\tbadtest/badvar stdout ^FAIL\tbadtest/badvar
! go test notest
! stdout ^ok
stderr '^notest.hello.go:6:1: .*declaration' # Exercise issue #7108
-- badtest/badexec/x_test.go -- -- badtest/badexec/x_test.go --
package badexec package badexec
...@@ -30,3 +40,10 @@ package badvar_test ...@@ -30,3 +40,10 @@ package badvar_test
func f() { func f() {
_ = notdefined _ = notdefined
} }
-- notest/hello.go --
package notest
func hello() {
println("hello world")
}
Hello world
package bench
import "testing"
func Benchmark(b *testing.B) {
}
package benchfatal
import "testing"
func BenchmarkThatCallsFatal(b *testing.B) {
b.Fatal("called by benchmark")
}
package p
/*
// hi
*/
import "C"
func F() {}
package p
/*
void
f(void)
{
}
*/
import "C"
var b bool
func F() {
if b {
for {
}
}
C.f()
}
package p
import "testing"
func TestF(t *testing.T) {
F()
}
package p
/*
void
f(void)
{
}
*/
import "C"
var b bool
func F() {
if b {
for {
}
}
C.f()
}
package p_test
import (
. "cgocover2"
"testing"
)
func TestF(t *testing.T) {
F()
}
package p
/*
void
f(void)
{
}
*/
import "C"
var b bool
func F() {
if b {
for {
}
}
C.f()
}
package p_test
import (
. "cgocover3"
"testing"
)
func TestF(t *testing.T) {
F()
}
package p
/*
void
f(void)
{
}
*/
import "C"
var b bool
func F() {
if b {
for {
}
}
C.f()
}
package p_test
import (
. "cgocover4"
"testing"
)
func TestF(t *testing.T) {
F()
}
package main
import (
_ "dupload/p2"
_ "p"
)
func main() {}
package p2
import _ "dupload/vendor/p"
//go:generate echo hello world
package gencycle
import _ "gencycle"
package main
import _ "importmain/test"
func main() {}
package test_test
import "testing"
import _ "importmain/ismain"
func TestCase(t *testing.T) {}
package multimain_test
import "testing"
func TestMain(m *testing.M) {
// Some users run m.Run multiple times, changing
// some kind of global state between runs.
// This used to work so I guess now it has to keep working.
// See golang.org/issue/23129.
m.Run()
m.Run()
}
func Test(t *testing.T) {
t.Log("notwithstanding")
}
package notest
func hello() {
println("hello world")
}
Hello world
package main
import _ "run/subdir/internal/private"
func main() {}
package main
import _ "run/internal"
func main() {}
package p
import (
"testing"
"time"
)
func Test1(t *testing.T) {
time.Sleep(200 * time.Millisecond)
}
package p
import (
"testing"
"time"
)
func Test1(t *testing.T) {
time.Sleep(200 * time.Millisecond)
}
package p
// missing import
var _ = io.DoesNotExist
package p1
import _ "testcycle/p2"
func init() {
println("p1 init")
}
package p1
import "testing"
func Test(t *testing.T) {
}
package p2
import _ "testcycle/p3"
func init() {
println("p2 init")
}
package p3
func init() {
println("p3 init")
}
package p3
import (
"testing"
_ "testcycle/p1"
)
func Test(t *testing.T) {
}
package q1
import "testing"
import _ "testcycle/q1"
func Test(t *testing.T) {}
package p
func init() {
panic("go test must not link and run test binaries without tests")
}
package testrace
import "testing"
func TestRace(t *testing.T) {
for i := 0; i < 10; i++ {
c := make(chan int)
x := 1
go func() {
x = 2
c <- 1
}()
x = 3
<-c
_ = x
}
}
func BenchmarkRace(b *testing.B) {
for i := 0; i < b.N; i++ {
c := make(chan int)
x := 1
go func() {
x = 2
c <- 1
}()
x = 3
<-c
_ = x
}
}
package x
import "testing"
func TestX(t *testing.T) {
t.Logf("LOG: X running")
t.Run("Y", func(t *testing.T) {
t.Logf("LOG: Y running")
})
}
func BenchmarkX(b *testing.B) {
b.Logf("LOG: X running N=%d", b.N)
b.Run("Y", func(b *testing.B) {
b.Logf("LOG: Y running N=%d", b.N)
})
}
package x
import "testing"
func TestZ(t *testing.T) {
t.Logf("LOG: Z running")
}
func TestXX(t *testing.T) {
t.Logf("LOG: XX running")
}
func BenchmarkZ(b *testing.B) {
b.Logf("LOG: Z running N=%d", b.N)
}
func BenchmarkXX(b *testing.B) {
b.Logf("LOG: XX running N=%d", b.N)
}
...@@ -116,9 +116,10 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (* ...@@ -116,9 +116,10 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*
if timeout != 0 { if timeout != 0 {
errChannel = make(chan error, 2) errChannel = make(chan error, 2)
time.AfterFunc(timeout, func() { timer := time.AfterFunc(timeout, func() {
errChannel <- timeoutError{} errChannel <- timeoutError{}
}) })
defer timer.Stop()
} }
rawConn, err := dialer.Dial(network, addr) rawConn, err := dialer.Dial(network, addr)
......
...@@ -159,7 +159,7 @@ static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) { ...@@ -159,7 +159,7 @@ static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) {
// //
// Note: The CFDataRef returned in pemRoots and untrustedPemRoots must // Note: The CFDataRef returned in pemRoots and untrustedPemRoots must
// be released (using CFRelease) after we've consumed its content. // be released (using CFRelease) after we've consumed its content.
int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) { static int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) {
int i; int i;
if (debugDarwinRoots) { if (debugDarwinRoots) {
......
...@@ -219,10 +219,26 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate ...@@ -219,10 +219,26 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(chain) < 1 {
return nil, errors.New("x509: internal error: system verifier returned an empty chain")
}
chains = append(chains, chain) // Mitigate CVE-2020-0601, where the Windows system verifier might be
// tricked into using custom curve parameters for a trusted root, by
// double-checking all ECDSA signatures. If the system was tricked into
// using spoofed parameters, the signature will be invalid for the correct
// ones we parsed. (We don't support custom curves ourselves.)
for i, parent := range chain[1:] {
if parent.PublicKeyAlgorithm != ECDSA {
continue
}
if err := parent.CheckSignature(chain[i].SignatureAlgorithm,
chain[i].RawTBSCertificate, chain[i].Signature); err != nil {
return nil, err
}
}
return chains, nil return [][]*Certificate{chain}, nil
} }
func loadSystemRoots() (*CertPool, error) { func loadSystemRoots() (*CertPool, error) {
......
...@@ -629,7 +629,8 @@ func TestPoolExhaustOnCancel(t *testing.T) { ...@@ -629,7 +629,8 @@ func TestPoolExhaustOnCancel(t *testing.T) {
go func() { go func() {
rows, err := db.Query("SELECT|people|name,photo|") rows, err := db.Query("SELECT|people|name,photo|")
if err != nil { if err != nil {
t.Fatalf("Query: %v", err) t.Errorf("Query: %v", err)
return
} }
rows.Close() rows.Close()
saturateDone.Done() saturateDone.Done()
...@@ -637,6 +638,9 @@ func TestPoolExhaustOnCancel(t *testing.T) { ...@@ -637,6 +638,9 @@ func TestPoolExhaustOnCancel(t *testing.T) {
} }
saturate.Wait() saturate.Wait()
if t.Failed() {
t.FailNow()
}
state = 2 state = 2
// Now cancel the request while it is waiting. // Now cancel the request while it is waiting.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment