]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: skip git sha256 tests if git < 2.29
authorDavid Finkel <david.finkel@gmail.com>
Sun, 24 Aug 2025 19:15:06 +0000 (15:15 -0400)
committerGopher Robot <gobot@golang.org>
Sun, 2 Nov 2025 15:51:05 +0000 (07:51 -0800)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Michael Matloob <matloob@google.com>
Auto-Submit: Michael Matloob <matloob@google.com>
Reviewed-by: Ian Alexander <jitsu@google.com>
src/cmd/go/internal/modfetch/codehost/git_test.go
src/cmd/go/internal/vcweb/script.go
src/cmd/go/scriptconds_test.go
src/cmd/go/testdata/script/README
src/cmd/go/testdata/script/build_git_sha256_go_get_branch.txt
src/cmd/go/testdata/script/build_git_sha256_moddep.txt
src/cmd/go/testdata/script/mod_download_git_bareRepository_sha256.txt
src/cmd/go/testdata/vcstest/git/gitrepo-sha256.txt
src/cmd/internal/script/engine.go

index e8884abdfedb60136e646e09fa3cd4627b913a9a..ef01810ee8b43663ba8831fa47bcfb158efa1253 100644 (file)
@@ -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)
index 3342ab200c6faa9f9a9a3a454c18b3cc7b16c6a0..0856c40677c1bc1fc48d9d30ffd1230e2c7cfe7a 100644 (file)
@@ -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("<suffix> 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
+}
index af9691ad2a4aca40ae15fadf5a1e7b455c44c39f..c87c60ad33a31be5fb1873e746d01ffd6705c30d 100644 (file)
@@ -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 = <suffix> (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("<suffix> indicates a minimum git version", hasAtLeastGitVersion))
        add("net", script.PrefixCondition("can connect to external network host <suffix>", 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 {
index 7724bc10ec46f0abc5d453cacbf557720d3793d5..d4f4c47af706f3b9cac9f16ae012215f1a81574a 100644 (file)
@@ -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:*]
+       <suffix> indicates a minimum git version
 [go-builder]
        GO_BUILDER_NAME is non-empty
 [link]
index fa5557b21e6d7f6688d7e16ee10026a1896f871f..0773e08ea53e8a00240168ee2b8bc1128215ef40 100644 (file)
@@ -1,5 +1,6 @@
 [short] skip
 [!git] skip
+[!git-min-vers:v2.29] skip
 
 env GOPRIVATE=vcs-test.golang.org
 
index e5bf209d89586761a9c8e037763dba5a67f0d882..21a296bd3d0845943832fd877b51da49e330ce13 100644 (file)
@@ -1,5 +1,6 @@
 [short] skip
 [!git] skip
+[!git-min-vers:v2.29] skip
 
 env GOPRIVATE=vcs-test.golang.org
 
index 9e8dc3c0150d7f5838746dc26c4c44b772d34dc8..df772f5c4bbf82c29c2a9cd5ac3d5126a2b603f4 100644 (file)
@@ -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
 
index 81b9a71c12593d4f751d8d8d64fb794f948bb16b..15068a249ef4e5a68224550b3ec6c4cf1fab9c2e 100644 (file)
@@ -1,3 +1,5 @@
+[!git-min-vers:v2.29] skip
+
 handle git
 
 # This is a sha256 version of gitrepo1.txt (which uses sha1 hashes)
index 4607868379488a751874f192ca161eee80de66d1..05b9433d3ec8a3c4266e319c2762a02cb6c36e87 100644 (file)
@@ -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)