From a026d729243e9d10574930a0204c50472c6dff8f Mon Sep 17 00:00:00 2001 From: kj Date: Tue, 5 Feb 2019 15:42:57 +0900 Subject: [PATCH 1/6] Add execute output style options --- cmd/task/task.go | 4 ++++ task.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/cmd/task/task.go b/cmd/task/task.go index 57c3637dbb..bd2f196b41 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -57,6 +57,7 @@ func main() { silent bool dry bool dir string + output string ) pflag.BoolVar(&versionFlag, "version", false, "show Task version") @@ -69,6 +70,7 @@ func main() { pflag.BoolVarP(&silent, "silent", "s", false, "disables echoing") pflag.BoolVar(&dry, "dry", false, "compiles and prints tasks in the order that they would be run, without executing them") pflag.StringVarP(&dir, "dir", "d", "", "sets directory of execution") + pflag.StringVarP(&output, "output", "o", "", "sets output style: [interleaved|group|prefixed]") pflag.Parse() if versionFlag { @@ -105,6 +107,8 @@ func main() { Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, + + OutputStyle: output, } if err := e.Setup(); err != nil { log.Fatal(err) diff --git a/task.go b/task.go index 9de7d88c01..e8979b4bb6 100644 --- a/task.go +++ b/task.go @@ -46,6 +46,7 @@ type Executor struct { Logger *logger.Logger Compiler compiler.Compiler Output output.Output + OutputStyle string taskvars taskfile.Vars @@ -134,6 +135,9 @@ func (e *Executor) Setup() error { if !version.IsV22(v) && len(e.Taskfile.Includes) > 0 { return fmt.Errorf(`task: Including Taskfiles is only available starting on Taskfile version v2.2`) } + if e.OutputStyle != "" { + e.Taskfile.Output = e.OutputStyle + } switch e.Taskfile.Output { case "", "interleaved": e.Output = output.Interleaved{} From f8fb6398701b78cd0fb41e1e19b7bea858dd0e03 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sat, 9 Feb 2019 10:01:07 -0200 Subject: [PATCH 2/6] Update documentation and changelog to mention the new `--output` flag Ref #173 --- CHANGELOG.md | 4 +++- docs/usage.md | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff5a657655..48542457ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ - Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with `:` - ([#161](https://github.com/go-task/task/issues/161), [#172](https://github.com/go-task/task/issues/172)). + ([#161](https://github.com/go-task/task/issues/161), [#172](https://github.com/go-task/task/issues/172)), +- Add flag to override the `output` option + ([#173](https://github.com/go-task/task/pull/173)). ## v2.3.0 - 2019-01-02 diff --git a/docs/usage.md b/docs/usage.md index b334595cdb..29f55ed2d8 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -708,6 +708,8 @@ $ task default [print-baz] baz ``` +> The `output` option can also be specified by the `--output` or `-o` flags. + ## Watch tasks If you give a `--watch` or `-w` argument, task will watch for file changes From 27b35157cdd0f9fe3eb450cf22233f6a3d9689b4 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sat, 9 Feb 2019 10:15:38 -0200 Subject: [PATCH 3/6] Indentation fix --- task.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/task.go b/task.go index e8979b4bb6..0a774185d3 100644 --- a/task.go +++ b/task.go @@ -43,9 +43,9 @@ type Executor struct { Stdout io.Writer Stderr io.Writer - Logger *logger.Logger - Compiler compiler.Compiler - Output output.Output + Logger *logger.Logger + Compiler compiler.Compiler + Output output.Output OutputStyle string taskvars taskfile.Vars From 713ecd35f6af6be11a583eadcb76ecd68cb782a7 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sat, 9 Feb 2019 10:16:13 -0200 Subject: [PATCH 4/6] Pass context as an argument --- cmd/task/task.go | 16 +++++++--------- status.go | 4 ++-- task.go | 9 ++------- task_test.go | 33 +++++++++++++++++---------------- 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/cmd/task/task.go b/cmd/task/task.go index bd2f196b41..694a0a5c4c 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -89,11 +89,6 @@ func main() { return } - ctx := context.Background() - if !watch { - ctx = getSignalContext() - } - e := task.Executor{ Force: force, Watch: watch, @@ -102,8 +97,6 @@ func main() { Dir: dir, Dry: dry, - Context: ctx, - Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, @@ -130,14 +123,19 @@ func main() { log.Fatal(err) } + ctx := context.Background() + if !watch { + ctx = getSignalContext() + } + if status { - if err = e.Status(calls...); err != nil { + if err = e.Status(ctx, calls...); err != nil { log.Fatal(err) } return } - if err := e.Run(calls...); err != nil { + if err := e.Run(ctx, calls...); err != nil { log.Fatal(err) } } diff --git a/status.go b/status.go index 5ba7cfdafa..9bee76a419 100644 --- a/status.go +++ b/status.go @@ -10,13 +10,13 @@ import ( ) // Status returns an error if any the of given tasks is not up-to-date -func (e *Executor) Status(calls ...taskfile.Call) error { +func (e *Executor) Status(ctx context.Context, calls ...taskfile.Call) error { for _, call := range calls { t, err := e.CompiledTask(call) if err != nil { return err } - isUpToDate, err := isTaskUpToDate(e.Context, t) + isUpToDate, err := isTaskUpToDate(ctx, t) if err != nil { return err } diff --git a/task.go b/task.go index 0a774185d3..7ea05731cf 100644 --- a/task.go +++ b/task.go @@ -37,8 +37,6 @@ type Executor struct { Silent bool Dry bool - Context context.Context - Stdin io.Reader Stdout io.Writer Stderr io.Writer @@ -54,7 +52,7 @@ type Executor struct { } // Run runs Task -func (e *Executor) Run(calls ...taskfile.Call) error { +func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error { // check if given tasks exist for _, c := range calls { if _, ok := e.Taskfile.Tasks[c.Task]; !ok { @@ -69,7 +67,7 @@ func (e *Executor) Run(calls ...taskfile.Call) error { } for _, c := range calls { - if err := e.RunTask(e.Context, c); err != nil { + if err := e.RunTask(ctx, c); err != nil { return err } } @@ -93,9 +91,6 @@ func (e *Executor) Setup() error { return fmt.Errorf(`task: could not parse taskfile version "%s": %v`, e.Taskfile.Version, err) } - if e.Context == nil { - e.Context = context.Background() - } if e.Stdin == nil { e.Stdin = os.Stdin } diff --git a/task_test.go b/task_test.go index 76dcdb4685..e2072865c2 100644 --- a/task_test.go +++ b/task_test.go @@ -2,6 +2,7 @@ package task_test import ( "bytes" + "context" "fmt" "io/ioutil" "os" @@ -40,7 +41,7 @@ func (fct fileContentTest) Run(t *testing.T) { Stderr: ioutil.Discard, } assert.NoError(t, e.Setup(), "e.Setup()") - assert.NoError(t, e.Run(taskfile.Call{Task: fct.Target}), "e.Run(target)") + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: fct.Target}), "e.Run(target)") for name, expectContent := range fct.Files { t.Run(fct.name(name), func(t *testing.T) { @@ -178,7 +179,7 @@ func TestVarsInvalidTmpl(t *testing.T) { Stderr: ioutil.Discard, } assert.NoError(t, e.Setup(), "e.Setup()") - assert.EqualError(t, e.Run(taskfile.Call{Task: target}), expectError, "e.Run(target)") + assert.EqualError(t, e.Run(context.Background(), taskfile.Call{Task: target}), expectError, "e.Run(target)") } func TestParams(t *testing.T) { @@ -230,7 +231,7 @@ func TestDeps(t *testing.T) { Stderr: ioutil.Discard, } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "default"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "default"})) for _, f := range files { f = filepath.Join(dir, f) @@ -258,14 +259,14 @@ func TestStatus(t *testing.T) { Silent: true, } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "gen-foo"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "gen-foo"})) if _, err := os.Stat(file); err != nil { t.Errorf("File should exists: %v", err) } e.Silent = false - assert.NoError(t, e.Run(taskfile.Call{Task: "gen-foo"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "gen-foo"})) if buff.String() != `task: Task "gen-foo" is up to date`+"\n" { t.Errorf("Wrong output message: %s", buff.String()) @@ -304,7 +305,7 @@ func TestGenerates(t *testing.T) { fmt.Sprintf("task: Task \"%s\" is up to date\n", theTask) // Run task for the first time. - assert.NoError(t, e.Run(taskfile.Call{Task: theTask})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: theTask})) if _, err := os.Stat(srcFile); err != nil { t.Errorf("File should exists: %v", err) @@ -319,7 +320,7 @@ func TestGenerates(t *testing.T) { buff.Reset() // Re-run task to ensure it's now found to be up-to-date. - assert.NoError(t, e.Run(taskfile.Call{Task: theTask})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: theTask})) if buff.String() != upToDate { t.Errorf("Wrong output message: %s", buff.String()) } @@ -350,14 +351,14 @@ func TestStatusChecksum(t *testing.T) { } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "build"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "build"})) for _, f := range files { _, err := os.Stat(filepath.Join(dir, f)) assert.NoError(t, err) } buff.Reset() - assert.NoError(t, e.Run(taskfile.Call{Task: "build"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "build"})) assert.Equal(t, `task: Task "build" is up to date`+"\n", buff.String()) } @@ -388,7 +389,7 @@ func TestCyclicDep(t *testing.T) { Stderr: ioutil.Discard, } assert.NoError(t, e.Setup()) - assert.IsType(t, &task.MaximumTaskCallExceededError{}, e.Run(taskfile.Call{Task: "task-1"})) + assert.IsType(t, &task.MaximumTaskCallExceededError{}, e.Run(context.Background(), taskfile.Call{Task: "task-1"})) } func TestTaskVersion(t *testing.T) { @@ -424,10 +425,10 @@ func TestTaskIgnoreErrors(t *testing.T) { } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "task-should-pass"})) - assert.Error(t, e.Run(taskfile.Call{Task: "task-should-fail"})) - assert.NoError(t, e.Run(taskfile.Call{Task: "cmd-should-pass"})) - assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "task-should-pass"})) + assert.Error(t, e.Run(context.Background(), taskfile.Call{Task: "task-should-fail"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "cmd-should-pass"})) + assert.Error(t, e.Run(context.Background(), taskfile.Call{Task: "cmd-should-fail"})) } func TestExpand(t *testing.T) { @@ -445,7 +446,7 @@ func TestExpand(t *testing.T) { Stderr: &buff, } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "pwd"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "pwd"})) assert.Equal(t, home, strings.TrimSpace(buff.String())) } @@ -464,7 +465,7 @@ func TestDry(t *testing.T) { Dry: true, } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "build"})) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "build"})) assert.Equal(t, "touch file.txt", strings.TrimSpace(buff.String())) if _, err := os.Stat(file); err == nil { From 902f0d3ac49ba7e608d5a8b2a55407bbacd1c646 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sat, 9 Feb 2019 10:41:19 -0200 Subject: [PATCH 5/6] Don't persist new checksum on the disk if dry mode is enabled Fixes #166 --- CHANGELOG.md | 5 ++++- internal/status/checksum.go | 9 ++++++--- status.go | 17 +++++++++-------- task.go | 4 ++-- task_test.go | 26 ++++++++++++++++++++++++++ testdata/dry_checksum/Taskfile.yml | 9 +++++++++ testdata/dry_checksum/source.txt | 1 + 7 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 testdata/dry_checksum/Taskfile.yml create mode 100644 testdata/dry_checksum/source.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 48542457ce..059ec4f431 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,10 @@ by prefixing it with `:` ([#161](https://github.com/go-task/task/issues/161), [#172](https://github.com/go-task/task/issues/172)), - Add flag to override the `output` option - ([#173](https://github.com/go-task/task/pull/173)). + ([#173](https://github.com/go-task/task/pull/173)); +- Fix bug where Task was persisting the new checksum on the disk when the Dry + Mode is enabled + ([#166](https://github.com/go-task/task/issues/166)). ## v2.3.0 - 2019-01-02 diff --git a/internal/status/checksum.go b/internal/status/checksum.go index 00798a0c0f..4433104703 100644 --- a/internal/status/checksum.go +++ b/internal/status/checksum.go @@ -17,6 +17,7 @@ type Checksum struct { Dir string Task string Sources []string + Dry bool } // IsUpToDate implements the Checker interface @@ -36,9 +37,11 @@ func (c *Checksum) IsUpToDate() (bool, error) { return false, nil } - _ = os.MkdirAll(filepath.Join(c.Dir, ".task", "checksum"), 0755) - if err = ioutil.WriteFile(checksumFile, []byte(newMd5+"\n"), 0644); err != nil { - return false, err + if !c.Dry { + _ = os.MkdirAll(filepath.Join(c.Dir, ".task", "checksum"), 0755) + if err = ioutil.WriteFile(checksumFile, []byte(newMd5+"\n"), 0644); err != nil { + return false, err + } } return oldMd5 == newMd5, nil } diff --git a/status.go b/status.go index 9bee76a419..173be34b20 100644 --- a/status.go +++ b/status.go @@ -16,7 +16,7 @@ func (e *Executor) Status(ctx context.Context, calls ...taskfile.Call) error { if err != nil { return err } - isUpToDate, err := isTaskUpToDate(ctx, t) + isUpToDate, err := e.isTaskUpToDate(ctx, t) if err != nil { return err } @@ -27,12 +27,12 @@ func (e *Executor) Status(ctx context.Context, calls ...taskfile.Call) error { return nil } -func isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, error) { +func (e *Executor) isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, error) { if len(t.Status) > 0 { - return isTaskUpToDateStatus(ctx, t) + return e.isTaskUpToDateStatus(ctx, t) } - checker, err := getStatusChecker(t) + checker, err := e.getStatusChecker(t) if err != nil { return false, err } @@ -40,15 +40,15 @@ func isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, error) { return checker.IsUpToDate() } -func statusOnError(t *taskfile.Task) error { - checker, err := getStatusChecker(t) +func (e *Executor) statusOnError(t *taskfile.Task) error { + checker, err := e.getStatusChecker(t) if err != nil { return err } return checker.OnError() } -func getStatusChecker(t *taskfile.Task) (status.Checker, error) { +func (e *Executor) getStatusChecker(t *taskfile.Task) (status.Checker, error) { switch t.Method { case "", "timestamp": return &status.Timestamp{ @@ -61,6 +61,7 @@ func getStatusChecker(t *taskfile.Task) (status.Checker, error) { Dir: t.Dir, Task: t.Task, Sources: t.Sources, + Dry: e.Dry, }, nil case "none": return status.None{}, nil @@ -69,7 +70,7 @@ func getStatusChecker(t *taskfile.Task) (status.Checker, error) { } } -func isTaskUpToDateStatus(ctx context.Context, t *taskfile.Task) (bool, error) { +func (e *Executor) isTaskUpToDateStatus(ctx context.Context, t *taskfile.Task) (bool, error) { for _, s := range t.Status { err := execext.RunCommand(ctx, &execext.RunCommandOptions{ Command: s, diff --git a/task.go b/task.go index 7ea05731cf..1632d6d67a 100644 --- a/task.go +++ b/task.go @@ -181,7 +181,7 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error { } if !e.Force { - upToDate, err := isTaskUpToDate(ctx, t) + upToDate, err := e.isTaskUpToDate(ctx, t) if err != nil { return err } @@ -195,7 +195,7 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error { for i := range t.Cmds { if err := e.runCommand(ctx, t, call, i); err != nil { - if err2 := statusOnError(t); err2 != nil { + if err2 := e.statusOnError(t); err2 != nil { e.Logger.VerboseErrf("task: error cleaning status on error: %v", err2) } diff --git a/task_test.go b/task_test.go index e2072865c2..f3d8ed7567 100644 --- a/task_test.go +++ b/task_test.go @@ -473,6 +473,32 @@ func TestDry(t *testing.T) { } } +// TestDryChecksum tests if the checksum file is not being written to disk +// if the dry mode is enabled. +func TestDryChecksum(t *testing.T) { + const dir = "testdata/dry_checksum" + + checksumFile := filepath.Join(dir, ".task/checksum/default") + _ = os.Remove(checksumFile) + + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + Dry: true, + } + assert.NoError(t, e.Setup()) + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "default"})) + + _, err := os.Stat(checksumFile) + assert.Error(t, err, "checksum file should not exist") + + e.Dry = false + assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "default"})) + _, err = os.Stat(checksumFile) + assert.NoError(t, err, "checksum file should exist") +} + func TestIncludes(t *testing.T) { tt := fileContentTest{ Dir: "testdata/includes", diff --git a/testdata/dry_checksum/Taskfile.yml b/testdata/dry_checksum/Taskfile.yml new file mode 100644 index 0000000000..057816b3dc --- /dev/null +++ b/testdata/dry_checksum/Taskfile.yml @@ -0,0 +1,9 @@ +version: '2' + +tasks: + default: + cmds: + - echo "Working..." + sources: + - source.txt + method: checksum diff --git a/testdata/dry_checksum/source.txt b/testdata/dry_checksum/source.txt new file mode 100644 index 0000000000..9ed2574292 --- /dev/null +++ b/testdata/dry_checksum/source.txt @@ -0,0 +1 @@ +Something... From 21e66c7c0272e367422db7acb2c48fc3fbac8690 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sat, 9 Feb 2019 10:48:48 -0200 Subject: [PATCH 6/6] Docs: Update theme color --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index d1398f9c32..4a832385b1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -33,7 +33,7 @@ name: 'Task', repo: 'go-task/task', ga: 'UA-126286662-1', - themeColor: '#83d0f2', + themeColor: '#00add8', loadSidebar: true, auto2top: true, maxLevel: 3,