"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) {
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
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)
func TestLatest(t *testing.T) {
t.Parallel()
+ gitVers := gitVersion(t)
+
type latestTest struct {
repo string
info *RevInfo
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)
func TestReadFile(t *testing.T) {
t.Parallel()
+ gitVers := gitVersion(t)
+
type readFileTest struct {
repo string
rev string
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)
func TestReadZip(t *testing.T) {
t.Parallel()
+ gitVers := gitVersion(t)
+
type readZipTest struct {
repo string
rev string
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)
func TestStat(t *testing.T) {
t.Parallel()
+ gitVers := gitVersion(t)
+
type statTest struct {
repo string
rev string
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)
"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"
)
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
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
+}
"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 {
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))
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 {
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]
[short] skip
[!git] skip
+[!git-min-vers:v2.29] skip
env GOPRIVATE=vcs-test.golang.org
[short] skip
[!git] skip
+[!git-min-vers:v2.29] skip
env GOPRIVATE=vcs-test.golang.org
[short] skip
[!git] skip
+[!git-min-vers:v2.29] skip
# This is a git sha256-mode copy of mod_download_git_bareRepository
+[!git-min-vers:v2.29] skip
+
handle git
# This is a sha256 version of gitrepo1.txt (which uses sha1 hashes)
"errors"
"fmt"
"io"
+ "maps"
+ "slices"
"sort"
"strings"
"time"
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)