Skip to content

Commit 9ee3698

Browse files
committed
testscript: remove temp dirs when finishing once again
The recent transition from RunMain to Main meant that we started calling os.Exit directly when Main finished. However, we failed to spot that os.Exit would make our earlier deferred cleanup of the temporary directory not run at all. Spotted because my /tmp started getting filled up after a few hours of development, and I found a suspiciously large number of testscript-looking directories.
1 parent eb18234 commit 9ee3698

File tree

1 file changed

+42
-38
lines changed

1 file changed

+42
-38
lines changed

testscript/exe.go

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,50 +50,54 @@ func Main(m TestingM, commands map[string]func()) {
5050
if mainf == nil {
5151
// Unknown command; this is just the top-level execution of the
5252
// test binary by "go test".
53+
os.Exit(testingMRun(m, commands))
54+
}
55+
// The command being registered is being invoked, so run it, then exit.
56+
os.Args[0] = cmdName
57+
mainf()
58+
os.Exit(0)
59+
}
5360

54-
// Set up all commands in a directory, added in $PATH.
55-
tmpdir, err := os.MkdirTemp("", "testscript-main")
56-
if err != nil {
57-
log.Fatalf("could not set up temporary directory: %v", err)
58-
}
59-
defer func() {
60-
if err := os.RemoveAll(tmpdir); err != nil {
61-
log.Fatalf("cannot delete temporary directory: %v", err)
62-
}
63-
}()
64-
bindir := filepath.Join(tmpdir, "bin")
65-
if err := os.MkdirAll(bindir, 0o777); err != nil {
66-
log.Fatalf("could not set up PATH binary directory: %v", err)
61+
// testingMRun exists just so that we can use `defer`, given that [Main] above uses [os.Exit].
62+
func testingMRun(m TestingM, commands map[string]func()) int {
63+
// Set up all commands in a directory, added in $PATH.
64+
tmpdir, err := os.MkdirTemp("", "testscript-main")
65+
if err != nil {
66+
log.Fatalf("could not set up temporary directory: %v", err)
67+
}
68+
defer func() {
69+
if err := os.RemoveAll(tmpdir); err != nil {
70+
log.Fatalf("cannot delete temporary directory: %v", err)
6771
}
68-
os.Setenv("PATH", bindir+string(filepath.ListSeparator)+os.Getenv("PATH"))
72+
}()
73+
bindir := filepath.Join(tmpdir, "bin")
74+
if err := os.MkdirAll(bindir, 0o777); err != nil {
75+
log.Fatalf("could not set up PATH binary directory: %v", err)
76+
}
77+
os.Setenv("PATH", bindir+string(filepath.ListSeparator)+os.Getenv("PATH"))
6978

70-
// We're not in a subcommand.
71-
for name := range commands {
72-
// Set up this command in the directory we added to $PATH.
73-
binfile := filepath.Join(bindir, name)
74-
if runtime.GOOS == "windows" {
75-
binfile += ".exe"
76-
}
77-
binpath, err := os.Executable()
78-
if err == nil {
79-
err = copyBinary(binpath, binfile)
80-
}
81-
if err != nil {
82-
log.Fatalf("could not set up %s in $PATH: %v", name, err)
83-
}
84-
scriptCmds[name] = func(ts *TestScript, neg bool, args []string) {
85-
if ts.params.RequireExplicitExec {
86-
ts.Fatalf("use 'exec %s' rather than '%s' (because RequireExplicitExec is enabled)", name, name)
87-
}
88-
ts.cmdExec(neg, append([]string{name}, args...))
79+
// We're not in a subcommand.
80+
for name := range commands {
81+
// Set up this command in the directory we added to $PATH.
82+
binfile := filepath.Join(bindir, name)
83+
if runtime.GOOS == "windows" {
84+
binfile += ".exe"
85+
}
86+
binpath, err := os.Executable()
87+
if err == nil {
88+
err = copyBinary(binpath, binfile)
89+
}
90+
if err != nil {
91+
log.Fatalf("could not set up %s in $PATH: %v", name, err)
92+
}
93+
scriptCmds[name] = func(ts *TestScript, neg bool, args []string) {
94+
if ts.params.RequireExplicitExec {
95+
ts.Fatalf("use 'exec %s' rather than '%s' (because RequireExplicitExec is enabled)", name, name)
8996
}
97+
ts.cmdExec(neg, append([]string{name}, args...))
9098
}
91-
os.Exit(m.Run())
9299
}
93-
// The command being registered is being invoked, so run it, then exit.
94-
os.Args[0] = cmdName
95-
mainf()
96-
os.Exit(0)
100+
return m.Run()
97101
}
98102

99103
// Deprecated: use [Main], as the only reason for returning exit codes

0 commit comments

Comments
 (0)