]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: fix version stamping for v2 modules and subdirectories
authorSam Thanawalla <samthanawalla@google.com>
Mon, 31 Mar 2025 19:06:43 +0000 (19:06 +0000)
committerSam Thanawalla <samthanawalla@google.com>
Mon, 7 Apr 2025 18:29:57 +0000 (11:29 -0700)
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>
src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/modfetch/repo.go
src/cmd/go/testdata/script/build_version_stamping_git.txt
src/cmd/go/testdata/script/version_buildvcs_bzr.txt
src/cmd/go/testdata/script/version_buildvcs_hg.txt

index 4a28a2a2cbb1f22314d51b73d57c7ab2dd6ef303..f11c2d9bed04ff7a36aeee2633d022fdc370eb9c 100644 (file)
@@ -2577,7 +2577,16 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
                }
                appendSetting("vcs.modified", strconv.FormatBool(st.Uncommitted))
                // 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)
                if err != nil {
                        goto omitVCS
index 782d1dade7a8f82cfbc3e162790a8c4ddd64c523..b07fda0fb5bcd11634cdb316b8ba0c6dab944510 100644 (file)
@@ -222,15 +222,19 @@ func Lookup(ctx context.Context, proxy, path string) Repo {
 
 var lookupLocalCache par.Cache[string, Repo] // path, Repo
 
-// LookupLocal will only use local VCS information to fetch the Repo.
-func LookupLocal(ctx context.Context, path string) Repo {
+// LookupLocal returns a Repo that accesses local VCS information.
+//
+// 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 {
                defer logCall("LookupLocal(%q)", path)()
        }
 
        return lookupLocalCache.Do(path, func() Repo {
                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 {
                                return nil, err
                        }
@@ -238,7 +242,7 @@ func LookupLocal(ctx context.Context, path string) Repo {
                        if err != nil {
                                return nil, err
                        }
-                       r, err := newCodeRepo(code, repoDir, path)
+                       r, err := newCodeRepo(code, codeRoot, path)
                        if err == nil && traceRepo {
                                r = newLoggingRepo(r)
                        }
index e9aa824474bb58eabb25de9ceda4c8c4208d923e..f9dbb370b65a9a7fd42ef4d2db1476f340e9472e 100644 (file)
@@ -34,14 +34,14 @@ exec git branch -m main
 # Use a 0.0.0 pseudo-version when no tags are present.
 go build
 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
 
 # Use a 0.0.0 pseudo-version if the current tag is not a valid semantic version.
 exec git tag 1.0.1
 go build
 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
 
 # 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.
 go build
 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
 
 # Use pseudo+dirty when uncommitted changes are present.
 mv README2 README3
 go build
 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
 
 # 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'
 go build
 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
 
 # Create +incompatible module
@@ -121,6 +121,67 @@ go version -m example$GOEXE
 stdout '\s+mod\s+example\s+v2.0.0\+incompatible.dirty\s+'
 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 --
 module example
 
@@ -133,6 +194,17 @@ func main() {
 -- $WORK/copy/README --
 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 --
 [user]
     name = Go Gopher
index 59796d1ffa8c2dbd9483ac5273bd16b07a04d4f0..fd0b80c40a9eaf0ea17b5ec22bb724fe6378383f 100644 (file)
@@ -44,7 +44,7 @@ stdout '^\tbuild\tvcs.modified=true$'
 cd ..
 
 # 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'
 cd a
 go install
@@ -61,7 +61,7 @@ cd ..
 cp README README2
 exec bzr add a README2
 exec bzr commit -m 'second commit'
-exec bzr tag v1.2.3
+exec bzr tag a/v1.2.3
 cd a
 go install
 go version -m $GOBIN/a$GOEXE
@@ -114,6 +114,10 @@ exit 1
 -- repo/README --
 Far out in the uncharted backwaters of the unfashionable end of the western
 spiral arm of the Galaxy lies a small, unregarded yellow sun.
+-- repo/go.mod --
+module example.com
+
+go 1.18
 -- repo/a/go.mod --
 module example.com/a
 
index 4f9fa7f2f443cd9714d3f91d5befac090e72fa33..81dee5a9df78f052d4d6abe4d839280e038e40b6 100644 (file)
@@ -41,20 +41,20 @@ go version -m $GOBIN/a$GOEXE
 stdout '^\tbuild\tvcs.revision=0000000000000000000000000000000000000000$'
 stdout '^\tbuild\tvcs.time=1970-01-01T00:00:00Z$'
 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 ..
 
 # 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 tag v1.2.3
+exec hg tag a/v1.2.3
 # 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)
 exec hg update '.~1'
 cd a
 go install
 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.modified=false$'
 stdout '\s+mod\s+example.com/a\s+v1.2.3\s+'
@@ -73,7 +73,7 @@ exec hg status
 stdout '^.+'
 go install
 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.modified=false$'
 stdout '\s+mod\s+example.com/a\s+v1.2.3\s+'
@@ -112,6 +112,10 @@ exit 1
 -- repo/README --
 Far out in the uncharted backwaters of the unfashionable end of the western
 spiral arm of the Galaxy lies a small, unregarded yellow sun.
+-- repo/go.mod --
+module example.com
+
+go 1.18
 -- repo/a/go.mod --
 module example.com/a