func NeedsGoPackages(t Testing) {
	if t, ok := t.(helperer); ok {
		t.Helper()
	}
	tool := os.Getenv("GOPACKAGESDRIVER")
	switch tool {
	case "off":
		tool = "go"
	case "":
		if _, err := exec.LookPath("gopackagesdriver"); err == nil {
			tool = "gopackagesdriver"
		} else {
			tool = "go"
		}
	}
	NeedsTool(t, tool)
}
NeedsGoPackages skips t if the go/packages driver (or 'go' tool) implied by
the current process environment is not present in the path.
package testenv
import (
	"bytes"
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	"os/exec"
	"runtime"
	"strings"
	"sync"
)
type Testing interface {
	Skipf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
}
type helperer interface {
	Helper()
}
var packageMainIsDevel = func() bool { return true }
var checkGoGoroot struct {
	once sync.Once
	err  error
}
func hasTool(tool string) error {
	if tool == "cgo" {
		enabled, err := cgoEnabled(false)
		if err != nil {
			return fmt.Errorf("checking cgo: %v", err)
		}
		if !enabled {
			return fmt.Errorf("cgo not enabled")
		}
		return nil
	}
	_, err := exec.LookPath(tool)
	if err != nil {
		return err
	}
	switch tool {
	case "patch":
		temp, err := ioutil.TempFile("", "patch-test")
		if err != nil {
			return err
		}
		temp.Close()
		defer os.Remove(temp.Name())
		cmd := exec.Command(tool, "-o", temp.Name())
		if err := cmd.Run(); err != nil {
			return err
		}
	case "go":
		checkGoGoroot.once.Do(func() {
			out, err := exec.Command(tool, "env", "GOROOT").CombinedOutput()
			if err != nil {
				checkGoGoroot.err = err
				return
			}
			GOROOT := strings.TrimSpace(string(out))
			if GOROOT != runtime.GOROOT() {
				checkGoGoroot.err = fmt.Errorf("'go env GOROOT' does not match runtime.GOROOT:\n\tgo env: %s\n\tGOROOT: %s", GOROOT, runtime.GOROOT())
			}
		})
		if checkGoGoroot.err != nil {
			return checkGoGoroot.err
		}
	case "diff":
		out, err := exec.Command(tool, "-version").Output()
		if err != nil {
			return err
		}
		if !bytes.Contains(out, []byte("GNU diffutils")) {
			return fmt.Errorf("diff is not the GNU version")
		}
	}
	return nil
}
func cgoEnabled(bypassEnvironment bool) (bool, error) {
	cmd := exec.Command("go", "env", "CGO_ENABLED")
	if bypassEnvironment {
		cmd.Env = append(append([]string(nil), os.Environ()...), "CGO_ENABLED=")
	}
	out, err := cmd.CombinedOutput()
	if err != nil {
		return false, err
	}
	enabled := strings.TrimSpace(string(out))
	return enabled == "1", nil
}
func allowMissingTool(tool string) bool {
	if runtime.GOOS == "android" {
		return true
	}
	switch tool {
	case "cgo":
		if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-nocgo") {
			return true
		}
		if enabled, err := cgoEnabled(true); err == nil && !enabled {
			return true
		}
	case "go":
		if os.Getenv("GO_BUILDER_NAME") == "illumos-amd64-joyent" {
			return true
		}
	case "diff":
		if os.Getenv("GO_BUILDER_NAME") != "" {
			return true
		}
	case "patch":
		if os.Getenv("GO_BUILDER_NAME") != "" {
			return true
		}
	}
	return !packageMainIsDevel()
}
func NeedsTool(t Testing, tool string) {
	if t, ok := t.(helperer); ok {
		t.Helper()
	}
	err := hasTool(tool)
	if err == nil {
		return
	}
	if allowMissingTool(tool) {
		t.Skipf("skipping because %s tool not available: %v", tool, err)
	} else {
		t.Fatalf("%s tool not available: %v", tool, err)
	}
}