From 9a406f5998a0fbc15c80399339859d2bf5921f62 Mon Sep 17 00:00:00 2001 From: "Mads H. Danquah" Date: Thu, 27 Apr 2023 08:23:45 +0200 Subject: [PATCH] fix: ensure that calls to other tasks can be silenced (#680) --- task.go | 9 ++--- task_test.go | 74 ++++++++++++++++++++++++++++++++++++ taskfile/call.go | 5 ++- taskfile/cmd.go | 1 + taskfile/dep.go | 11 ++++-- testdata/silent/Taskfile.yml | 50 ++++++++++++++++++++++++ variables.go | 5 ++- 7 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 testdata/silent/Taskfile.yml diff --git a/task.go b/task.go index 9bb18f9e..e1c7dbfc 100644 --- a/task.go +++ b/task.go @@ -177,7 +177,7 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error { } if upToDate && preCondMet { - if e.Verbose || (!t.Silent && !e.Taskfile.Silent && !e.Silent) { + if e.Verbose || (!call.Silent && !t.Silent && !e.Taskfile.Silent && !e.Silent) { e.Logger.Errf(logger.Magenta, "task: Task %q is up to date\n", t.Name()) } return nil @@ -237,9 +237,8 @@ func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error { for _, d := range t.Deps { d := d - g.Go(func() error { - err := e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars}) + err := e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars, Silent: d.Silent}) if err != nil { return err } @@ -267,7 +266,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi reacquire := e.releaseConcurrencyLimit() defer reacquire() - err := e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars}) + err := e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars, Silent: cmd.Silent}) if err != nil { return err } @@ -278,7 +277,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi return nil } - if e.Verbose || (!cmd.Silent && !t.Silent && !e.Taskfile.Silent && !e.Silent) { + if e.Verbose || (!call.Silent && !cmd.Silent && !t.Silent && !e.Taskfile.Silent && !e.Silent) { e.Logger.Errf(logger.Green, "task: [%s] %s\n", t.Name(), cmd.Cmd) } diff --git a/task_test.go b/task_test.go index 0def5c0c..f727b776 100644 --- a/task_test.go +++ b/task_test.go @@ -1892,3 +1892,77 @@ func TestSplitArgs(t *testing.T) { require.NoError(t, err) assert.Equal(t, "3\n", buff.String()) } + +func TestSilence(t *testing.T) { + var buff bytes.Buffer + e := task.Executor{ + Dir: "testdata/silent", + Stdout: &buff, + Stderr: &buff, + Silent: false, + } + require.NoError(t, e.Setup()) + + // First verify that the silent flag is in place. + task, err := e.GetTask(taskfile.Call{Task: "task-test-silent-calls-chatty-silenced"}) + require.NoError(t, err, "Unable to look up task task-test-silent-calls-chatty-silenced") + require.True(t, task.Cmds[0].Silent, "The task task-test-silent-calls-chatty-silenced should have a silent call to chatty") + + // Then test the two basic cases where the task is silent or not. + // A silenced task. + err = e.Run(context.Background(), taskfile.Call{Task: "silent"}) + require.NoError(t, err) + require.Empty(t, buff.String(), "siWhile running lent: Expected not see output, because the task is silent") + + buff.Reset() + + // A chatty (not silent) task. + err = e.Run(context.Background(), taskfile.Call{Task: "chatty"}) + require.NoError(t, err) + require.NotEmpty(t, buff.String(), "chWhile running atty: Expected to see output, because the task is not silent") + + buff.Reset() + + // Then test invoking the two task from other tasks. + // A silenced task that calls a chatty task. + err = e.Run(context.Background(), taskfile.Call{Task: "task-test-silent-calls-chatty-non-silenced"}) + require.NoError(t, err) + require.NotEmpty(t, buff.String(), "While running task-test-silent-calls-chatty-non-silenced: Expected to see output. The task is silenced, but the called task is not. Silence does not propagate to called tasks.") + + buff.Reset() + + // A silent task that does a silent call to a chatty task. + err = e.Run(context.Background(), taskfile.Call{Task: "task-test-silent-calls-chatty-silenced"}) + require.NoError(t, err) + require.Empty(t, buff.String(), "While running task-test-silent-calls-chatty-silenced: Expected not to see output. The task calls chatty task, but the call is silenced.") + + buff.Reset() + + // A chatty task that does a call to a chatty task. + err = e.Run(context.Background(), taskfile.Call{Task: "task-test-chatty-calls-chatty-non-silenced"}) + require.NoError(t, err) + require.NotEmpty(t, buff.String(), "While running task-test-chatty-calls-chatty-non-silenced: Expected to see output. Both caller and callee are chatty and not silenced.") + + buff.Reset() + + // A chatty task that does a silenced call to a chatty task. + err = e.Run(context.Background(), taskfile.Call{Task: "task-test-chatty-calls-chatty-silenced"}) + require.NoError(t, err) + require.NotEmpty(t, buff.String(), "While running task-test-chatty-calls-chatty-silenced: Expected to see output. Call to a chatty task is silenced, but the parent task is not.") + + buff.Reset() + + // A chatty task with no cmd's of its own that does a silenced call to a chatty task. + err = e.Run(context.Background(), taskfile.Call{Task: "task-test-no-cmds-calls-chatty-silenced"}) + require.NoError(t, err) + require.Empty(t, buff.String(), "While running task-test-no-cmds-calls-chatty-silenced: Expected not to see output. While the task itself is not silenced, it does not have any cmds and only does an invocation of a silenced task.") + + buff.Reset() + + // A chatty task that does a silenced invocation of a task. + err = e.Run(context.Background(), taskfile.Call{Task: "task-test-chatty-calls-silenced-cmd"}) + require.NoError(t, err) + require.Empty(t, buff.String(), "While running task-test-chatty-calls-silenced-cmd: Expected not to see output. While the task itself is not silenced, its call to the chatty task is silent.") + + buff.Reset() +} diff --git a/taskfile/call.go b/taskfile/call.go index c1ca1083..bb00e782 100644 --- a/taskfile/call.go +++ b/taskfile/call.go @@ -2,6 +2,7 @@ package taskfile // Call is the parameters to a task call type Call struct { - Task string - Vars *Vars + Task string + Vars *Vars + Silent bool } diff --git a/taskfile/cmd.go b/taskfile/cmd.go index f0f0ff7b..5bb54421 100644 --- a/taskfile/cmd.go +++ b/taskfile/cmd.go @@ -99,6 +99,7 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error { if err := node.Decode(&taskCall); err == nil && taskCall.Task != "" { c.Task = taskCall.Task c.Vars = taskCall.Vars + c.Silent = cmdStruct.Silent return nil } diff --git a/taskfile/dep.go b/taskfile/dep.go index 6b6ba01b..34d96192 100644 --- a/taskfile/dep.go +++ b/taskfile/dep.go @@ -8,8 +8,9 @@ import ( // Dep is a task dependency type Dep struct { - Task string - Vars *Vars + Task string + Vars *Vars + Silent bool } func (d *Dep) DeepCopy() *Dep { @@ -35,14 +36,16 @@ func (d *Dep) UnmarshalYAML(node *yaml.Node) error { case yaml.MappingNode: var taskCall struct { - Task string - Vars *Vars + Task string + Vars *Vars + Silent bool } if err := node.Decode(&taskCall); err != nil { return err } d.Task = taskCall.Task d.Vars = taskCall.Vars + d.Silent = taskCall.Silent return nil } diff --git a/testdata/silent/Taskfile.yml b/testdata/silent/Taskfile.yml new file mode 100644 index 00000000..ad9267e0 --- /dev/null +++ b/testdata/silent/Taskfile.yml @@ -0,0 +1,50 @@ +version: '3' + +tasks: + silent: + desc: "silent" + silent: true + cmds: + - exit 0 + chatty: + desc: "chatty" + silent: false + cmds: + - exit 0 + + # Test combinations of silent and chatty tasks + task-test-silent-calls-chatty-non-silenced: + silent: true + cmds: + - task: chatty + + task-test-silent-calls-chatty-silenced: + silent: true + cmds: + - task: chatty + silent: true + + task-test-no-cmds-calls-chatty-silenced: + silent: false + cmds: + - task: chatty + silent: true + + task-test-chatty-calls-chatty-non-silenced: + silent: false + cmds: + - cmd: exit 0 + - task: chatty + + task-test-chatty-calls-chatty-silenced: + silent: false + cmds: + - cmd: exit 0 + - task: chatty + silent: true + + task-test-chatty-calls-silenced-cmd: + silent: false + cmds: + - cmd: exit 0 + silent: true diff --git a/variables.go b/variables.go index 75667822..76187e6f 100644 --- a/variables.go +++ b/variables.go @@ -142,8 +142,9 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf continue } new.Deps = append(new.Deps, &taskfile.Dep{ - Task: r.Replace(dep.Task), - Vars: r.ReplaceVars(dep.Vars), + Task: r.Replace(dep.Task), + Vars: r.ReplaceVars(dep.Vars), + Silent: dep.Silent, }) } }