cmd/go: fix version stamping for v2 modules and subdirectories

We were not passing the module path to newCodeRepo which caused it to
incorrectly parse the major version. This allowed v0 and v1 modules to
work because an empty major version is allowed in that case.

Additionally we need to pass the root module path to derive the correct tag
for subdirectories.

Fixes: #72877
Fixes: #71738
Change-Id: Id792923f426858513972e713623270edbc76c545
Reviewed-on: https://go-review.googlesource.com/c/go/+/661875
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Sam Thanawalla 2025-03-31 19:06:43 +00:00
parent a08d2db6d1
commit d584d2b3dd
5 changed files with 110 additions and 17 deletions

View File

@ -2577,7 +2577,16 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
} }
appendSetting("vcs.modified", strconv.FormatBool(st.Uncommitted)) appendSetting("vcs.modified", strconv.FormatBool(st.Uncommitted))
// Determine the correct version of this module at the current revision and update the build metadata accordingly. // Determine the correct version of this module at the current revision and update the build metadata accordingly.
repo := modfetch.LookupLocal(ctx, repoDir) rootModPath := goModPath(repoDir)
// If no root module is found, skip embedding VCS data since we cannot determine the module path of the root.
if rootModPath == "" {
goto omitVCS
}
codeRoot, _, ok := module.SplitPathVersion(rootModPath)
if !ok {
goto omitVCS
}
repo := modfetch.LookupLocal(ctx, codeRoot, p.Module.Path, repoDir)
revInfo, err := repo.Stat(ctx, st.Revision) revInfo, err := repo.Stat(ctx, st.Revision)
if err != nil { if err != nil {
goto omitVCS goto omitVCS

View File

@ -222,15 +222,19 @@ func Lookup(ctx context.Context, proxy, path string) Repo {
var lookupLocalCache par.Cache[string, Repo] // path, Repo var lookupLocalCache par.Cache[string, Repo] // path, Repo
// LookupLocal will only use local VCS information to fetch the Repo. // LookupLocal returns a Repo that accesses local VCS information.
func LookupLocal(ctx context.Context, path string) Repo { //
// codeRoot is the module path of the root module in the repository.
// path is the module path of the module being looked up.
// dir is the file system path of the repository containing the module.
func LookupLocal(ctx context.Context, codeRoot string, path string, dir string) Repo {
if traceRepo { if traceRepo {
defer logCall("LookupLocal(%q)", path)() defer logCall("LookupLocal(%q)", path)()
} }
return lookupLocalCache.Do(path, func() Repo { return lookupLocalCache.Do(path, func() Repo {
return newCachingRepo(ctx, path, func(ctx context.Context) (Repo, error) { return newCachingRepo(ctx, path, func(ctx context.Context) (Repo, error) {
repoDir, vcsCmd, err := vcs.FromDir(path, "", true) repoDir, vcsCmd, err := vcs.FromDir(dir, "", true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -238,7 +242,7 @@ func LookupLocal(ctx context.Context, path string) Repo {
if err != nil { if err != nil {
return nil, err return nil, err
} }
r, err := newCodeRepo(code, repoDir, path) r, err := newCodeRepo(code, codeRoot, path)
if err == nil && traceRepo { if err == nil && traceRepo {
r = newLoggingRepo(r) r = newLoggingRepo(r)
} }

View File

@ -34,14 +34,14 @@ exec git branch -m main
# Use a 0.0.0 pseudo-version when no tags are present. # Use a 0.0.0 pseudo-version when no tags are present.
go build go build
go version -m example$GOEXE go version -m example$GOEXE
stdout '\s+mod\s+example\s+v0.0.0-20220719150700-b52f952448d2\s+' stdout '\s+mod\s+example\s+v0.0.0-20220719150700-e7537ba8fd6d\s+'
rm example$GOEXE rm example$GOEXE
# Use a 0.0.0 pseudo-version if the current tag is not a valid semantic version. # Use a 0.0.0 pseudo-version if the current tag is not a valid semantic version.
exec git tag 1.0.1 exec git tag 1.0.1
go build go build
go version -m example$GOEXE go version -m example$GOEXE
stdout '\s+mod\s+example\s+v0.0.0-20220719150700-b52f952448d2\s+' stdout '\s+mod\s+example\s+v0.0.0-20220719150700-e7537ba8fd6d\s+'
rm example$GOEXE rm example$GOEXE
# Use the current tag which has a valid semantic version to stamp the version. # Use the current tag which has a valid semantic version to stamp the version.
@ -79,14 +79,14 @@ exec git commit -m 'commit 3'
# Use a pseudo-version when current commit doesn't match a tagged version. # Use a pseudo-version when current commit doesn't match a tagged version.
go build go build
go version -m example$GOEXE go version -m example$GOEXE
stdout '\s+mod\s+example\s+v1.0.3-0.20220719150702-deaeab06f7fe\s+' stdout '\s+mod\s+example\s+v1.0.3-0.20220719150702-b0226f18a7ae\s+'
rm example$GOEXE rm example$GOEXE
# Use pseudo+dirty when uncommitted changes are present. # Use pseudo+dirty when uncommitted changes are present.
mv README2 README3 mv README2 README3
go build go build
go version -m example$GOEXE go version -m example$GOEXE
stdout '\s+mod\s+example\s+v1.0.3-0.20220719150702-deaeab06f7fe\+dirty\s+' stdout '\s+mod\s+example\s+v1.0.3-0.20220719150702-b0226f18a7ae\+dirty\s+'
rm example$GOEXE rm example$GOEXE
# Make sure we always use the previously tagged version to generate the pseudo-version at a untagged revision. # Make sure we always use the previously tagged version to generate the pseudo-version at a untagged revision.
@ -105,7 +105,7 @@ exec git tag v1.0.4
exec git checkout ':/commit 4' exec git checkout ':/commit 4'
go build go build
go version -m example$GOEXE go version -m example$GOEXE
stdout '\s+mod\s+example\s+v1.0.3-0.20220719150703-2e239bf29c13\s+' stdout '\s+mod\s+example\s+v1.0.3-0.20220719150703-2ebc76937b49\s+'
rm example$GOEXE rm example$GOEXE
# Create +incompatible module # Create +incompatible module
@ -121,6 +121,67 @@ go version -m example$GOEXE
stdout '\s+mod\s+example\s+v2.0.0\+incompatible.dirty\s+' stdout '\s+mod\s+example\s+v2.0.0\+incompatible.dirty\s+'
rm example$GOEXE rm example$GOEXE
# Make sure v2 works as expected.
exec git checkout v1.0.4
go mod edit -module example/v2
exec git add .
exec git commit -m 'commit 7'
exec git tag v2.1.1
go build
go version -m example$GOEXE
stdout '\s+mod\s+example/v2\s+v2.1.1\s+'
rm example$GOEXE
# v2+dirty
mv README5 README6
go build
go version -m example$GOEXE
stdout '\s+mod\s+example/v2\s+v2.1.1\+dirty\s+'
rm example$GOEXE
# v2+pseudo
exec git add .
exec git commit -m 'commit 8'
go build
go version -m example$GOEXE
stdout '\s+mod\s+example/v2\s+v2.1.2-0.20220719150704-0ebeb94ecde2\s+'
rm example$GOEXE
# v2+pseudo+dirty
mv README6 README7
go build
go version -m example$GOEXE
stdout '\s+mod\s+example/v2\s+v2.1.2-0.20220719150704-0ebeb94ecde2\+dirty\s+'
rm example$GOEXE
# modules in subdirectories should be stamped with the correct tag
exec git add .
cd subdir
exec git commit -m 'commit 9'
go build
go version -m subdir$GOEXE
# missing tag creates a pseudo version with v2.0.0
stdout '\s+mod\s+example/subdir/v2\s+v2.0.0-20220719150704-fbef6799938f\s+'
rm subdir$GOEXE
# tag with subdir
exec git tag subdir/v2.1.0
go build
go version -m subdir$GOEXE
stdout '\s+mod\s+example/subdir/v2\s+v2.1.0\s+'
# v2+dirty
mv ../README7 README8
go build
go version -m subdir$GOEXE
stdout '\s+mod\s+example/subdir/v2\s+v2.1.0\+dirty\s+'
rm subdir$GOEXE
# modules in a subdirectory without a go.mod in the root should result in (devel)
rm ../go.mod
go build
go version -m subdir$GOEXE
stdout '\s+mod\s+example/subdir/v2\s+\(devel\)\s+'
rm subdir$GOEXE
-- $WORK/repo/go.mod -- -- $WORK/repo/go.mod --
module example module example
@ -133,6 +194,17 @@ func main() {
-- $WORK/copy/README -- -- $WORK/copy/README --
hello hello
-- $WORK/repo/subdir/go.mod --
module example/subdir/v2
go 1.18
-- $WORK/repo/subdir/main.go --
package main
func main() {
}
-- $WORK/home/gopher/.gitconfig -- -- $WORK/home/gopher/.gitconfig --
[user] [user]
name = Go Gopher name = Go Gopher

View File

@ -44,7 +44,7 @@ stdout '^\tbuild\tvcs.modified=true$'
cd .. cd ..
# Revision and commit time are tagged for repositories with commits. # Revision and commit time are tagged for repositories with commits.
exec bzr add a README exec bzr add a README go.mod
exec bzr commit -m 'initial commit' exec bzr commit -m 'initial commit'
cd a cd a
go install go install
@ -61,7 +61,7 @@ cd ..
cp README README2 cp README README2
exec bzr add a README2 exec bzr add a README2
exec bzr commit -m 'second commit' exec bzr commit -m 'second commit'
exec bzr tag v1.2.3 exec bzr tag a/v1.2.3
cd a cd a
go install go install
go version -m $GOBIN/a$GOEXE go version -m $GOBIN/a$GOEXE
@ -114,6 +114,10 @@ exit 1
-- repo/README -- -- repo/README --
Far out in the uncharted backwaters of the unfashionable end of the western Far out in the uncharted backwaters of the unfashionable end of the western
spiral arm of the Galaxy lies a small, unregarded yellow sun. spiral arm of the Galaxy lies a small, unregarded yellow sun.
-- repo/go.mod --
module example.com
go 1.18
-- repo/a/go.mod -- -- repo/a/go.mod --
module example.com/a module example.com/a

View File

@ -41,20 +41,20 @@ go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.revision=0000000000000000000000000000000000000000$' stdout '^\tbuild\tvcs.revision=0000000000000000000000000000000000000000$'
stdout '^\tbuild\tvcs.time=1970-01-01T00:00:00Z$' stdout '^\tbuild\tvcs.time=1970-01-01T00:00:00Z$'
stdout '^\tbuild\tvcs.modified=true$' stdout '^\tbuild\tvcs.modified=true$'
stdout '\s+mod\s+example.com/a\s+v0.0.0-19700101000000-000000000000\+dirty' stdout '\s+mod\s+example.com/a\s\(devel\)\s+'
cd .. cd ..
# Revision and commit time are tagged for repositories with commits. # Revision and commit time are tagged for repositories with commits.
exec hg add a README exec hg add a README go.mod
exec hg commit -m 'initial commit' --user test-user --date '2024-07-31T01:21:27+00:00' exec hg commit -m 'initial commit' --user test-user --date '2024-07-31T01:21:27+00:00'
exec hg tag v1.2.3 exec hg tag a/v1.2.3
# Switch back to the tagged branch. # Switch back to the tagged branch.
# Tagging a commit causes a new commit to be created. (See https://repo.mercurial-scm.org/hg/help/revsets) # Tagging a commit causes a new commit to be created. (See https://repo.mercurial-scm.org/hg/help/revsets)
exec hg update '.~1' exec hg update '.~1'
cd a cd a
go install go install
go version -m $GOBIN/a$GOEXE go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.revision=71eaed52daeaafea83cb604f75b0a0336ef2c345$' stdout '^\tbuild\tvcs.revision=eae91df98b5dd3c4451accf64c683ddc3edff6a9$'
stdout '^\tbuild\tvcs.time=2024-07-31T01:21:27Z$' stdout '^\tbuild\tvcs.time=2024-07-31T01:21:27Z$'
stdout '^\tbuild\tvcs.modified=false$' stdout '^\tbuild\tvcs.modified=false$'
stdout '\s+mod\s+example.com/a\s+v1.2.3\s+' stdout '\s+mod\s+example.com/a\s+v1.2.3\s+'
@ -73,7 +73,7 @@ exec hg status
stdout '^.+' stdout '^.+'
go install go install
go version -m $GOBIN/a$GOEXE go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.revision=71eaed52daeaafea83cb604f75b0a0336ef2c345$' stdout '^\tbuild\tvcs.revision=eae91df98b5dd3c4451accf64c683ddc3edff6a9$'
stdout '^\tbuild\tvcs.time=2024-07-31T01:21:27Z$' stdout '^\tbuild\tvcs.time=2024-07-31T01:21:27Z$'
stdout '^\tbuild\tvcs.modified=false$' stdout '^\tbuild\tvcs.modified=false$'
stdout '\s+mod\s+example.com/a\s+v1.2.3\s+' stdout '\s+mod\s+example.com/a\s+v1.2.3\s+'
@ -112,6 +112,10 @@ exit 1
-- repo/README -- -- repo/README --
Far out in the uncharted backwaters of the unfashionable end of the western Far out in the uncharted backwaters of the unfashionable end of the western
spiral arm of the Galaxy lies a small, unregarded yellow sun. spiral arm of the Galaxy lies a small, unregarded yellow sun.
-- repo/go.mod --
module example.com
go 1.18
-- repo/a/go.mod -- -- repo/a/go.mod --
module example.com/a module example.com/a