cmd/go/internal/modfetch/codehost: skip hg tests if no hg binary is present

Change-Id: I5cf57bf1153eb662bcab71e3d2c04848212559a6
Reviewed-on: https://go-review.googlesource.com/c/go/+/330989
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go
index 89a73ba..a684fa1 100644
--- a/src/cmd/go/internal/modfetch/codehost/git_test.go
+++ b/src/cmd/go/internal/modfetch/codehost/git_test.go
@@ -8,7 +8,6 @@
 	"archive/zip"
 	"bytes"
 	"flag"
-	"fmt"
 	"internal/testenv"
 	"io"
 	"io/fs"
@@ -47,12 +46,6 @@
 var localGitRepo string
 
 func testMain(m *testing.M) int {
-	if _, err := exec.LookPath("git"); err != nil {
-		fmt.Fprintln(os.Stderr, "skipping because git binary not found")
-		fmt.Println("PASS")
-		return 0
-	}
-
 	dir, err := os.MkdirTemp("", "gitrepo-test-")
 	if err != nil {
 		log.Fatal(err)
@@ -60,23 +53,25 @@
 	defer os.RemoveAll(dir)
 
 	if testenv.HasExternalNetwork() && testenv.HasExec() {
-		// Clone gitrepo1 into a local directory.
-		// If we use a file:// URL to access the local directory,
-		// then git starts up all the usual protocol machinery,
-		// which will let us test remote git archive invocations.
-		localGitRepo = filepath.Join(dir, "gitrepo2")
-		if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
-			log.Fatal(err)
-		}
-		if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
-			log.Fatal(err)
+		if _, err := exec.LookPath("git"); err == nil {
+			// Clone gitrepo1 into a local directory.
+			// If we use a file:// URL to access the local directory,
+			// then git starts up all the usual protocol machinery,
+			// which will let us test remote git archive invocations.
+			localGitRepo = filepath.Join(dir, "gitrepo2")
+			if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
+				log.Fatal(err)
+			}
+			if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
+				log.Fatal(err)
+			}
 		}
 	}
 
 	return m.Run()
 }
 
-func testRepo(remote string) (Repo, error) {
+func testRepo(t *testing.T, remote string) (Repo, error) {
 	if remote == "localGitRepo" {
 		// Convert absolute path to file URL. LocalGitRepo will not accept
 		// Windows absolute paths because they look like a host:path remote.
@@ -87,15 +82,17 @@
 		} else {
 			url = "file:///" + filepath.ToSlash(localGitRepo)
 		}
+		testenv.MustHaveExecPath(t, "git")
 		return LocalGitRepo(url)
 	}
-	kind := "git"
+	vcs := "git"
 	for _, k := range []string{"hg"} {
 		if strings.Contains(remote, "/"+k+"/") {
-			kind = k
+			vcs = k
 		}
 	}
-	return NewRepo(kind, remote)
+	testenv.MustHaveExecPath(t, vcs)
+	return NewRepo(vcs, remote)
 }
 
 var tagsTests = []struct {
@@ -116,7 +113,7 @@
 
 	for _, tt := range tagsTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -168,7 +165,7 @@
 
 	for _, tt := range latestTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -221,7 +218,7 @@
 
 	for _, tt := range readFileTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -412,7 +409,7 @@
 
 	for _, tt := range readZipTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -581,7 +578,7 @@
 
 	for _, tt := range statTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}