# This test checks that VCS information is stamped into Go binaries by default,
# controlled with -buildvcs. This test focuses on Mercurial specifics.
# The Git test covers common functionality.

[!exec:hg] skip
[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.
go install
go version -m $GOBIN/a$GOEXE
! stdout hgrevision
stdout '\s+mod\s+example.com/a\s+\(devel\)'
rm $GOBIN/a$GOEXE

# If there is a repository, but it can't be used for some reason,
# there should be an error. It should hint about -buildvcs=false.
cd ..
mkdir .hg
env PATH=$WORK${/}fakebin${:}$oldpath
chmod 0755 $WORK/fakebin/hg
! exec hg help
cd a
! go install
stderr '^error obtaining VCS status: exit status 1\n\tUse -buildvcs=false to disable VCS stamping.$'
rm $GOBIN/a$GOEXE
cd ..
env PATH=$oldpath
rm .hg

# 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 '^\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\(devel\)\s+'
cd ..

# Revision and commit time are tagged for repositories with commits.
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 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=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+'
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=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+'
rm $GOBIN/a$GOEXE

# Building with -buildvcs=false suppresses the info.
go install -buildvcs=false
go version -m $GOBIN/a$GOEXE
! stdout hgrevision
stdout '\s+mod\s+example.com/a\s+\(devel\)'
rm $GOBIN/a$GOEXE

# An untracked file is shown as uncommitted, even if it isn't part of the build.
cp ../../outside/empty.txt .
go install
go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.modified=true$'
stdout '\s+mod\s+example.com/a\s+v1.2.3\+dirty\s+'
rm empty.txt
rm $GOBIN/a$GOEXE

# An edited file is shown as uncommitted, even if it isn't part of the build.
cp ../../outside/empty.txt ../README
go install
go version -m $GOBIN/a$GOEXE
stdout '^\tbuild\tvcs.modified=true$'
stdout '\s+mod\s+example.com/a\s+v1.2.3\+dirty\s+'
exec hg revert ../README
rm $GOBIN/a$GOEXE

-- $WORK/fakebin/hg --
#!/bin/sh
exit 1
-- $WORK/fakebin/hg.bat --
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

go 1.18
-- repo/a/a.go --
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 --
