From 426ef30ecf2d2b6eadd962358884ed68220b9cc5 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 19 Aug 2025 15:27:39 -0400 Subject: [PATCH] cmd/go: implement -reuse for Mercurial repos When we added -reuse in CL 411398, we only handled Git repos. This was partly because we were focused on Git traffic, partly because Git is the dominant module VCS, and partly because I couldn't see how to retrieve the metadata needed in other version control systems. This CL adds -reuse support for Mercurial, the second most popular VCS for modules, now that I see how to implement it. Although the Mercurial command line does not have sufficient information, the Mercurial Python API does, so we ship and invoke a Mercurial extension written in Python that can compute a hash of the remote repo without downloading it entirely, as well as resolve a remote name to a hash or check the continued existence of a hash. Then we can avoid downloading the repo at all if it hasn't changed since the last check or if the specific reference we need still resolves or exists. Fixes #75119. Change-Id: Ia47d89b15c1091c44efef9d325270fc400a412c4 Reviewed-on: https://go-review.googlesource.com/c/go/+/718382 Auto-Submit: Russ Cox Reviewed-by: Michael Matloob Reviewed-by: Michael Matloob LUCI-TryBot-Result: Go LUCI --- lib/hg/goreposum.py | 64 +++++ src/cmd/go/internal/modfetch/cache.go | 3 +- .../go/internal/modfetch/codehost/codehost.go | 9 +- .../go/internal/modfetch/codehost/git_test.go | 1 + src/cmd/go/internal/modfetch/codehost/vcs.go | 192 ++++++++++--- src/cmd/go/internal/modfetch/coderepo.go | 3 + src/cmd/go/internal/modload/build.go | 6 + src/cmd/go/internal/vcweb/vcweb.go | 6 +- src/cmd/go/testdata/script/reuse_git.txt | 5 +- src/cmd/go/testdata/script/reuse_hg.txt | 271 +++++++++--------- .../go/testdata/vcstest/hg/prefixtagtests.txt | 67 +++-- src/cmd/go/testdata/vcstest/hg/tagtests.txt | 54 ++-- 12 files changed, 433 insertions(+), 248 deletions(-) create mode 100644 lib/hg/goreposum.py diff --git a/lib/hg/goreposum.py b/lib/hg/goreposum.py new file mode 100644 index 00000000000..1a7d7a44466 --- /dev/null +++ b/lib/hg/goreposum.py @@ -0,0 +1,64 @@ +# Copyright 2025 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. + +# Mercurial extension to add a 'goreposum' command that +# computes a hash of a remote repo's tag state. +# Tag definitions can come from the .hgtags file stored in +# any head of any branch, and the server protocol does not +# expose the tags directly. However, the protocol does expose +# the hashes of all the branch heads, so we can use a hash of +# all those branch names and heads as a conservative snapshot +# of the entire remote repo state, and use that as the tag sum. +# Any change on the server then invalidates the tag sum, +# even if it didn't have anything to do with tags, but at least +# we will avoid re-cloning a server when there have been no +# changes at all. +# +# Separately, this extension also adds a 'golookup' command that +# returns the hash of a specific reference, like 'default' or a tag. +# And golookup of a hash confirms that it still exists on the server. +# We can use that to revalidate that specific versions still exist and +# have the same meaning they did the last time we checked. +# +# Usage: +# +# hg --config "extensions.goreposum=$GOROOT/lib/hg/goreposum.py" goreposum REPOURL + +import base64, hashlib, sys +from mercurial import registrar, ui, hg, node +from mercurial.i18n import _ +cmdtable = {} +command = registrar.command(cmdtable) +@command(b'goreposum', [], _('url'), norepo=True) +def goreposum(ui, url): + """ + goreposum computes a checksum of all the named state in the remote repo. + It hashes together all the branch names and hashes + and then all the bookmark names and hashes. + Tags are stored in .hgtags files in any of the branches, + so the branch metadata includes the tags as well. + """ + h = hashlib.sha256() + peer = hg.peer(ui, {}, url) + for name, revs in peer.branchmap().items(): + h.update(name) + for r in revs: + h.update(b' ') + h.update(r) + h.update(b'\n') + if (b'bookmarks' in peer.listkeys(b'namespaces')): + for name, rev in peer.listkeys(b'bookmarks').items(): + h.update(name) + h.update(b'=') + h.update(rev) + h.update(b'\n') + print('r1:'+base64.standard_b64encode(h.digest()).decode('utf-8')) + +@command(b'golookup', [], _('url rev'), norepo=True) +def golookup(ui, url, rev): + """ + golookup looks up a single identifier in the repo, + printing its hash. + """ + print(node.hex(hg.peer(ui, {}, url).lookup(rev)).decode('utf-8')) diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go index 9c34581a910..30020d24a71 100644 --- a/src/cmd/go/internal/modfetch/cache.go +++ b/src/cmd/go/internal/modfetch/cache.go @@ -622,10 +622,11 @@ func writeDiskStat(ctx context.Context, file string, info *RevInfo) error { o := *info.Origin info.Origin = &o - // Tags never matter if you are starting with a semver version, + // Tags and RepoSum never matter if you are starting with a semver version, // as we would be when finding this cache entry. o.TagSum = "" o.TagPrefix = "" + o.RepoSum = "" // Ref doesn't matter if you have a pseudoversion. if module.IsPseudoVersion(info.Version) { o.Ref = "" diff --git a/src/cmd/go/internal/modfetch/codehost/codehost.go b/src/cmd/go/internal/modfetch/codehost/codehost.go index edb87e40891..08b1216d6bf 100644 --- a/src/cmd/go/internal/modfetch/codehost/codehost.go +++ b/src/cmd/go/internal/modfetch/codehost/codehost.go @@ -116,9 +116,12 @@ type Origin struct { Ref string `json:",omitempty"` // If RepoSum is non-empty, then the resolution of this module version - // failed due to the repo being available but the version not being present. - // This depends on the entire state of the repo, which RepoSum summarizes. - // For Git, this is a hash of all the refs and their hashes. + // depends on the entire state of the repo, which RepoSum summarizes. + // For Git, this is a hash of all the refs and their hashes, and the RepoSum + // is only needed for module versions that don't exist. + // For Mercurial, this is a hash of all the branches and their heads' hashes, + // since the set of available tags is dervied from .hgtags files in those branches, + // and the RepoSum is used for all module versions, available and not, RepoSum string `json:",omitempty"` } diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go index 68b0d161a09..e032a14e124 100644 --- a/src/cmd/go/internal/modfetch/codehost/git_test.go +++ b/src/cmd/go/internal/modfetch/codehost/git_test.go @@ -383,6 +383,7 @@ func TestLatest(t *testing.T) { Origin: &Origin{ VCS: "hg", URL: hgrepo1, + Ref: "tip", Hash: "745aacc8b24decc44ac2b13870f5472b479f4d72", }, Name: "745aacc8b24decc44ac2b13870f5472b479f4d72", diff --git a/src/cmd/go/internal/modfetch/codehost/vcs.go b/src/cmd/go/internal/modfetch/codehost/vcs.go index d80397502b4..a73f882ccc6 100644 --- a/src/cmd/go/internal/modfetch/codehost/vcs.go +++ b/src/cmd/go/internal/modfetch/codehost/vcs.go @@ -17,9 +17,11 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" "cmd/go/internal/base" + "cmd/go/internal/cfg" "cmd/go/internal/lockedfile" "cmd/go/internal/str" "cmd/internal/par" @@ -80,6 +82,10 @@ type vcsRepo struct { fetchOnce sync.Once fetchErr error + fetched atomic.Bool + + repoSumOnce sync.Once + repoSum string } func newVCSRepo(ctx context.Context, vcs, remote string, local bool) (Repo, error) { @@ -129,6 +135,9 @@ func newVCSRepo(ctx context.Context, vcs, remote string, local bool) (Repo, erro return nil, err } _, err = Run(ctx, r.dir, cmd.init(r.remote)) + if err == nil && cmd.postInit != nil { + err = cmd.postInit(ctx, r) + } release() if err != nil { @@ -142,20 +151,27 @@ func newVCSRepo(ctx context.Context, vcs, remote string, local bool) (Repo, erro const vcsWorkDirType = "vcs1." type vcsCmd struct { - vcs string // vcs name "hg" - init func(remote string) []string // cmd to init repo to track remote - tags func(remote string) []string // cmd to list local tags - tagRE *lazyregexp.Regexp // regexp to extract tag names from output of tags cmd - branches func(remote string) []string // cmd to list local branches - branchRE *lazyregexp.Regexp // regexp to extract branch names from output of tags cmd - badLocalRevRE *lazyregexp.Regexp // regexp of names that must not be served out of local cache without doing fetch first - statLocal func(rev, remote string) []string // cmd to stat local rev - parseStat func(rev, out string) (*RevInfo, error) // cmd to parse output of statLocal - fetch []string // cmd to fetch everything from remote - latest string // name of latest commit on remote (tip, HEAD, etc) - readFile func(rev, file, remote string) []string // cmd to read rev's file - readZip func(rev, subdir, remote, target string) []string // cmd to read rev's subdir as zip file - doReadZip func(ctx context.Context, dst io.Writer, workDir, rev, subdir, remote string) error // arbitrary function to read rev's subdir as zip file + vcs string // vcs name "hg" + init func(remote string) []string // cmd to init repo to track remote + postInit func(context.Context, *vcsRepo) error // func to init repo after .init runs + repoSum func(remote string) []string // cmd to calculate reposum of remote repo + lookupRef func(remote, ref string) []string // cmd to look up ref in remote repo + tags func(remote string) []string // cmd to list local tags + tagsNeedsFetch bool // run fetch before tags + tagRE *lazyregexp.Regexp // regexp to extract tag names from output of tags cmd + branches func(remote string) []string // cmd to list local branches + branchesNeedsFetch bool // run branches before tags + branchRE *lazyregexp.Regexp // regexp to extract branch names from output of tags cmd + badLocalRevRE *lazyregexp.Regexp // regexp of names that must not be served out of local cache without doing fetch first + statLocal func(rev, remote string) []string // cmd to stat local rev + parseStat func(rev, out string) (*RevInfo, error) // func to parse output of statLocal + fetch []string // cmd to fetch everything from remote + latest string // name of latest commit on remote (tip, HEAD, etc) + readFile func(rev, file, remote string) []string // cmd to read rev's file + readZip func(rev, subdir, remote, target string) []string // cmd to read rev's subdir as zip file + + // arbitrary function to read rev's subdir as zip file + doReadZip func(ctx context.Context, dst io.Writer, workDir, rev, subdir, remote string) error } var re = lazyregexp.New @@ -163,18 +179,38 @@ var re = lazyregexp.New var vcsCmds = map[string]*vcsCmd{ "hg": { vcs: "hg", - init: func(remote string) []string { - return []string{"hg", "clone", "-U", "--", remote, "."} + repoSum: func(remote string) []string { + return []string{ + "hg", + "--config=extensions.goreposum=" + filepath.Join(cfg.GOROOT, "lib/hg/goreposum.py"), + "goreposum", + remote, + } }, + lookupRef: func(remote, ref string) []string { + return []string{ + "hg", + "--config=extensions.goreposum=" + filepath.Join(cfg.GOROOT, "lib/hg/goreposum.py"), + "golookup", + remote, + ref, + } + }, + init: func(remote string) []string { + return []string{"hg", "init", "."} + }, + postInit: hgAddRemote, tags: func(remote string) []string { return []string{"hg", "tags", "-q"} }, - tagRE: re(`(?m)^[^\n]+$`), + tagsNeedsFetch: true, + tagRE: re(`(?m)^[^\n]+$`), branches: func(remote string) []string { return []string{"hg", "branches", "-c", "-q"} }, - branchRE: re(`(?m)^[^\n]+$`), - badLocalRevRE: re(`(?m)^(tip)$`), + branchesNeedsFetch: true, + branchRE: re(`(?m)^[^\n]+$`), + badLocalRevRE: re(`(?m)^(tip)$`), statLocal: func(rev, remote string) []string { return []string{"hg", "log", "-l1", "-r", rev, "--template", "{node} {date|hgdate} {tags}"} }, @@ -276,6 +312,10 @@ var vcsCmds = map[string]*vcsCmd{ } func (r *vcsRepo) loadTags(ctx context.Context) { + if r.cmd.tagsNeedsFetch { + r.fetchOnce.Do(func() { r.fetch(ctx) }) + } + out, err := Run(ctx, r.dir, r.cmd.tags(r.remote)) if err != nil { return @@ -296,6 +336,10 @@ func (r *vcsRepo) loadBranches(ctx context.Context) { return } + if r.cmd.branchesNeedsFetch { + r.fetchOnce.Do(func() { r.fetch(ctx) }) + } + out, err := Run(ctx, r.dir, r.cmd.branches(r.remote)) if err != nil { return @@ -310,7 +354,84 @@ func (r *vcsRepo) loadBranches(ctx context.Context) { } } +func (r *vcsRepo) loadRepoSum(ctx context.Context) { + if r.cmd.repoSum == nil { + return + } + where := r.remote + if r.fetched.Load() { + where = "." // use local repo + } + out, err := Run(ctx, r.dir, r.cmd.repoSum(where)) + if err != nil { + return + } + r.repoSum = strings.TrimSpace(string(out)) +} + +func (r *vcsRepo) lookupRef(ctx context.Context, ref string) (string, error) { + if r.cmd.lookupRef == nil { + return "", fmt.Errorf("no lookupRef") + } + out, err := Run(ctx, r.dir, r.cmd.lookupRef(r.remote, ref)) + if err != nil { + return "", err + } + return strings.TrimSpace(string(out)), nil +} + +// repoSumOrigin returns an Origin containing a RepoSum. +func (r *vcsRepo) repoSumOrigin(ctx context.Context) *Origin { + origin := &Origin{ + VCS: r.cmd.vcs, + URL: r.remote, + RepoSum: r.repoSum, + } + r.repoSumOnce.Do(func() { r.loadRepoSum(ctx) }) + origin.RepoSum = r.repoSum + return origin +} + func (r *vcsRepo) CheckReuse(ctx context.Context, old *Origin, subdir string) error { + if old == nil { + return fmt.Errorf("missing origin") + } + if old.VCS != r.cmd.vcs || old.URL != r.remote { + return fmt.Errorf("origin moved from %v %q to %v %q", old.VCS, old.URL, r.cmd.vcs, r.remote) + } + if old.Subdir != subdir { + return fmt.Errorf("origin moved from %v %q %q to %v %q %q", old.VCS, old.URL, old.Subdir, r.cmd.vcs, r.remote, subdir) + } + + if old.Ref == "" && old.RepoSum == "" && old.Hash != "" { + // Hash has to remain in repo. + hash, err := r.lookupRef(ctx, old.Hash) + if err == nil && hash == old.Hash { + return nil + } + if err != nil { + return fmt.Errorf("looking up hash: %v", err) + } + return fmt.Errorf("hash changed") // weird but maybe they made a tag + } + + if old.Ref != "" && old.RepoSum == "" { + hash, err := r.lookupRef(ctx, old.Ref) + if err == nil && hash != "" && hash == old.Hash { + return nil + } + } + + r.repoSumOnce.Do(func() { r.loadRepoSum(ctx) }) + if r.repoSum != "" { + if old.RepoSum == "" { + return fmt.Errorf("non-specific origin") + } + if old.RepoSum != r.repoSum { + return fmt.Errorf("repo changed") + } + return nil + } return fmt.Errorf("vcs %s: CheckReuse: %w", r.cmd.vcs, errors.ErrUnsupported) } @@ -323,14 +444,8 @@ func (r *vcsRepo) Tags(ctx context.Context, prefix string) (*Tags, error) { r.tagsOnce.Do(func() { r.loadTags(ctx) }) tags := &Tags{ - // None of the other VCS provide a reasonable way to compute TagSum - // without downloading the whole repo, so we only include VCS and URL - // in the Origin. - Origin: &Origin{ - VCS: r.cmd.vcs, - URL: r.remote, - }, - List: []Tag{}, + Origin: r.repoSumOrigin(ctx), + List: []Tag{}, } for tag := range r.tags { if strings.HasPrefix(tag, prefix) { @@ -372,7 +487,7 @@ func (r *vcsRepo) Stat(ctx context.Context, rev string) (*RevInfo, error) { } info, err := r.statLocal(ctx, rev) if err != nil { - return nil, err + return info, err } if !revOK { info.Version = info.Name @@ -389,13 +504,15 @@ func (r *vcsRepo) fetch(ctx context.Context) { } _, r.fetchErr = Run(ctx, r.dir, r.cmd.fetch) release() + r.fetched.Store(true) } } func (r *vcsRepo) statLocal(ctx context.Context, rev string) (*RevInfo, error) { out, err := Run(ctx, r.dir, r.cmd.statLocal(rev, r.remote)) if err != nil { - return nil, &UnknownRevisionError{Rev: rev} + info := &RevInfo{Origin: r.repoSumOrigin(ctx)} + return info, &UnknownRevisionError{Rev: rev} } info, err := r.cmd.parseStat(rev, string(out)) if err != nil { @@ -406,6 +523,10 @@ func (r *vcsRepo) statLocal(ctx context.Context, rev string) (*RevInfo, error) { } info.Origin.VCS = r.cmd.vcs info.Origin.URL = r.remote + info.Origin.Ref = rev + if strings.HasPrefix(info.Name, rev) && len(rev) >= 12 { + info.Origin.Ref = "" // duplicates Hash + } return info, nil } @@ -521,6 +642,11 @@ func (d *deleteCloser) Close() error { return d.File.Close() } +func hgAddRemote(ctx context.Context, r *vcsRepo) error { + // Write .hg/hgrc with remote URL in it. + return os.WriteFile(filepath.Join(r.dir, ".hg/hgrc"), []byte(fmt.Sprintf("[paths]\ndefault = %s\n", r.remote)), 0666) +} + func hgParseStat(rev, out string) (*RevInfo, error) { f := strings.Fields(out) if len(f) < 3 { @@ -545,9 +671,7 @@ func hgParseStat(rev, out string) (*RevInfo, error) { sort.Strings(tags) info := &RevInfo{ - Origin: &Origin{ - Hash: hash, - }, + Origin: &Origin{Hash: hash}, Name: hash, Short: ShortenSHA1(hash), Time: time.Unix(t, 0).UTC(), @@ -630,9 +754,7 @@ func fossilParseStat(rev, out string) (*RevInfo, error) { version = hash // extend to full hash } info := &RevInfo{ - Origin: &Origin{ - Hash: hash, - }, + Origin: &Origin{Hash: hash}, Name: hash, Short: ShortenSHA1(hash), Time: t, diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go index 3df469d2852..7cec96a3070 100644 --- a/src/cmd/go/internal/modfetch/coderepo.go +++ b/src/cmd/go/internal/modfetch/coderepo.go @@ -384,6 +384,9 @@ func (r *codeRepo) convert(ctx context.Context, info *codehost.RevInfo, statVers } else { origin.TagPrefix = tags.Origin.TagPrefix origin.TagSum = tags.Origin.TagSum + if tags.Origin.RepoSum != "" { + origin.RepoSum = tags.Origin.RepoSum + } } } }() diff --git a/src/cmd/go/internal/modload/build.go b/src/cmd/go/internal/modload/build.go index f6ba8d43b77..4f334a47203 100644 --- a/src/cmd/go/internal/modload/build.go +++ b/src/cmd/go/internal/modload/build.go @@ -189,6 +189,12 @@ func mergeOrigin(m1, m2 *codehost.Origin) *codehost.Origin { merged.TagSum = m2.TagSum merged.TagPrefix = m2.TagPrefix } + if m2.RepoSum != "" { + if m1.RepoSum != "" && m1.RepoSum != m2.RepoSum { + return nil + } + merged.RepoSum = m2.RepoSum + } if m2.Ref != "" { if m1.Ref != "" && m1.Ref != m2.Ref { return nil diff --git a/src/cmd/go/internal/vcweb/vcweb.go b/src/cmd/go/internal/vcweb/vcweb.go index 4b4e127bb04..98d39a3b1f2 100644 --- a/src/cmd/go/internal/vcweb/vcweb.go +++ b/src/cmd/go/internal/vcweb/vcweb.go @@ -199,8 +199,10 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { defer func() { if v := recover(); v != nil { - debug.PrintStack() - s.logger.Fatal(v) + if v == http.ErrAbortHandler { + panic(v) + } + s.logger.Fatalf("panic serving %s: %v\n%s", req.URL, v, debug.Stack()) } }() diff --git a/src/cmd/go/testdata/script/reuse_git.txt b/src/cmd/go/testdata/script/reuse_git.txt index 3ec6421cfae..faf2124db56 100644 --- a/src/cmd/go/testdata/script/reuse_git.txt +++ b/src/cmd/go/testdata/script/reuse_git.txt @@ -5,16 +5,15 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off -# go mod download with the pseudo-version should invoke git but not have a TagSum or Ref. +# go mod download with the pseudo-version should invoke git but not have a TagSum or Ref or RepoSum. go mod download -x -json vcs-test.golang.org/git/hello.git@v0.0.0-20170922010558-fc3a09f3dc5c stderr 'git( .*)* fetch' cp stdout hellopseudo.json -! stdout '"(Query|TagPrefix|TagSum|Ref)"' +! stdout '"(Query|TagPrefix|TagSum|Ref|RepoSum)"' stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' stdout '"VCS": "git"' stdout '"URL": ".*/git/hello"' stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"RepoSum"' go clean -modcache # go mod download vcstest/hello should invoke git, print origin info diff --git a/src/cmd/go/testdata/script/reuse_hg.txt b/src/cmd/go/testdata/script/reuse_hg.txt index ebc7643733d..b9df7ae7f26 100644 --- a/src/cmd/go/testdata/script/reuse_hg.txt +++ b/src/cmd/go/testdata/script/reuse_hg.txt @@ -1,21 +1,19 @@ -skip - [short] skip -[!hg] skip +[!exec:hg] skip env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off -# go mod download with the pseudo-version should invoke hg but not have a TagSum or Ref. -go mod download -x -json vcs-test.golang.org/hg/hello.hg@v0.0.0-20170922010558-fc3a09f3dc5c +# go mod download with the pseudo-version should invoke hg but not have a TagSum or Ref or RepoSum. +go mod download -x -json vcs-test.golang.org/hg/hello.hg@v0.0.0-20170922011414-e483a7d9f8c9 stderr 'hg( .*)* pull' cp stdout hellopseudo.json -! stdout '"(Query|TagPrefix|TagSum|Ref)"' -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +! stdout '"(Query|TagPrefix|TagSum|Ref|RepoSum)"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' ! stdout '"RepoSum"' go clean -modcache @@ -23,64 +21,63 @@ go clean -modcache go mod download -x -json vcs-test.golang.org/hg/hello.hg@latest stderr 'hg( .*)* pull' cp stdout hello.json -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' stdout '"Query": "latest"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Ref": "HEAD"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"RepoSum"' +! stdout '"TagSum"' +stdout '"Ref": "tip"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' # pseudo-version again should not invoke hg pull (it has the version from the @latest query) # but still be careful not to include a TagSum or a Ref, especially not Ref set to HEAD, # which is easy to do when reusing the cached version from the @latest query. -go mod download -x -json vcs-test.golang.org/hg/hello.hg@v0.0.0-20170922010558-fc3a09f3dc5c +go mod download -x -json vcs-test.golang.org/hg/hello.hg@v0.0.0-20170922011414-e483a7d9f8c9 ! stderr 'hg( .*)* pull' cp stdout hellopseudo2.json cmpenv hellopseudo.json hellopseudo2.json -# go mod download vcstest/hello@hash needs to check TagSum to find pseudoversion base. -go mod download -x -json vcs-test.golang.org/hg/hello.hg@fc3a09f3dc5c -! stderr 'hg( .*)* pull' +# go mod download hg/hello@hash needs to check RepoSum to find pseudoversion base, +# which does a refreshing hg pull. +go mod download -x -json vcs-test.golang.org/hg/hello.hg@e483a7d9f8c9 +stderr 'hg( .*)* pull' cp stdout hellohash.json -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' -stdout '"Query": "fc3a09f3dc5c"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' +stdout '"Query": "e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"RepoSum"' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' # go mod download vcstest/hello/v9 should fail, still print origin info +# hg uses RepoSum instead of TagSum to describe failure condition. ! go mod download -x -json vcs-test.golang.org/hg/hello.hg/v9@latest cp stdout hellov9.json stdout '"Version": "latest"' stdout '"Error":.*no matching versions' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Ref": "HEAD"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout 'RepoSum' +! stdout '"TagSum"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' -# go mod download vcstest/hello/sub/v9 should also fail, print origin info with TagPrefix +# go mod download vcstest/hello/sub/v9 should also fail, print origin info +# hg uses RepoSum instead of TagSum to describe failure condition. ! go mod download -x -json vcs-test.golang.org/hg/hello.hg/sub/v9@latest cp stdout hellosubv9.json stdout '"Version": "latest"' stdout '"Error":.*no matching versions' -stdout '"TagPrefix": "sub/"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Ref": "HEAD"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout 'RepoSum' +! stdout '"TagPrefix"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' # go mod download vcstest/hello@nonexist should fail, still print origin info ! go mod download -x -json vcs-test.golang.org/hg/hello.hg@nonexist cp stdout hellononexist.json stdout '"Version": "nonexist"' stdout '"Error":.*unknown revision nonexist' -stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' ! stdout '"(TagPrefix|TagSum|Ref|Hash)"' # go mod download vcstest/hello@1234567890123456789012345678901234567890 should fail, still print origin info @@ -89,7 +86,7 @@ stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' cp stdout hellononhash.json stdout '"Version": "1234567890123456789012345678901234567890"' stdout '"Error":.*unknown revision 1234567890123456789012345678901234567890' -stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' ! stdout '"(TagPrefix|TagSum|Ref|Hash)"' # go mod download vcstest/hello@v0.0.0-20220101120101-123456789abc should fail, still print origin info @@ -98,10 +95,11 @@ stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' cp stdout hellononpseudo.json stdout '"Version": "v0.0.0-20220101120101-123456789abc"' stdout '"Error":.*unknown revision 123456789abc' -stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' ! stdout '"(TagPrefix|TagSum|Ref|Hash)"' # go mod download vcstest/tagtests should invoke hg, print origin info +# Need RepoSum to lock in tagged "latest". go mod download -x -json vcs-test.golang.org/hg/tagtests.hg@latest stderr 'hg( .*)* pull' cp stdout tagtests.json @@ -110,12 +108,11 @@ stdout '"Query": "latest"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/tags/v0.2.2"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' -! stdout '"RepoSum"' +! stdout '"TagSum"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' -# go mod download vcstest/tagtests@v0.2.2 should print origin info, no TagSum needed +# go mod download vcstest/tagtests@v0.2.2 should print origin info, no TagSum or RepoSum needed. go mod download -x -json vcs-test.golang.org/hg/tagtests.hg@v0.2.2 cp stdout tagtestsv022.json stdout '"Version": "v0.2.2"' @@ -124,22 +121,21 @@ stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' ! stdout '"TagSum"' -stdout '"Ref": "refs/tags/v0.2.2"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' ! stdout '"RepoSum"' +stdout '"Ref": "v0.2.2"' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' -# go mod download vcstest/tagtests@master needs a TagSum again -go mod download -x -json vcs-test.golang.org/hg/tagtests.hg@master -cp stdout tagtestsmaster.json -stdout '"Version": "v0.2.3-0.20190509225625-c7818c24fa2f"' -stdout '"Query": "master"' +# go mod download vcstest/tagtests@default needs a RepoSum again +go mod download -x -json vcs-test.golang.org/hg/tagtests.hg@default +cp stdout tagtestsdefault.json +stdout '"Version": "v0.0.0-20190509225625-8d0b18b816df"' +stdout '"Query": "default"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/heads/master"' -stdout '"Hash": "c7818c24fa2f3f714c67d0a6d3e411c85a518d1f"' -! stdout '"RepoSum"' +! stdout '"TagSum"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' +stdout '"Hash": "8d0b18b816df5e9c564761b405b1d7949c24ee6b"' # go mod download vcstest/prefixtagtests should invoke hg, print origin info go mod download -x -json vcs-test.golang.org/hg/prefixtagtests.hg/sub@latest @@ -150,14 +146,14 @@ stdout '"Query": "latest"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/prefixtagtests"' stdout '"Subdir": "sub"' -stdout '"TagPrefix": "sub/"' -stdout '"TagSum": "t1:YGSbWkJ8dn9ORAr[+]BlKHFK/2ZhXLb9hVuYfTZ9D8C7g="' -stdout '"Ref": "refs/tags/sub/v0.0.10"' -stdout '"Hash": "2b7c4692e12c109263cab51b416fcc835ddd7eae"' -! stdout '"RepoSum"' +stdout '"Ref": "sub/v0.0.10"' +! stdout '"TagPrefix"' +! stdout '"TagSum"' +stdout '"RepoSum": "r1:YWOcei109p5Kohsr5xnSYlaQXmpT3iWZHZhRbfMoTkc="' +stdout '"Hash": "1cc0dfcc254cb8901799e7f7ae182c04019b7a88"' # go mod download of a bunch of these should fail (some are invalid) but write good JSON for later -! go mod download -json vcs-test.golang.org/hg/hello.hg@latest vcs-test.golang.org/hg/hello.hg/v9@latest vcs-test.golang.org/hg/hello.hg/sub/v9@latest vcs-test.golang.org/hg/tagtests.hg@latest vcs-test.golang.org/hg/tagtests.hg@v0.2.2 vcs-test.golang.org/hg/tagtests.hg@master +! go mod download -json vcs-test.golang.org/hg/hello.hg@latest vcs-test.golang.org/hg/hello.hg/v9@latest vcs-test.golang.org/hg/hello.hg/sub/v9@latest vcs-test.golang.org/hg/tagtests.hg@latest vcs-test.golang.org/hg/tagtests.hg@v0.2.2 vcs-test.golang.org/hg/tagtests.hg@default cp stdout all.json # clean the module cache, make sure that makes go mod download re-run hg pull, clean again @@ -171,40 +167,40 @@ go clean -modcache go mod download -reuse=hello.json -x -json vcs-test.golang.org/hg/hello.hg@latest ! stderr 'hg( .*)* pull' stdout '"Reuse": true' -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Ref": "HEAD"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Ref": "tip"' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' +! stdout '"(Dir|Info|GoMod|Zip)"' # reuse go mod download vcstest/hello pseudoversion result go clean -modcache -go mod download -reuse=hellopseudo.json -x -json vcs-test.golang.org/hg/hello.hg@v0.0.0-20170922010558-fc3a09f3dc5c +go mod download -reuse=hellopseudo.json -x -json vcs-test.golang.org/hg/hello.hg@v0.0.0-20170922011414-e483a7d9f8c9 ! stderr 'hg( .*)* pull' stdout '"Reuse": true' -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' ! stdout '"(Query|TagPrefix|TagSum|Ref)"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' ! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' # reuse go mod download vcstest/hello@hash go clean -modcache -go mod download -reuse=hellohash.json -x -json vcs-test.golang.org/hg/hello.hg@fc3a09f3dc5c +go mod download -reuse=hellohash.json -x -json vcs-test.golang.org/hg/hello.hg@e483a7d9f8c9 ! stderr 'hg( .*)* pull' stdout '"Reuse": true' -stdout '"Query": "fc3a09f3dc5c"' -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +stdout '"Query": "e483a7d9f8c9"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' ! stdout '"(TagPrefix|Ref)"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' +! stdout '"(Dir|Info|GoMod|Zip)"' # reuse go mod download vcstest/hello/v9 error result go clean -modcache @@ -213,10 +209,9 @@ go clean -modcache stdout '"Reuse": true' stdout '"Error":.*no matching versions' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Ref": "HEAD"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' +! stdout '"(Dir|Info|GoMod|Zip)"' # reuse go mod download vcstest/hello/sub/v9 error result go clean -modcache @@ -224,11 +219,11 @@ go clean -modcache ! stderr 'hg( .*)* pull' stdout '"Reuse": true' stdout '"Error":.*no matching versions' -stdout '"TagPrefix": "sub/"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Ref": "HEAD"' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +! stdout '"TagPrefix"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Ref": "tip"' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' +! stdout '"(Dir|Info|GoMod|Zip)"' # reuse go mod download vcstest/hello@nonexist go clean -modcache @@ -237,7 +232,7 @@ go clean -modcache stdout '"Reuse": true' stdout '"Version": "nonexist"' stdout '"Error":.*unknown revision nonexist' -stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' ! stdout '"(TagPrefix|TagSum|Ref|Hash)"' ! stdout '"(Dir|Info|GoMod|Zip)"' @@ -248,7 +243,7 @@ go clean -modcache stdout '"Reuse": true' stdout '"Version": "1234567890123456789012345678901234567890"' stdout '"Error":.*unknown revision 1234567890123456789012345678901234567890' -stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' ! stdout '"(TagPrefix|TagSum|Ref|Hash)"' ! stdout '"(Dir|Info|GoMod|Zip)"' @@ -259,7 +254,7 @@ go clean -modcache stdout '"Reuse": true' stdout '"Version": "v0.0.0-20220101120101-123456789abc"' stdout '"Error":.*unknown revision 123456789abc' -stdout '"RepoSum": "r1:c0/9JCZ25lxoBiK3[+]3BhACU4giH49flcJmBynJ[+]Jvmc="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' ! stdout '"(TagPrefix|TagSum|Ref|Hash)"' ! stdout '"(Dir|Info|GoMod|Zip)"' @@ -273,10 +268,9 @@ stdout '"Query": "latest"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/tags/v0.2.2"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' +! stdout '"(Dir|Info|GoMod|Zip)"' # reuse go mod download vcstest/tagtests@v0.2.2 result go clean -modcache @@ -289,39 +283,42 @@ stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' ! stdout '"TagSum"' -stdout '"Ref": "refs/tags/v0.2.2"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' +stdout '"Ref": "v0.2.2"' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' ! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' -# reuse go mod download vcstest/tagtests@master result +# reuse go mod download vcstest/tagtests@default result go clean -modcache -go mod download -reuse=tagtestsmaster.json -x -json vcs-test.golang.org/hg/tagtests.hg@master +go mod download -reuse=tagtestsdefault.json -x -json vcs-test.golang.org/hg/tagtests.hg@default ! stderr 'hg( .*)* pull' stdout '"Reuse": true' -stdout '"Version": "v0.2.3-0.20190509225625-c7818c24fa2f"' -stdout '"Query": "master"' + # NOTE: Strictly speaking this should be v0.2.3-... but we never + # implemented Mercurial support for finding ancestor tags to + # create pseudo-versions. +stdout '"Version": "v0.0.0-20190509225625-8d0b18b816df"' +stdout '"Query": "default"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/heads/master"' -stdout '"Hash": "c7818c24fa2f3f714c67d0a6d3e411c85a518d1f"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' +stdout '"Ref": "default"' +stdout '"Hash": "8d0b18b816df5e9c564761b405b1d7949c24ee6b"' +! stdout '"(Dir|Info|GoMod|Zip)"' -# reuse go mod download vcstest/tagtests@master result again with all.json +# reuse go mod download vcstest/tagtests@default result again with all.json go clean -modcache -go mod download -reuse=all.json -x -json vcs-test.golang.org/hg/tagtests.hg@master +go mod download -reuse=all.json -x -json vcs-test.golang.org/hg/tagtests.hg@default ! stderr 'hg( .*)* pull' stdout '"Reuse": true' -stdout '"Version": "v0.2.3-0.20190509225625-c7818c24fa2f"' -stdout '"Query": "master"' +stdout '"Version": "v0.0.0-20190509225625-8d0b18b816df"' +stdout '"Query": "default"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"TagPrefix"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/heads/master"' -stdout '"Hash": "c7818c24fa2f3f714c67d0a6d3e411c85a518d1f"' -! stdout '"(Dir|Info|GoMod|Zip|RepoSum)"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' +stdout '"Ref": "default"' +stdout '"Hash": "8d0b18b816df5e9c564761b405b1d7949c24ee6b"' +! stdout '"(Dir|Info|GoMod|Zip)"' # go mod download vcstest/prefixtagtests result with json go clean -modcache @@ -332,15 +329,14 @@ stdout '"Query": "latest"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/prefixtagtests"' stdout '"Subdir": "sub"' -stdout '"TagPrefix": "sub/"' -stdout '"TagSum": "t1:YGSbWkJ8dn9ORAr[+]BlKHFK/2ZhXLb9hVuYfTZ9D8C7g="' -stdout '"Ref": "refs/tags/sub/v0.0.10"' -stdout '"Hash": "2b7c4692e12c109263cab51b416fcc835ddd7eae"' +stdout '"RepoSum": "r1:YWOcei109p5Kohsr5xnSYlaQXmpT3iWZHZhRbfMoTkc="' +stdout '"Ref": "sub/v0.0.10"' +stdout '"Hash": "1cc0dfcc254cb8901799e7f7ae182c04019b7a88"' ! stdout '"(Dir|Info|GoMod|Zip)"' # reuse the bulk results with all.json go clean -modcache -! go mod download -reuse=all.json -json vcs-test.golang.org/hg/hello.hg@latest vcs-test.golang.org/hg/hello.hg/v9@latest vcs-test.golang.org/hg/hello.hg/sub/v9@latest vcs-test.golang.org/hg/tagtests.hg@latest vcs-test.golang.org/hg/tagtests.hg@v0.2.2 vcs-test.golang.org/hg/tagtests.hg@master +! go mod download -reuse=all.json -json vcs-test.golang.org/hg/hello.hg@latest vcs-test.golang.org/hg/hello.hg/v9@latest vcs-test.golang.org/hg/hello.hg/sub/v9@latest vcs-test.golang.org/hg/tagtests.hg@latest vcs-test.golang.org/hg/tagtests.hg@v0.2.2 vcs-test.golang.org/hg/tagtests.hg@default ! stderr 'hg( .*)* pull' stdout '"Reuse": true' ! stdout '"(Dir|Info|GoMod|Zip)"' @@ -348,7 +344,7 @@ stdout '"Reuse": true' # reuse attempt with stale hash should reinvoke hg, not report reuse go clean -modcache cp tagtestsv022.json tagtestsv022badhash.json -replace '57952' '56952XXX' tagtestsv022badhash.json +replace '1e5315' '1e5315XXX' tagtestsv022badhash.json go mod download -reuse=tagtestsv022badhash.json -x -json vcs-test.golang.org/hg/tagtests.hg@v0.2.2 stderr 'hg( .*)* pull' ! stdout '"Reuse": true' @@ -357,8 +353,8 @@ stdout '"Version": "v0.2.2"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' ! stdout '"(TagPrefix|TagSum|RepoSum)"' -stdout '"Ref": "refs/tags/v0.2.2"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' +stdout '"Ref": "v0.2.2"' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' stdout '"Dir"' stdout '"Info"' stdout '"GoMod"' @@ -388,20 +384,19 @@ stdout '"URL": ".*/hg/tagtests"' # reuse with stale Dir go clean -modcache cp tagtestsv022.json tagtestsv022baddir.json -replace '\t\t\"Ref\":' '\t\t\"Subdir\": \"subdir\",\n\t\t\"Ref\":' tagtestsv022baddir.json +replace '\"VCS\":' '\"Subdir\":\"subdir\", \"VCS\":' tagtestsv022baddir.json go mod download -reuse=tagtestsv022baddir.json -x -json vcs-test.golang.org/hg/tagtests.hg@v0.2.2 ! stdout '"Reuse": true' stdout '"URL": ".*/hg/tagtests"' ! stdout '"RepoSum"' -# reuse with stale TagSum +# reuse with stale RepoSum go clean -modcache -cp tagtests.json tagtestsbadtagsum.json -replace 'sMEOGo=' 'sMEoGo=XXX' tagtestsbadtagsum.json -go mod download -reuse=tagtestsbadtagsum.json -x -json vcs-test.golang.org/hg/tagtests.hg@latest +cp tagtests.json tagtestsbadreposum.json +replace '8dnv90' '8dnv90XXX' tagtestsbadreposum.json +go mod download -reuse=tagtestsbadreposum.json -x -json vcs-test.golang.org/hg/tagtests.hg@latest ! stdout '"Reuse": true' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -! stdout '"RepoSum"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' # go list on repo with no tags go clean -modcache @@ -409,14 +404,12 @@ go list -x -json -m -retracted -versions vcs-test.golang.org/hg/hello.hg@latest stderr 'hg( .*)* pull' cp stdout hellolist.json ! stdout '"Versions"' -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' stdout '"Query": "latest"' -! stdout '"TagPrefix"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"RepoSum"' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' # reuse go list on repo with no tags go clean -modcache @@ -424,24 +417,22 @@ go list -x -reuse=hellolist.json -json -m -retracted -versions vcs-test.golang.o ! stderr 'hg( .*)* pull' stdout '"Reuse": true' ! stdout '"Versions"' -stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"' +stdout '"Version": "v0.0.0-20170922011414-e483a7d9f8c9"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/hello"' stdout '"Query": "latest"' -! stdout '"TagPrefix"' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' -stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"' -! stdout '"RepoSum"' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' +stdout '"Hash": "e483a7d9f8c9b4bc57430bdd8f81f0a65e4011c0"' # reuse with stale list go clean -modcache cp hellolist.json hellolistbad.json -replace '47DEQ' 'ZZZ' hellolistbad.json +replace 'blLvkhBri' 'ZZZ' hellolistbad.json go clean -modcache go list -x -reuse=hellolistbad.json -json -m -retracted -versions vcs-test.golang.org/hg/hello.hg@latest stderr 'hg( .*)* pull' ! stdout '"Reuse": true' -stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="' +stdout '"RepoSum": "r1:blLvkhBriVMV[+]6Il4Ub43wlyWXIe1NpobTelF0peaG0="' # go list on repo with tags go clean -modcache @@ -454,9 +445,9 @@ stdout '"v0.2.2"' stdout '"Version": "v0.2.2"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/tags/v0.2.2"' +stdout '"Ref": "v0.2.2"' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' # reuse go list on repo with tags go clean -modcache @@ -469,15 +460,15 @@ stdout '"v0.2.2"' stdout '"Version": "v0.2.2"' stdout '"VCS": "hg"' stdout '"URL": ".*/hg/tagtests"' -stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' -stdout '"Ref": "refs/tags/v0.2.2"' +stdout '"Ref": "v0.2.2"' +stdout '"Hash": "1e531550e864b16f25013cfbbf2d8e7cf07a0374"' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' # reuse with stale list go clean -modcache cp taglist.json taglistbad.json -replace 'Dp7yRKDu' 'ZZZ' taglistbad.json +replace '8dnv906' 'ZZZ' taglistbad.json go list -reuse=taglistbad.json -x -json -m -retracted -versions vcs-test.golang.org/hg/tagtests.hg@latest stderr 'hg( .*)* pull' ! stdout '"Reuse": true' -stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="' +stdout '"RepoSum": "r1:8dnv906Aq1vb9YpNl9pslfva0VfG9enKb6O6NWs0xF0="' diff --git a/src/cmd/go/testdata/vcstest/hg/prefixtagtests.txt b/src/cmd/go/testdata/vcstest/hg/prefixtagtests.txt index 6c89c857f49..c61c9bacae9 100644 --- a/src/cmd/go/testdata/vcstest/hg/prefixtagtests.txt +++ b/src/cmd/go/testdata/vcstest/hg/prefixtagtests.txt @@ -1,52 +1,51 @@ -handle git +env date=2019-05-09T18:35:00-04:00 -env GIT_AUTHOR_NAME='Jay Conrod' -env GIT_AUTHOR_EMAIL='jayconrod@google.com' -env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME -env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL +handle hg -at 2019-05-09T18:35:00-04:00 +hg init +hg add sub +hg commit -u rsc -d $date -m 'create module sub' -git init - -git add sub -git commit -m 'create module sub' -git branch -m master - -echo 'v0.1.0' +echo v0.1.0 cp stdout status -git add status -git commit -a -m 'v0.1.0' -git tag 'v0.1.0' +hg add status +hg commit -u rsc -d $date -m v0.1.0 +hg tag -u rsc -d $date v0.1.0 -echo 'sub/v0.0.9' +echo sub/v0.0.9 cp stdout status -git commit -a -m 'sub/v0.0.9' -git tag 'sub/v0.0.9' +hg add status +hg commit -u rsc -d $date -m sub/v0.0.9 +hg tag -u rsc -d $date sub/v0.0.9 -echo 'sub/v0.0.10' +echo sub/v0.0.10 cp stdout status -git commit -a -m 'sub/v0.0.10' -git tag 'sub/v0.0.10' +hg commit -u rsc -d $date -m sub/v0.0.10 status +hg tag -u rsc -d $date sub/v0.0.10 -echo 'v0.2.0' +echo v0.2.0 cp stdout status -git commit -a -m 'v0.2.0' -git tag 'v0.2.0' +hg commit -u rsc -d $date -m v0.2.0 +hg tag -u rsc -d $date v0.2.0 echo 'after last tag' cp stdout status -git commit -a -m 'after last tag' +hg commit -u rsc -d $date -m 'after last tag' -git show-ref --tags --heads -cmp stdout .git-refs +hg tags +cmp stdout .hg-tags --- .git-refs -- -c3ee5d0dfbb9bf3c4d8bb2bce24cd8d14d2d4238 refs/heads/master -2b7c4692e12c109263cab51b416fcc835ddd7eae refs/tags/sub/v0.0.10 -883885166298d79a0561d571a3044ec5db2e7c28 refs/tags/sub/v0.0.9 -db89fc573cfb939faf0aa0660671eb4cf8b8b673 refs/tags/v0.1.0 -1abe41965749e50828dd41de8d12c6ebc8e4e131 refs/tags/v0.2.0 +hg branches +cmp stdout .hg-branches + +-- .hg-tags -- +tip 9:840814f739c2 +v0.2.0 7:84e452ea2b0a +sub/v0.0.10 5:1cc0dfcc254c +sub/v0.0.9 3:c5f5e3168705 +v0.1.0 1:d6ba12969a9b +-- .hg-branches -- +default 9:840814f739c2 -- sub/go.mod -- module vcs-test.golang.org/git/prefixtagtests.git/sub -- sub/sub.go -- diff --git a/src/cmd/go/testdata/vcstest/hg/tagtests.txt b/src/cmd/go/testdata/vcstest/hg/tagtests.txt index 92e79cda877..38b3e97ef9b 100644 --- a/src/cmd/go/testdata/vcstest/hg/tagtests.txt +++ b/src/cmd/go/testdata/vcstest/hg/tagtests.txt @@ -1,39 +1,26 @@ -handle git +env date=2019-05-09T18:56:25-04:00 -env GIT_AUTHOR_NAME='Jay Conrod' -env GIT_AUTHOR_EMAIL='jayconrod@google.com' -env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME -env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL +handle hg -at 2019-05-09T18:56:25-04:00 +hg init +hg add go.mod tagtests.go +hg commit --user 'rsc' --date $date -m 'create module tagtests' +hg branch b +hg add v0.2.1 +hg commit --user 'rsc' --date $date -m 'v0.2.1' +hg tag --user 'rsc' --date $date v0.2.1 -git init +hg update default +hg add v0.2.2 +hg commit --user 'rsc' --date $date -m 'v0.2.2' +hg tag --user 'rsc' --date $date v0.2.2 -git add go.mod tagtests.go -git commit -m 'create module tagtests' -git branch -m master -git branch b +hg tags +cmp stdout .hg-tags -git add v0.2.1 -git commit -m 'v0.2.1' -git tag 'v0.2.1' +hg branches +cmp stdout .hg-branches -git checkout b -git add 'v0.2.2' -git commit -m 'v0.2.2' -git tag 'v0.2.2' - -git checkout master -git merge b -m 'merge' - -git show-ref --tags --heads -cmp stdout .git-refs - --- .git-refs -- -59356c8cd18c5fe9a598167d98a6843e52d57952 refs/heads/b -c7818c24fa2f3f714c67d0a6d3e411c85a518d1f refs/heads/master -101c49f5af1b2466332158058cf5f03c8cca6429 refs/tags/v0.2.1 -59356c8cd18c5fe9a598167d98a6843e52d57952 refs/tags/v0.2.2 -- go.mod -- module vcs-test.golang.org/git/tagtests.git -- tagtests.go -- @@ -42,3 +29,10 @@ package tagtests v0.2.1 -- v0.2.2 -- v0.2.2 +-- .hg-tags -- +tip 4:8d0b18b816df +v0.2.2 3:1e531550e864 +v0.2.1 1:010a2d1a2ea7 +-- .hg-branches -- +default 4:8d0b18b816df +b 2:ceae444ffda5