Skip to content

Commit

Permalink
cmd/go: fix the accuracy of Mercurial vcs.* stamped data
Browse files Browse the repository at this point in the history
There were a few Mercurial command line uses that could cause the wrong
data to be used:

* The log command needs '-r.' to specify the currently checked out commit
* HGPLAIN is needed to disable optional output on commands
* '-S' is needed to for the 'status' command to recurse into any subrepos

The most likely issue to be seen here was the use of '-l1' instead of
'-r.', which prints the most recent commit instead of the current checkout.
Since tagging in Mercurial creates a new commit, this basically means the
data was wrong for every tagged build.

This also adds an hgrc config file to the test, with config options to
keep the time and author values fixed.  It's what's used in the Mercurial
test harness to keep the commit hashes stable, and allows the tests here to
also match the time and the revision ID, to prevent regressing.

Fixes #63532

Change-Id: I5b9971ce87c83431ec77e4a002bdc33fcf393856
GitHub-Last-Rev: 62c9db0
GitHub-Pull-Request: #63557
Reviewed-on: https://go-review.googlesource.com/c/go/+/535377
Reviewed-by: Bryan Mills <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Sam Thanawalla <[email protected]>
Auto-Submit: Sam Thanawalla <[email protected]>
Reviewed-by: Michael Matloob <[email protected]>
  • Loading branch information
mharbison72 authored and gopherbot committed Sep 27, 2024
1 parent 99bf122 commit 62452be
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
13 changes: 10 additions & 3 deletions src/cmd/go/internal/vcs/vcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
type Cmd struct {
Name string
Cmd string // name of binary to invoke command
Env []string // any environment values to set/override
RootNames []rootName // filename and mode indicating the root of a checkout directory

CreateCmd []string // commands to download a fresh copy of a repository
Expand Down Expand Up @@ -154,6 +155,10 @@ func vcsByCmd(cmd string) *Cmd {
var vcsHg = &Cmd{
Name: "Mercurial",
Cmd: "hg",

// HGPLAIN=1 turns off additional output that a user may have enabled via
// config options or certain extensions.
Env: []string{"HGPLAIN=1"},
RootNames: []rootName{
{filename: ".hg", isDir: true},
},
Expand Down Expand Up @@ -189,12 +194,11 @@ func hgRemoteRepo(vcsHg *Cmd, rootDir string) (remoteRepo string, err error) {

func hgStatus(vcsHg *Cmd, rootDir string) (Status, error) {
// Output changeset ID and seconds since epoch.
out, err := vcsHg.runOutputVerboseOnly(rootDir, `log -l1 -T {node}:{date|hgdate}`)
out, err := vcsHg.runOutputVerboseOnly(rootDir, `log -r. -T {node}:{date|hgdate}`)
if err != nil {
return Status{}, err
}

// Successful execution without output indicates an empty repo (no commits).
var rev string
var commitTime time.Time
if len(out) > 0 {
Expand All @@ -209,7 +213,7 @@ func hgStatus(vcsHg *Cmd, rootDir string) (Status, error) {
}

// Also look for untracked files.
out, err = vcsHg.runOutputVerboseOnly(rootDir, "status")
out, err = vcsHg.runOutputVerboseOnly(rootDir, "status -S")
if err != nil {
return Status{}, err
}
Expand Down Expand Up @@ -689,6 +693,9 @@ func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([

cmd := exec.Command(v.Cmd, args...)
cmd.Dir = dir
if v.Env != nil {
cmd.Env = append(cmd.Environ(), v.Env...)
}
if cfg.BuildX {
fmt.Fprintf(os.Stderr, "cd %s\n", dir)
fmt.Fprintf(os.Stderr, "%s %s\n", v.Cmd, strings.Join(args, " "))
Expand Down
39 changes: 33 additions & 6 deletions src/cmd/go/testdata/script/version_buildvcs_hg.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
[short] skip
env GOBIN=$WORK/gopath/bin
env oldpath=$PATH
env TZ=GMT
env HGRCPATH=$WORK/hgrc
cd repo/a

# If there's no local repository, there's no VCS info.
Expand All @@ -29,24 +31,43 @@ cd ..
env PATH=$oldpath
rm .hg

# If there is an empty repository in a parent directory, only "uncommitted" is tagged.
# An empty repository or one explicitly updated to null uses the null cset ID,
# and the time is hard set to 1/1/70, regardless of the current time.
exec hg init
cd a
go install
go version -m $GOBIN/a$GOEXE
! stdout vcs.revision
! stdout vcs.time
stdout '^\tbuild\tvcs.revision=0000000000000000000000000000000000000000$'
stdout '^\tbuild\tvcs.time=1970-01-01T00:00:00Z$'
stdout '^\tbuild\tvcs.modified=true$'
cd ..

# Revision and commit time are tagged for repositories with commits.
exec hg add a README
exec hg commit -m 'initial commit'
exec hg commit -m 'initial commit' --user test-user --date '2024-07-31T01:21:27+00:00'
cd a
go install
go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.revision='
stdout '^\tbuild\tvcs.time='
stdout '^\tbuild\tvcs.revision=71eaed52daeaafea83cb604f75b0a0336ef2c345$'
stdout '^\tbuild\tvcs.time=2024-07-31T01:21:27Z$'
stdout '^\tbuild\tvcs.modified=false$'
rm $GOBIN/a$GOEXE

# Add an extra commit and then back off of it to show that the hash is
# from the checked out revision, not the tip revision.
cp ../../outside/empty.txt .
exec hg ci -Am 'another commit' --user test-user --date '2024-08-01T19:24:38+00:00'
exec hg update --clean -r '.^'

# Modified state is not thrown off by extra status output
exec hg bisect -v -g .
exec hg bisect -v -b '.^^'
exec hg status
stdout '^.+'
go install
go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.revision=71eaed52daeaafea83cb604f75b0a0336ef2c345$'
stdout '^\tbuild\tvcs.time=2024-07-31T01:21:27Z$'
stdout '^\tbuild\tvcs.modified=false$'
rm $GOBIN/a$GOEXE

Expand Down Expand Up @@ -88,4 +109,10 @@ go 1.18
package main

func main() {}
-- $WORK/hgrc --
[ui]
# tweakdefaults is an opt-in that may print extra output in commands like
# status. That can be disabled by setting HGPLAIN=1.
tweakdefaults = 1

-- outside/empty.txt --

0 comments on commit 62452be

Please sign in to comment.