diff --git a/testscript/testdata/nothing/nothing.txt b/testscript/testdata/nothing/nothing.txt new file mode 100644 index 00000000..c0ff0eae --- /dev/null +++ b/testscript/testdata/nothing/nothing.txt @@ -0,0 +1,5 @@ +# Intentionally empty test script; used to test Params.WorkdirRoot + +-- README.md -- +This file exists so that a test for Params.WorkdirRoot can verify the existence of a file +within WorkdirRoot/script-nothing once scripts have finished. diff --git a/testscript/testscript.go b/testscript/testscript.go index 700c12a7..b440d748 100644 --- a/testscript/testscript.go +++ b/testscript/testscript.go @@ -97,6 +97,12 @@ type Params struct { // left intact for later inspection. TestWork bool + // WorkdirRoot specifies the directory within which scripts' work + // directories will be created. Setting WorkdirRoot implies TestWork=true. + // If empty, the work directories will be created inside + // $GOTMPDIR/go-test-script*, where $GOTMPDIR defaults to os.TempDir(). + WorkdirRoot string + // IgnoreMissedCoverage specifies that if coverage information // is being generated (with the -test.coverprofile flag) and a subcommand // function passed to RunMain fails to generate coverage information @@ -160,9 +166,14 @@ func RunT(t T, p Params) { if len(files) == 0 { t.Fatal(fmt.Sprintf("no scripts found matching glob: %v", glob)) } - testTempDir, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-test-script") - if err != nil { - t.Fatal(err) + testTempDir := p.WorkdirRoot + if testTempDir == "" { + testTempDir, err = ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-test-script") + if err != nil { + t.Fatal(err) + } + } else { + p.TestWork = true } // The temp dir returned by ioutil.TempDir might be a sym linked dir (default // behaviour in macOS). That could mess up matching that includes $WORK if, @@ -528,7 +539,7 @@ func (ts *TestScript) condition(cond string) (bool, error) { // abbrev abbreviates the actual work directory in the string s to the literal string "$WORK". func (ts *TestScript) abbrev(s string) string { s = strings.Replace(s, ts.workdir, "$WORK", -1) - if *testWork { + if *testWork || ts.params.TestWork { // Expose actual $WORK value in environment dump on first line of work script, // so that the user can find out what directory -testwork left behind. s = "WORK=" + ts.workdir + "\n" + strings.TrimPrefix(s, "WORK=$WORK\n") diff --git a/testscript/testscript_test.go b/testscript/testscript_test.go index caf60732..ac97400d 100644 --- a/testscript/testscript_test.go +++ b/testscript/testscript_test.go @@ -203,6 +203,32 @@ func TestTestwork(t *testing.T) { } } +// TestWorkdirRoot tests that a non zero value in Params.WorkdirRoot is honoured +func TestWorkdirRoot(t *testing.T) { + td, err := ioutil.TempDir("", "") + if err != nil { + t.Fatalf("failed to create temp dir: %v", err) + } + defer os.RemoveAll(td) + params := Params{ + Dir: filepath.Join("testdata", "nothing"), + WorkdirRoot: td, + } + // Run as a sub-test so that this call blocks until the sub-tests created by + // calling Run (which themselves call t.Parallel) complete. + t.Run("run tests", func(t *testing.T) { + Run(t, params) + }) + // Verify that we have a single go-test-script-* named directory + files, err := filepath.Glob(filepath.Join(td, "script-nothing", "README.md")) + if err != nil { + t.Fatal(err) + } + if len(files) != 1 { + t.Fatalf("unexpected files found for kept files; got %q", files) + } +} + // TestBadDir verifies that invoking testscript with a directory that either // does not exist or that contains no *.txt scripts fails the test func TestBadDir(t *testing.T) {