Source file
src/cmd/go/scriptconds_test.go
1
2
3
4
5 package main_test
6
7 import (
8 "cmd/go/internal/cfg"
9 "cmd/internal/script"
10 "cmd/internal/script/scripttest"
11 "errors"
12 "fmt"
13 "internal/buildcfg"
14 "os"
15 "os/exec"
16 "path/filepath"
17 "regexp"
18 "runtime"
19 "runtime/debug"
20 "testing"
21
22 "golang.org/x/mod/semver"
23 )
24
25 func scriptConditions(t *testing.T) map[string]script.Cond {
26 conds := scripttest.DefaultConds()
27
28 scripttest.AddToolChainScriptConditions(t, conds, goHostOS, goHostArch)
29
30 add := func(name string, cond script.Cond) {
31 if _, ok := conds[name]; ok {
32 panic(fmt.Sprintf("condition %q is already registered", name))
33 }
34 conds[name] = cond
35 }
36
37 lazyBool := func(summary string, f func() bool) script.Cond {
38 return script.OnceCondition(summary, func() (bool, error) { return f(), nil })
39 }
40
41 add("abscc", script.Condition("default $CC path is absolute and exists", defaultCCIsAbsolute))
42 add("case-sensitive", script.OnceCondition("$WORK filesystem is case-sensitive", isCaseSensitive))
43 add("cc", script.PrefixCondition("go env CC = <suffix> (ignoring the go/env file)", ccIs))
44 add("git", lazyBool("the 'git' executable exists and provides the standard CLI", hasWorkingGit))
45 add("git-sha256", script.OnceCondition("the local 'git' version is recent enough to support sha256 object/commit hashes", gitSupportsSHA256))
46 add("trimpath", script.OnceCondition("test binary was built with -trimpath", isTrimpath))
47 add("default-cgo", lazyBool("when CGO_ENABLED=1|0 was set in make.bash", defaultCgo))
48
49 return conds
50 }
51
52 func defaultCCIsAbsolute(s *script.State) (bool, error) {
53 GOOS, _ := s.LookupEnv("GOOS")
54 GOARCH, _ := s.LookupEnv("GOARCH")
55 defaultCC := cfg.DefaultCC(GOOS, GOARCH)
56 if filepath.IsAbs(defaultCC) {
57 if _, err := exec.LookPath(defaultCC); err == nil {
58 return true, nil
59 }
60 }
61 return false, nil
62 }
63
64 func ccIs(s *script.State, want string) (bool, error) {
65 CC, _ := s.LookupEnv("CC")
66 if CC != "" {
67 return CC == want, nil
68 }
69 GOOS, _ := s.LookupEnv("GOOS")
70 GOARCH, _ := s.LookupEnv("GOARCH")
71 return cfg.DefaultCC(GOOS, GOARCH) == want, nil
72 }
73
74 func isCaseSensitive() (bool, error) {
75 tmpdir, err := os.MkdirTemp(testTmpDir, "case-sensitive")
76 if err != nil {
77 return false, fmt.Errorf("failed to create directory to determine case-sensitivity: %w", err)
78 }
79 defer os.RemoveAll(tmpdir)
80
81 fcap := filepath.Join(tmpdir, "FILE")
82 if err := os.WriteFile(fcap, []byte{}, 0644); err != nil {
83 return false, fmt.Errorf("error writing file to determine case-sensitivity: %w", err)
84 }
85
86 flow := filepath.Join(tmpdir, "file")
87 _, err = os.ReadFile(flow)
88 switch {
89 case err == nil:
90 return false, nil
91 case os.IsNotExist(err):
92 return true, nil
93 default:
94 return false, fmt.Errorf("unexpected error reading file when determining case-sensitivity: %w", err)
95 }
96 }
97
98 func isTrimpath() (bool, error) {
99 info, _ := debug.ReadBuildInfo()
100 if info == nil {
101 return false, errors.New("missing build info")
102 }
103
104 for _, s := range info.Settings {
105 if s.Key == "-trimpath" && s.Value == "true" {
106 return true, nil
107 }
108 }
109 return false, nil
110 }
111
112 func hasWorkingGit() bool {
113 if runtime.GOOS == "plan9" {
114
115
116 return false
117 }
118 _, err := exec.LookPath("git")
119 return err == nil
120 }
121
122
123 var gitVersLineExtract = regexp.MustCompile(`git version\s+(\d+\.\d+(?:\.\d+)?)`)
124
125 func gitVersion() (string, error) {
126 gitOut, runErr := exec.Command("git", "version").CombinedOutput()
127 if runErr != nil {
128 return "v0", fmt.Errorf("failed to execute git version: %w", runErr)
129 }
130 matches := gitVersLineExtract.FindSubmatch(gitOut)
131 if len(matches) < 2 {
132 return "v0", fmt.Errorf("git version extraction regexp did not match version line: %q", gitOut)
133 }
134 return "v" + string(matches[1]), nil
135 }
136
137 func hasAtLeastGitVersion(minVers string) (bool, error) {
138 gitVers, gitVersErr := gitVersion()
139 if gitVersErr != nil {
140 return false, gitVersErr
141 }
142 return semver.Compare(minVers, gitVers) <= 0, nil
143 }
144
145 func gitSupportsSHA256() (bool, error) {
146 return hasAtLeastGitVersion("v2.29")
147 }
148
149 func defaultCgo() bool {
150 return buildcfg.DefaultCGO_ENABLED == "1" || buildcfg.DefaultCGO_ENABLED == "0"
151 }
152
View as plain text