"os"
"path/filepath"
"strings"
+ "time"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"golang.org/x/mod/semver"
)
-var QuietLookup bool // do not print about lookups
-
var PkgMod string // $GOPATH/pkg/mod; set by package modload
+const logFindingDelay = 1 * time.Second
+
func cacheDir(path string) (string, error) {
if PkgMod == "" {
return "", fmt.Errorf("internal error: modfetch.PkgMod not set")
err error
}
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)
return cached{list, err}
}).(cached)
return cachedInfo{info, nil}
}
- if !QuietLookup {
+ 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)
if err == nil {
// If we resolved, say, 1234abcde to v0.0.0-20180604122334-1234abcdef78,
func (r *cachingRepo) Latest() (*RevInfo, error) {
c := r.cache.Do("latest:", func() interface{} {
- if !QuietLookup {
+ logTimer := time.AfterFunc(logFindingDelay, func() {
fmt.Fprintf(os.Stderr, "go: finding %s latest\n", r.path)
- }
+ })
+ defer logTimer.Stop()
+
info, err := r.r.Latest()
// Save info for likely future Stat call.
return err
}
- if cfg.CmdName != "mod download" {
- fmt.Fprintf(os.Stderr, "go: extracting %s %s\n", mod.Path, mod.Version)
- }
-
unlock, err := lockVersion(mod)
if err != nil {
return err
continue
default:
- // The argument is a package path.
+ // The argument is a package or module path.
if pkgs := modload.TargetPackages(path); len(pkgs) != 0 {
// The path is in the main module. Nothing to query.
if vers != "upgrade" && vers != "patch" {
info, err := modload.Query(path, vers, prevM.Version, modload.Allowed)
if err == nil {
+ if info.Version != vers && info.Version != prevM.Version {
+ logOncef("go: %s %s => %s", path, vers, info.Version)
+ }
return module.Version{Path: path, Version: info.Version}, nil
}
if !strings.Contains(path, "...") {
var modErr *modload.PackageNotInModuleError
if errors.As(err, &modErr) && modErr.Mod.Path == path {
+ if modErr.Mod.Version != vers {
+ logOncef("go: %s %s => %s", path, vers, modErr.Mod.Version)
+ }
return modErr.Mod, nil
}
}
return module.Version{}, err
}
- return results[0].Mod, nil
+ m := results[0].Mod
+ if m.Path != path {
+ logOncef("go: found %s in %s %s", path, m.Path, m.Version)
+ } else if m.Version != vers {
+ logOncef("go: %s %s => %s", path, vers, m.Version)
+ }
+ return m, nil
}
// An upgrader adapts an underlying mvs.Reqs to apply an
return m, nil
}
+ if info.Version != m.Version {
+ logOncef("go: %s %s => %s", m.Path, getU, info.Version)
+ }
return module.Version{Path: m.Path, Version: info.Version}, nil
}
}
return r.Reqs.Required(mod)
}
+
+var loggedLines sync.Map
+
+func logOncef(format string, args ...interface{}) {
+ msg := fmt.Sprintf(format, args...)
+ if _, dup := loggedLines.LoadOrStore(msg, true); !dup {
+ fmt.Fprintln(os.Stderr, msg)
+ }
+}
added[pkg.path] = true
numAdded++
if !haveMod[err.Module] {
+ fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version)
haveMod[err.Module] = true
modAddedBy[err.Module] = pkg
buildList = append(buildList, err.Module)
"strings"
"sync"
+ "cmd/go/internal/cfg"
"cmd/go/internal/imports"
"cmd/go/internal/modfetch"
"cmd/go/internal/search"
return info, err
}
+var errQueryDisabled error = queryDisabledError{}
+
+type queryDisabledError struct{}
+
+func (queryDisabledError) Error() string {
+ if cfg.BuildModReason == "" {
+ return fmt.Sprintf("cannot query module due to -mod=%s", cfg.BuildMod)
+ }
+ return fmt.Sprintf("cannot query module due to -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
+}
+
func queryProxy(proxy, path, query, current string, allowed func(module.Version) bool) (*modfetch.RevInfo, error) {
if current != "" && !semver.IsValid(current) {
return nil, fmt.Errorf("invalid previous version %q", current)
}
+ if cfg.BuildMod != "" && cfg.BuildMod != "mod" {
+ return nil, errQueryDisabled
+ }
if allowed == nil {
allowed = func(module.Version) bool { return true }
}
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)
stdout '^golang.org/x/text v0.0.0.* .*vendor[\\/]golang.org[\\/]x[\\/]text[\\/]language$'
! go list -mod=vendor -m rsc.io/quote@latest
-stderr 'go list -m: rsc.io/quote@latest: module lookup disabled by -mod=vendor'
+stderr 'go list -m: rsc.io/quote@latest: cannot query module due to -mod=vendor'
! go get -mod=vendor -u
stderr 'flag provided but not defined: -mod'
func Test(t *testing.T) {}
-- update-main-expected --
+go: example.com/badchain/c upgrade => v1.1.0
go get: example.com/badchain/c@v1.0.0 updating to
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: example.com/badchain/a upgrade => v1.1.0
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:
module declares its path as: badchain.example.com/c
but was required as: example.com/badchain/c
-- list-missing-expected --
+go: found example.com/badchain/c in example.com/badchain/c v1.1.0
go: m/use imports
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: found example.com/badchain/c in example.com/badchain/c v1.1.0
go: m/testuse tested by
m/testuse.test imports
example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: