Skip to content

Commit a900337

Browse files
Bryan C. Millsheschi
Bryan C. Mills
authored andcommitted
[release-branch.go1.17] cmd/dist: consistently set PWD when executing a command in a different directory
Fixes #52995 Updates #33598 Change-Id: If0de906ffa2fcc83bb2a90f9e80a5b29d7667398 Reviewed-on: https://go-review.googlesource.com/c/go/+/353449 Trust: Bryan C. Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> (cherry picked from commit c035d82) Reviewed-on: https://go-review.googlesource.com/c/go/+/407881 Reviewed-by: Heschi Kreinick <[email protected]> Run-TryBot: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 0e7138a commit a900337

File tree

3 files changed

+80
-29
lines changed

3 files changed

+80
-29
lines changed

src/cmd/dist/exec.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"os"
9+
"os/exec"
10+
"strings"
11+
)
12+
13+
// setDir sets cmd.Dir to dir, and also adds PWD=dir to cmd's environment.
14+
func setDir(cmd *exec.Cmd, dir string) {
15+
cmd.Dir = dir
16+
setEnv(cmd, "PWD", dir)
17+
}
18+
19+
// setEnv sets cmd.Env so that key = value.
20+
//
21+
// It first removes any existing values for key, so it is safe to call
22+
// even from within cmdbootstrap.
23+
func setEnv(cmd *exec.Cmd, key, value string) {
24+
kv := key + "=" + value
25+
if cmd.Env == nil {
26+
cmd.Env = os.Environ()
27+
}
28+
29+
prefix := kv[:len(key)+1]
30+
for i, entry := range cmd.Env {
31+
if strings.HasPrefix(entry, prefix) {
32+
cmd.Env[i] = kv
33+
return
34+
}
35+
}
36+
37+
cmd.Env = append(cmd.Env, kv)
38+
}
39+
40+
// unsetEnv sets cmd.Env so that key is not present in the environment.
41+
func unsetEnv(cmd *exec.Cmd, key string) {
42+
if cmd.Env == nil {
43+
cmd.Env = os.Environ()
44+
}
45+
46+
prefix := key + "="
47+
for i, entry := range cmd.Env {
48+
if strings.HasPrefix(entry, prefix) {
49+
cmd.Env = append(cmd.Env[:i], cmd.Env[i+1:]...)
50+
return
51+
}
52+
}
53+
}

src/cmd/dist/test.go

+26-28
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,8 @@ func (t *tester) registerTests() {
522522
heading: "GOOS=ios on darwin/amd64",
523523
fn: func(dt *distTest) error {
524524
cmd := t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-run=SystemRoots", "crypto/x509")
525-
cmd.Env = append(os.Environ(), "GOOS=ios", "CGO_ENABLED=1")
525+
setEnv(cmd, "GOOS", "ios")
526+
setEnv(cmd, "CGO_ENABLED", "1")
526527
return nil
527528
},
528529
})
@@ -542,7 +543,7 @@ func (t *tester) registerTests() {
542543
cmd := t.addCmd(dt, "src", t.goTest(), t.timeout(300), "runtime", "-cpu=1,2,4", "-quick")
543544
// We set GOMAXPROCS=2 in addition to -cpu=1,2,4 in order to test runtime bootstrap code,
544545
// creation of first goroutines and first garbage collections in the parallel setting.
545-
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
546+
setEnv(cmd, "GOMAXPROCS", "2")
546547
return nil
547548
},
548549
})
@@ -563,7 +564,7 @@ func (t *tester) registerTests() {
563564
return nil
564565
}
565566
cmd := exec.Command("go", "test")
566-
cmd.Dir = filepath.Join(os.Getenv("GOROOT"), "src/cmd/go/testdata/testterminal18153")
567+
setDir(cmd, filepath.Join(os.Getenv("GOROOT"), "src/cmd/go/testdata/testterminal18153"))
567568
cmd.Stdout = os.Stdout
568569
cmd.Stderr = os.Stderr
569570
return cmd.Run()
@@ -600,16 +601,13 @@ func (t *tester) registerTests() {
600601
return err
601602
}
602603

603-
// Run `go test fmt` in the moved GOROOT.
604+
// Run `go test fmt` in the moved GOROOT, without explicitly setting
605+
// GOROOT in the environment. The 'go' command should find itself.
604606
cmd := exec.Command(filepath.Join(moved, "bin", "go"), "test", "fmt")
605607
cmd.Stdout = os.Stdout
606608
cmd.Stderr = os.Stderr
607-
// Don't set GOROOT in the environment.
608-
for _, e := range os.Environ() {
609-
if !strings.HasPrefix(e, "GOROOT=") && !strings.HasPrefix(e, "GOCACHE=") {
610-
cmd.Env = append(cmd.Env, e)
611-
}
612-
}
609+
unsetEnv(cmd, "GOROOT")
610+
unsetEnv(cmd, "GOCACHE") // TODO(bcmills): ...why‽
613611
err := cmd.Run()
614612

615613
if rerr := os.Rename(moved, goroot); rerr != nil {
@@ -736,11 +734,9 @@ func (t *tester) registerTests() {
736734
heading: "../misc/swig/callback",
737735
fn: func(dt *distTest) error {
738736
cmd := t.addCmd(dt, "misc/swig/callback", t.goTest())
739-
cmd.Env = append(os.Environ(),
740-
"CGO_CFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
741-
"CGO_CXXFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
742-
"CGO_LDFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
743-
)
737+
setEnv(cmd, "CGO_CFLAGS", "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option")
738+
setEnv(cmd, "CGO_CXXFLAGS", "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option")
739+
setEnv(cmd, "CGO_LDFLAGS", "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option")
744740
return nil
745741
},
746742
},
@@ -892,9 +888,9 @@ func (t *tester) registerSeqTest(name, dirBanner string, cmdline ...interface{})
892888
func (t *tester) bgDirCmd(dir, bin string, args ...string) *exec.Cmd {
893889
cmd := exec.Command(bin, args...)
894890
if filepath.IsAbs(dir) {
895-
cmd.Dir = dir
891+
setDir(cmd, dir)
896892
} else {
897-
cmd.Dir = filepath.Join(goroot, dir)
893+
setDir(cmd, filepath.Join(goroot, dir))
898894
}
899895
return cmd
900896
}
@@ -1132,7 +1128,8 @@ func (t *tester) runHostTest(dir, pkg string) error {
11321128
defer os.Remove(f.Name())
11331129

11341130
cmd := t.dirCmd(dir, t.goTest(), "-c", "-o", f.Name(), pkg)
1135-
cmd.Env = append(os.Environ(), "GOARCH="+gohostarch, "GOOS="+gohostos)
1131+
setEnv(cmd, "GOARCH", gohostarch)
1132+
setEnv(cmd, "GOOS", gohostos)
11361133
if err := cmd.Run(); err != nil {
11371134
return err
11381135
}
@@ -1141,15 +1138,15 @@ func (t *tester) runHostTest(dir, pkg string) error {
11411138

11421139
func (t *tester) cgoTest(dt *distTest) error {
11431140
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest())
1144-
cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=auto")
1141+
setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=auto")
11451142

11461143
// Skip internal linking cases on linux/arm64 to support GCC-9.4 and above.
11471144
// See issue #39466.
11481145
skipInternalLink := goarch == "arm64" && goos == "linux"
11491146

11501147
if t.internalLink() && !skipInternalLink {
11511148
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=internal")
1152-
cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=internal")
1149+
setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=internal")
11531150
}
11541151

11551152
pair := gohostos + "-" + goarch
@@ -1161,9 +1158,9 @@ func (t *tester) cgoTest(dt *distTest) error {
11611158
break
11621159
}
11631160
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest())
1164-
cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=external")
1161+
setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=external")
11651162

1166-
cmd = t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external -s")
1163+
t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external -s")
11671164

11681165
if t.supportedBuildmode("pie") {
11691166
t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie")
@@ -1181,10 +1178,10 @@ func (t *tester) cgoTest(dt *distTest) error {
11811178
"openbsd-386", "openbsd-amd64", "openbsd-arm", "openbsd-arm64", "openbsd-mips64":
11821179

11831180
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest())
1184-
cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=external")
1181+
setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=external")
11851182
// cgo should be able to cope with both -g arguments and colored
11861183
// diagnostics.
1187-
cmd.Env = append(cmd.Env, "CGO_CFLAGS=-g0 -fdiagnostics-color")
1184+
setEnv(cmd, "CGO_CFLAGS", "-g0 -fdiagnostics-color")
11881185

11891186
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=auto")
11901187
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=external")
@@ -1217,7 +1214,7 @@ func (t *tester) cgoTest(dt *distTest) error {
12171214
// than -static in -extldflags, so test both.
12181215
// See issue #16651.
12191216
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=static")
1220-
cmd.Env = append(os.Environ(), "CGO_LDFLAGS=-static -pthread")
1217+
setEnv(cmd, "CGO_LDFLAGS", "-static -pthread")
12211218
}
12221219
}
12231220

@@ -1456,7 +1453,7 @@ func (t *tester) raceTest(dt *distTest) error {
14561453
// We shouldn't need to redo all of misc/cgo/test too.
14571454
// The race buildler will take care of this.
14581455
// cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-race")
1459-
// cmd.Env = append(os.Environ(), "GOTRACEBACK=2")
1456+
// setEnv(cmd, "GOTRACEBACK", "2")
14601457
}
14611458
if t.extLink() {
14621459
// Test with external linking; see issue 9133.
@@ -1486,7 +1483,8 @@ func (t *tester) testDirTest(dt *distTest, shard, shards int) error {
14861483
})
14871484

14881485
cmd := t.dirCmd("test", "go", "build", "-o", runtest.exe, "run.go")
1489-
cmd.Env = append(os.Environ(), "GOOS="+gohostos, "GOARCH="+gohostarch)
1486+
setEnv(cmd, "GOOS", gohostos)
1487+
setEnv(cmd, "GOARCH", gohostarch)
14901488
runtest.err = cmd.Run()
14911489
})
14921490
if runtest.err != nil {
@@ -1650,7 +1648,7 @@ func (t *tester) runPrecompiledStdTest(timeout time.Duration) error {
16501648
bin := t.prebuiltGoPackageTestBinary()
16511649
fmt.Fprintf(os.Stderr, "# %s: using pre-built %s...\n", stdMatches[0], bin)
16521650
cmd := exec.Command(bin, "-test.short="+short(), "-test.timeout="+timeout.String())
1653-
cmd.Dir = filepath.Dir(bin)
1651+
setDir(cmd, filepath.Dir(bin))
16541652
cmd.Stdout = os.Stdout
16551653
cmd.Stderr = os.Stderr
16561654
if err := cmd.Start(); err != nil {

src/cmd/dist/util.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func run(dir string, mode int, cmd ...string) string {
7272
}
7373

7474
xcmd := exec.Command(cmd[0], cmd[1:]...)
75-
xcmd.Dir = dir
75+
setDir(xcmd, dir)
7676
var data []byte
7777
var err error
7878

0 commit comments

Comments
 (0)