From 93dcb20e1290573bf2751add8d1963a7b878b83b Mon Sep 17 00:00:00 2001 From: masaushi Date: Sun, 26 Sep 2021 22:30:32 +0900 Subject: [PATCH] fix error in evaluating dynamic variables with newly created directory --- internal/execext/exec.go | 23 +++++++++++++++- task_test.go | 27 +++++++++++++++++++ .../dynamic_var_on_created_dir/Taskfile.yml | 10 +++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 testdata/dir/dynamic_var_on_created_dir/Taskfile.yml diff --git a/internal/execext/exec.go b/internal/execext/exec.go index 851fd2bd..cfdb578c 100644 --- a/internal/execext/exec.go +++ b/internal/execext/exec.go @@ -47,10 +47,10 @@ func RunCommand(ctx context.Context, opts *RunCommandOptions) error { r, err := interp.New( interp.Params("-e"), - interp.Dir(opts.Dir), interp.Env(expand.ListEnviron(environ...)), interp.OpenHandler(openHandler), interp.StdIO(opts.Stdin, opts.Stdout, opts.Stderr), + dirOption(opts.Dir), ) if err != nil { return err @@ -87,3 +87,24 @@ func openHandler(ctx context.Context, path string, flag int, perm os.FileMode) ( } return interp.DefaultOpenHandler()(ctx, path, flag, perm) } + +func dirOption(path string) interp.RunnerOption { + return func(r *interp.Runner) error { + err := interp.Dir(path)(r) + if err == nil { + return nil + } + + // If the specified directory doesn't exist, it will be created later. + // Therefore, even if `interp.Dir` method returns an error, the + // directory path should be set only when the directory cannot be found. + if absPath, _ := filepath.Abs(path); absPath != "" { + if _, err := os.Stat(absPath); os.IsNotExist(err) { + r.Dir = absPath + return nil + } + } + + return err + } +} diff --git a/task_test.go b/task_test.go index 8ccc92d9..5931c404 100644 --- a/task_test.go +++ b/task_test.go @@ -877,6 +877,33 @@ func TestWhenDirAttributeItCreatesMissingAndRunsInThatDir(t *testing.T) { _ = os.RemoveAll(toBeCreated) } +func TestDynamicVariablesRunOnTheNewCreatedDir(t *testing.T) { + const expected = "created" + const dir = "testdata/dir/dynamic_var_on_created_dir/" + const toBeCreated = dir + expected + const target = "default" + var out bytes.Buffer + e := &task.Executor{ + Dir: dir, + Stdout: &out, + Stderr: &out, + } + + // Ensure that the directory to be created doesn't actually exist. + _ = os.RemoveAll(toBeCreated) + if _, err := os.Stat(toBeCreated); err == nil { + t.Errorf("Directory should not exist: %v", err) + } + assert.NoError(t, e.Setup()) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: target})) + + got := strings.TrimSuffix(filepath.Base(out.String()), "\n") + assert.Equal(t, expected, got, "Mismatch in the working directory") + + // Clean-up after ourselves only if no error. + _ = os.RemoveAll(toBeCreated) +} + func TestDynamicVariablesShouldRunOnTheTaskDir(t *testing.T) { tt := fileContentTest{ Dir: "testdata/dir/dynamic_var", diff --git a/testdata/dir/dynamic_var_on_created_dir/Taskfile.yml b/testdata/dir/dynamic_var_on_created_dir/Taskfile.yml new file mode 100644 index 00000000..f2769309 --- /dev/null +++ b/testdata/dir/dynamic_var_on_created_dir/Taskfile.yml @@ -0,0 +1,10 @@ +version: '3' + +tasks: + default: + dir: created + cmds: + - echo {{.TASK_DIR}} + vars: + TASK_DIR: + sh: echo $(pwd)