diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 4a28a2a2cb..f11c2d9bed 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -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 diff --git a/src/cmd/go/internal/modfetch/repo.go b/src/cmd/go/internal/modfetch/repo.go index 782d1dade7..b07fda0fb5 100644 --- a/src/cmd/go/internal/modfetch/repo.go +++ b/src/cmd/go/internal/modfetch/repo.go @@ -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) } diff --git a/src/cmd/go/testdata/script/build_version_stamping_git.txt b/src/cmd/go/testdata/script/build_version_stamping_git.txt index e9aa824474..f9dbb370b6 100644 --- a/src/cmd/go/testdata/script/build_version_stamping_git.txt +++ b/src/cmd/go/testdata/script/build_version_stamping_git.txt @@ -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 diff --git a/src/cmd/go/testdata/script/version_buildvcs_bzr.txt b/src/cmd/go/testdata/script/version_buildvcs_bzr.txt index 59796d1ffa..fd0b80c40a 100644 --- a/src/cmd/go/testdata/script/version_buildvcs_bzr.txt +++ b/src/cmd/go/testdata/script/version_buildvcs_bzr.txt @@ -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 diff --git a/src/cmd/go/testdata/script/version_buildvcs_hg.txt b/src/cmd/go/testdata/script/version_buildvcs_hg.txt index 4f9fa7f2f4..81dee5a9df 100644 --- a/src/cmd/go/testdata/script/version_buildvcs_hg.txt +++ b/src/cmd/go/testdata/script/version_buildvcs_hg.txt @@ -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