}
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
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
}
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)
}
# 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.
# 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.
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
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
-- $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
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
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
-- 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
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+'
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+'
-- 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