Skip to content

Commit 31b9365

Browse files
abhinavmvdan
authored andcommitted
testscript: Add Chdir method to change directory
It is not currently possible for a custom testscript command to change the working directory of that script run. `TestScript.Exec` runs the command in a subprocess, so one cannot do `ts.Exec("cd", dir)`. This change adds a `Chdir` method to `TestScript` that allows changing the working directory of the script. The implementation is the same as the "cd" command, which now relies on `Chdir`. The availability of this function matches similar functionality in the [`State.Chdir` method of rsc.io/script][1]. (I ported some tests from rsc.io/script to testscript.) [1]: https://pkg.go.dev/rsc.io/script#State.Chdir
1 parent 9d241da commit 31b9365

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

testscript/cmd.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,11 @@ func (ts *TestScript) cmdCd(neg bool, args []string) {
6161
}
6262

6363
dir := args[0]
64-
if !filepath.IsAbs(dir) {
65-
dir = filepath.Join(ts.cd, dir)
66-
}
67-
info, err := os.Stat(dir)
64+
err := ts.Chdir(dir)
6865
if os.IsNotExist(err) {
6966
ts.Fatalf("directory %s does not exist", dir)
7067
}
7168
ts.Check(err)
72-
if !info.IsDir() {
73-
ts.Fatalf("%s is not a directory", dir)
74-
}
75-
ts.cd = dir
7669
ts.Logf("%s\n", ts.cd)
7770
}
7871

testscript/testdata/custom_cd.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Verify that a custom command can chdir.
2+
3+
mkChdir foo
4+
exists $WORK/foo
5+
6+
# Current directory is not $WORK.
7+
! exists foo

testscript/testscript.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,24 @@ func (ts *TestScript) BackgroundCmds() []*exec.Cmd {
10431043
return cmds
10441044
}
10451045

1046+
// Chdir changes the current directory of the script.
1047+
// The path may be relative to the current directory.
1048+
func (ts *TestScript) Chdir(dir string) error {
1049+
if !filepath.IsAbs(dir) {
1050+
dir = filepath.Join(ts.cd, dir)
1051+
}
1052+
info, err := os.Stat(dir)
1053+
if err != nil {
1054+
return err
1055+
}
1056+
if !info.IsDir() {
1057+
return fmt.Errorf("%s is not a directory", dir)
1058+
}
1059+
1060+
ts.cd = dir
1061+
return nil
1062+
}
1063+
10461064
// waitOrStop waits for the already-started command cmd by calling its Wait method.
10471065
//
10481066
// If cmd does not return before ctx is done, waitOrStop sends it an interrupt

testscript/testscript_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,27 @@ func TestScripts(t *testing.T) {
263263
}
264264
},
265265
"echoandexit": echoandexit,
266+
"mkChdir": func(ts *TestScript, neg bool, args []string) {
267+
if neg {
268+
ts.Fatalf("unsupported: ! mkChdir")
269+
}
270+
if len(args) != 1 {
271+
ts.Fatalf("usage: mkChdir dir")
272+
}
273+
274+
dir := args[0]
275+
if !filepath.IsAbs(dir) {
276+
dir = ts.MkAbs(dir)
277+
}
278+
279+
if err := os.MkdirAll(dir, 0o777); err != nil {
280+
ts.Fatalf("cannot create dir: %v", err)
281+
}
282+
283+
if err := ts.Chdir(dir); err != nil {
284+
ts.Fatalf("cannot chdir: %v", err)
285+
}
286+
},
266287
},
267288
Setup: func(env *Env) error {
268289
infos, err := os.ReadDir(env.WorkDir)

0 commit comments

Comments
 (0)