Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 42 additions & 38 deletions testscript/exe.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,50 +50,54 @@ func Main(m TestingM, commands map[string]func()) {
if mainf == nil {
// Unknown command; this is just the top-level execution of the
// test binary by "go test".
os.Exit(testingMRun(m, commands))
}
// The command being registered is being invoked, so run it, then exit.
os.Args[0] = cmdName
mainf()
os.Exit(0)
}

// Set up all commands in a directory, added in $PATH.
tmpdir, err := os.MkdirTemp("", "testscript-main")
if err != nil {
log.Fatalf("could not set up temporary directory: %v", err)
}
defer func() {
if err := os.RemoveAll(tmpdir); err != nil {
log.Fatalf("cannot delete temporary directory: %v", err)
}
}()
bindir := filepath.Join(tmpdir, "bin")
if err := os.MkdirAll(bindir, 0o777); err != nil {
log.Fatalf("could not set up PATH binary directory: %v", err)
// testingMRun exists just so that we can use `defer`, given that [Main] above uses [os.Exit].
func testingMRun(m TestingM, commands map[string]func()) int {
// Set up all commands in a directory, added in $PATH.
tmpdir, err := os.MkdirTemp("", "testscript-main")
if err != nil {
log.Fatalf("could not set up temporary directory: %v", err)
}
defer func() {
if err := os.RemoveAll(tmpdir); err != nil {
log.Fatalf("cannot delete temporary directory: %v", err)
}
os.Setenv("PATH", bindir+string(filepath.ListSeparator)+os.Getenv("PATH"))
}()
bindir := filepath.Join(tmpdir, "bin")
if err := os.MkdirAll(bindir, 0o777); err != nil {
log.Fatalf("could not set up PATH binary directory: %v", err)
}
os.Setenv("PATH", bindir+string(filepath.ListSeparator)+os.Getenv("PATH"))

// We're not in a subcommand.
for name := range commands {
// Set up this command in the directory we added to $PATH.
binfile := filepath.Join(bindir, name)
if runtime.GOOS == "windows" {
binfile += ".exe"
}
binpath, err := os.Executable()
if err == nil {
err = copyBinary(binpath, binfile)
}
if err != nil {
log.Fatalf("could not set up %s in $PATH: %v", name, err)
}
scriptCmds[name] = func(ts *TestScript, neg bool, args []string) {
if ts.params.RequireExplicitExec {
ts.Fatalf("use 'exec %s' rather than '%s' (because RequireExplicitExec is enabled)", name, name)
}
ts.cmdExec(neg, append([]string{name}, args...))
// We're not in a subcommand.
for name := range commands {
// Set up this command in the directory we added to $PATH.
binfile := filepath.Join(bindir, name)
if runtime.GOOS == "windows" {
binfile += ".exe"
}
binpath, err := os.Executable()
if err == nil {
err = copyBinary(binpath, binfile)
}
if err != nil {
log.Fatalf("could not set up %s in $PATH: %v", name, err)
}
scriptCmds[name] = func(ts *TestScript, neg bool, args []string) {
if ts.params.RequireExplicitExec {
ts.Fatalf("use 'exec %s' rather than '%s' (because RequireExplicitExec is enabled)", name, name)
}
ts.cmdExec(neg, append([]string{name}, args...))
}
os.Exit(m.Run())
}
// The command being registered is being invoked, so run it, then exit.
os.Args[0] = cmdName
mainf()
os.Exit(0)
return m.Run()
}

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