From: David Finkel Date: Sun, 24 Aug 2025 19:15:06 +0000 (-0400) Subject: cmd/go: skip git sha256 tests if git < 2.29 X-Git-Tag: go1.26rc1~407 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=388c41c412c24b751c8c09465787ae79bceca9c7;p=gostls13.git cmd/go: skip git sha256 tests if git < 2.29 Fix test building on older Ubuntu LTS releases (that are still supported). Git SHA256 support was only included in 2.29, which came out in 2021. Check the output of `git version` and skip these tests if the version is older than that introduction. Thanks to @ianlancetaylor for flagging this. Updates: #73704 Change-Id: I9d413a63fa43f34f94c274bba7f7b883c80433b6 Reviewed-on: https://go-review.googlesource.com/c/go/+/698835 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Matloob Reviewed-by: Michael Matloob Auto-Submit: Michael Matloob Reviewed-by: Ian Alexander --- diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go index e8884abdfe..ef01810ee8 100644 --- a/src/cmd/go/internal/modfetch/codehost/git_test.go +++ b/src/cmd/go/internal/modfetch/codehost/git_test.go @@ -16,14 +16,18 @@ import ( "io/fs" "log" "os" + "os/exec" "path" "path/filepath" "reflect" + "regexp" "runtime" "strings" "sync" "testing" "time" + + "golang.org/x/mod/semver" ) func TestMain(m *testing.M) { @@ -192,9 +196,29 @@ func testRepo(ctx context.Context, t *testing.T, remote string) (Repo, error) { return NewRepo(ctx, vcsName, remote, false) } +var gitVersLineExtract = regexp.MustCompile(`git version\s+([\d.]+)`) + +func gitVersion(t testing.TB) string { + gitOut, runErr := exec.Command("git", "version").CombinedOutput() + if runErr != nil { + t.Logf("failed to execute git version: %s", runErr) + return "v0" + } + matches := gitVersLineExtract.FindSubmatch(gitOut) + if len(matches) < 2 { + t.Logf("git version extraction regexp did not match version line: %q", gitOut) + return "v0" + } + return "v" + string(matches[1]) +} + +const minGitSHA256Vers = "v2.29" + func TestTags(t *testing.T) { t.Parallel() + gitVers := gitVersion(t) + type tagsTest struct { repo string prefix string @@ -204,6 +228,9 @@ func TestTags(t *testing.T) { runTest := func(tt tagsTest) func(*testing.T) { return func(t *testing.T) { t.Parallel() + if tt.repo == gitsha256repo && semver.Compare(gitVers, minGitSHA256Vers) < 0 { + t.Skipf("git version is too old (%+v); skipping git sha256 test", gitVers) + } ctx := testContext(t) r, err := testRepo(ctx, t, tt.repo) @@ -288,6 +315,8 @@ func TestTags(t *testing.T) { func TestLatest(t *testing.T) { t.Parallel() + gitVers := gitVersion(t) + type latestTest struct { repo string info *RevInfo @@ -297,6 +326,10 @@ func TestLatest(t *testing.T) { t.Parallel() ctx := testContext(t) + if tt.repo == gitsha256repo && semver.Compare(gitVers, minGitSHA256Vers) < 0 { + t.Skipf("git version is too old (%+v); skipping git sha256 test", gitVers) + } + r, err := testRepo(ctx, t, tt.repo) if err != nil { t.Fatal(err) @@ -375,6 +408,8 @@ func TestLatest(t *testing.T) { func TestReadFile(t *testing.T) { t.Parallel() + gitVers := gitVersion(t) + type readFileTest struct { repo string rev string @@ -387,6 +422,10 @@ func TestReadFile(t *testing.T) { t.Parallel() ctx := testContext(t) + if tt.repo == gitsha256repo && semver.Compare(gitVers, minGitSHA256Vers) < 0 { + t.Skipf("git version is too old (%+v); skipping git sha256 test", gitVers) + } + r, err := testRepo(ctx, t, tt.repo) if err != nil { t.Fatal(err) @@ -468,6 +507,8 @@ type zipFile struct { func TestReadZip(t *testing.T) { t.Parallel() + gitVers := gitVersion(t) + type readZipTest struct { repo string rev string @@ -480,6 +521,10 @@ func TestReadZip(t *testing.T) { t.Parallel() ctx := testContext(t) + if tt.repo == gitsha256repo && semver.Compare(gitVers, minGitSHA256Vers) < 0 { + t.Skipf("git version is too old (%+v); skipping git sha256 test", gitVers) + } + r, err := testRepo(ctx, t, tt.repo) if err != nil { t.Fatal(err) @@ -753,6 +798,8 @@ var hgmap = map[string]string{ func TestStat(t *testing.T) { t.Parallel() + gitVers := gitVersion(t) + type statTest struct { repo string rev string @@ -764,6 +811,10 @@ func TestStat(t *testing.T) { t.Parallel() ctx := testContext(t) + if tt.repo == gitsha256repo && semver.Compare(gitVers, minGitSHA256Vers) < 0 { + t.Skipf("git version is too old (%+v); skipping git sha256 test", gitVers) + } + r, err := testRepo(ctx, t, tt.repo) if err != nil { t.Fatal(err) diff --git a/src/cmd/go/internal/vcweb/script.go b/src/cmd/go/internal/vcweb/script.go index 3342ab200c..0856c40677 100644 --- a/src/cmd/go/internal/vcweb/script.go +++ b/src/cmd/go/internal/vcweb/script.go @@ -18,12 +18,14 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "strconv" "strings" "time" "golang.org/x/mod/module" + "golang.org/x/mod/semver" "golang.org/x/mod/zip" ) @@ -42,6 +44,7 @@ func newScriptEngine() *script.Engine { return script.OnceCondition(summary, func() (bool, error) { return f(), nil }) } add("bzr", lazyBool("the 'bzr' executable exists and provides the standard CLI", hasWorkingBzr)) + add("git-min-vers", script.PrefixCondition(" indicates a minimum git version", hasAtLeastGitVersion)) interrupt := func(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) } gracePeriod := 30 * time.Second // arbitrary @@ -394,3 +397,25 @@ func hasWorkingBzr() bool { err = exec.Command(bzr, "help").Run() return err == nil } + +var gitVersLineExtract = regexp.MustCompile(`git version\s+([\d.]+)`) + +func gitVersion() (string, error) { + gitOut, runErr := exec.Command("git", "version").CombinedOutput() + if runErr != nil { + return "v0", fmt.Errorf("failed to execute git version: %w", runErr) + } + matches := gitVersLineExtract.FindSubmatch(gitOut) + if len(matches) < 2 { + return "v0", fmt.Errorf("git version extraction regexp did not match version line: %q", gitOut) + } + return "v" + string(matches[1]), nil +} + +func hasAtLeastGitVersion(s *script.State, minVers string) (bool, error) { + gitVers, gitVersErr := gitVersion() + if gitVersErr != nil { + return false, gitVersErr + } + return semver.Compare(minVers, gitVers) <= 0, nil +} diff --git a/src/cmd/go/scriptconds_test.go b/src/cmd/go/scriptconds_test.go index af9691ad2a..c87c60ad33 100644 --- a/src/cmd/go/scriptconds_test.go +++ b/src/cmd/go/scriptconds_test.go @@ -14,10 +14,13 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "runtime/debug" "sync" "testing" + + "golang.org/x/mod/semver" ) func scriptConditions(t *testing.T) map[string]script.Cond { @@ -41,6 +44,7 @@ func scriptConditions(t *testing.T) map[string]script.Cond { add("case-sensitive", script.OnceCondition("$WORK filesystem is case-sensitive", isCaseSensitive)) add("cc", script.PrefixCondition("go env CC = (ignoring the go/env file)", ccIs)) add("git", lazyBool("the 'git' executable exists and provides the standard CLI", hasWorkingGit)) + add("git-min-vers", script.PrefixCondition(" indicates a minimum git version", hasAtLeastGitVersion)) add("net", script.PrefixCondition("can connect to external network host ", hasNet)) add("trimpath", script.OnceCondition("test binary was built with -trimpath", isTrimpath)) @@ -153,6 +157,28 @@ func hasWorkingGit() bool { return err == nil } +var gitVersLineExtract = regexp.MustCompile(`git version\s+([\d.]+)`) + +func gitVersion() (string, error) { + gitOut, runErr := exec.Command("git", "version").CombinedOutput() + if runErr != nil { + return "v0", fmt.Errorf("failed to execute git version: %w", runErr) + } + matches := gitVersLineExtract.FindSubmatch(gitOut) + if len(matches) < 2 { + return "v0", fmt.Errorf("git version extraction regexp did not match version line: %q", gitOut) + } + return "v" + string(matches[1]), nil +} + +func hasAtLeastGitVersion(s *script.State, minVers string) (bool, error) { + gitVers, gitVersErr := gitVersion() + if gitVersErr != nil { + return false, gitVersErr + } + return semver.Compare(minVers, gitVers) <= 0, nil +} + func hasWorkingBzr() bool { bzr, err := exec.LookPath("bzr") if err != nil { diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README index 7724bc10ec..d4f4c47af7 100644 --- a/src/cmd/go/testdata/script/README +++ b/src/cmd/go/testdata/script/README @@ -399,6 +399,8 @@ The available conditions are: GOOS/GOARCH supports -fuzz with instrumentation [git] the 'git' executable exists and provides the standard CLI +[git-min-vers:*] + indicates a minimum git version [go-builder] GO_BUILDER_NAME is non-empty [link] diff --git a/src/cmd/go/testdata/script/build_git_sha256_go_get_branch.txt b/src/cmd/go/testdata/script/build_git_sha256_go_get_branch.txt index fa5557b21e..0773e08ea5 100644 --- a/src/cmd/go/testdata/script/build_git_sha256_go_get_branch.txt +++ b/src/cmd/go/testdata/script/build_git_sha256_go_get_branch.txt @@ -1,5 +1,6 @@ [short] skip [!git] skip +[!git-min-vers:v2.29] skip env GOPRIVATE=vcs-test.golang.org diff --git a/src/cmd/go/testdata/script/build_git_sha256_moddep.txt b/src/cmd/go/testdata/script/build_git_sha256_moddep.txt index e5bf209d89..21a296bd3d 100644 --- a/src/cmd/go/testdata/script/build_git_sha256_moddep.txt +++ b/src/cmd/go/testdata/script/build_git_sha256_moddep.txt @@ -1,5 +1,6 @@ [short] skip [!git] skip +[!git-min-vers:v2.29] skip env GOPRIVATE=vcs-test.golang.org diff --git a/src/cmd/go/testdata/script/mod_download_git_bareRepository_sha256.txt b/src/cmd/go/testdata/script/mod_download_git_bareRepository_sha256.txt index 9e8dc3c015..df772f5c4b 100644 --- a/src/cmd/go/testdata/script/mod_download_git_bareRepository_sha256.txt +++ b/src/cmd/go/testdata/script/mod_download_git_bareRepository_sha256.txt @@ -1,5 +1,6 @@ [short] skip [!git] skip +[!git-min-vers:v2.29] skip # This is a git sha256-mode copy of mod_download_git_bareRepository diff --git a/src/cmd/go/testdata/vcstest/git/gitrepo-sha256.txt b/src/cmd/go/testdata/vcstest/git/gitrepo-sha256.txt index 81b9a71c12..15068a249e 100644 --- a/src/cmd/go/testdata/vcstest/git/gitrepo-sha256.txt +++ b/src/cmd/go/testdata/vcstest/git/gitrepo-sha256.txt @@ -1,3 +1,5 @@ +[!git-min-vers:v2.29] skip + handle git # This is a sha256 version of gitrepo1.txt (which uses sha1 hashes) diff --git a/src/cmd/internal/script/engine.go b/src/cmd/internal/script/engine.go index 4607868379..05b9433d3e 100644 --- a/src/cmd/internal/script/engine.go +++ b/src/cmd/internal/script/engine.go @@ -55,6 +55,8 @@ import ( "errors" "fmt" "io" + "maps" + "slices" "sort" "strings" "time" @@ -518,7 +520,7 @@ func (e *Engine) conditionsActive(s *State, conds []condition) (bool, error) { if ok { impl = e.Conds[prefix] if impl == nil { - return false, fmt.Errorf("unknown condition prefix %q", prefix) + return false, fmt.Errorf("unknown condition prefix %q; known: %v", prefix, slices.Collect(maps.Keys(e.Conds))) } if !impl.Usage().Prefix { return false, fmt.Errorf("condition %q cannot be used with a suffix", prefix)