Skip to content

Commit

Permalink
interp: record runner state at the first Reset call
Browse files Browse the repository at this point in the history
This is perhaps a bit confusing, but it's a good middle ground. This
lets us support Reset while not undoing changes that the user has done
outside of New, which is common.

The downside is that making any changes after the first call to Run or
Reset are undone by further calls to Reset. However, that's fine; Reset
is meant to return a runner to its initial state, not any other previous
or arbitrary state.
  • Loading branch information
mvdan committed Mar 18, 2019
1 parent cf97eb2 commit 6f9e3e5
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
18 changes: 10 additions & 8 deletions interp/interp.go
Expand Up @@ -57,12 +57,6 @@ func New(opts ...func(*Runner) error) (*Runner, error) {
if r.Stdout == nil || r.Stderr == nil {
StdIO(r.Stdin, r.Stdout, r.Stderr)(r)
}
r.origDir = r.Dir
r.origParams = r.Params
r.origOpts = r.opts
r.origStdin = r.Stdin
r.origStdout = r.Stdout
r.origStderr = r.Stderr
return r, nil
}

Expand Down Expand Up @@ -494,8 +488,8 @@ const (
optGlobStar
)

// Reset returns a runner to its initial state, before any programs were
// interpreted via the Run method.
// Reset returns a runner to its initial state, right before the first call to
// Run or Reset.
//
// Typically, this function only needs to be called if a runner is reused to run
// multiple programs non-incrementally. Not calling Reset between each run will
Expand All @@ -505,6 +499,14 @@ func (r *Runner) Reset() {
if !r.usedNew {
panic("use interp.New to construct a Runner")
}
if !r.didReset {
r.origDir = r.Dir
r.origParams = r.Params
r.origOpts = r.opts
r.origStdin = r.Stdin
r.origStdout = r.Stdout
r.origStderr = r.Stderr
}
// reset the internal state
*r = Runner{
Env: r.Env,
Expand Down
10 changes: 9 additions & 1 deletion interp/interp_test.go
Expand Up @@ -2958,8 +2958,11 @@ func TestRunnerResetFields(t *testing.T) {
r, _ := New(
Params("-f", "--", "first", dir, logFile.Name()),
Dir(dir),
StdIO(nil, logFile, os.Stderr),
)
// Check that using option funcs and Runner fields directly is still
// kept by Reset.
StdIO(nil, logFile, os.Stderr)(r)
r.Env = expand.ListEnviron(append(os.Environ(), "GLOBAL=foo")...)

file := parse(t, nil, `
# Params set 3 arguments
Expand All @@ -2977,10 +2980,15 @@ echo line1
echo line2
[[ "$(wc -l <$3)" == "2" ]] || exit 14
# $GLOBAL was set directly via the Env field
[[ "$GLOBAL" == "foo" ]] || exit 15
# Change all of the above within the script. Reset should undo this.
set +f -- newargs
cd
exec >/dev/null 2>/dev/null
GLOBAL=
export GLOBAL=
`)
ctx := context.Background()
for i := 0; i < 3; i++ {
Expand Down

0 comments on commit 6f9e3e5

Please sign in to comment.