From 2a92b70bc2c3673a83569cab3cee79fb62247cd7 Mon Sep 17 00:00:00 2001 From: Pete Davison Date: Mon, 31 Mar 2025 21:49:00 +0100 Subject: [PATCH] feat: better functional options (#2147) --- cmd/task/task.go | 4 +- executor.go | 484 ++++++++++++++++++++++++++------------- executor_test.go | 168 +++++++------- formatter_test.go | 12 +- internal/flags/flags.go | 96 ++++---- task_test.go | 492 ++++++++++++++++++++-------------------- 6 files changed, 710 insertions(+), 546 deletions(-) diff --git a/cmd/task/task.go b/cmd/task/task.go index 9ec60171..09c2a1e8 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -114,8 +114,8 @@ func run() error { } e := task.NewExecutor( - flags.WithExecutorOptions(), - task.ExecutorWithVersionCheck(true), + flags.WithFlags(), + task.WithVersionCheck(true), ) if err := e.Setup(); err != nil { return err diff --git a/executor.go b/executor.go index d73f9f3b..81626efa 100644 --- a/executor.go +++ b/executor.go @@ -18,7 +18,9 @@ import ( type ( // An ExecutorOption is a functional option for an [Executor]. - ExecutorOption func(*Executor) + ExecutorOption interface { + ApplyToExecutor(*Executor) + } // An Executor is used for processing Taskfile(s) and executing the task(s) // within them. Executor struct { @@ -103,226 +105,384 @@ func NewExecutor(opts ...ExecutorOption) *Executor { // to the [Executor]. func (e *Executor) Options(opts ...ExecutorOption) { for _, opt := range opts { - opt(e) + opt.ApplyToExecutor(e) } } -// ExecutorWithDir sets the working directory of the [Executor]. By default, the +// WithDir sets the working directory of the [Executor]. By default, the // directory is set to the user's current working directory. -func ExecutorWithDir(dir string) ExecutorOption { - return func(e *Executor) { - e.Dir = dir - } +func WithDir(dir string) ExecutorOption { + return dirOption{dir} } -// ExecutorWithEntrypoint sets the entrypoint (main Taskfile) of the [Executor]. -// By default, Task will search for one of the default Taskfiles in the given +type dirOption struct { + dir string +} + +func (o dirOption) ApplyToExecutor(e *Executor) { + e.Dir = o.dir +} + +// WithEntrypoint sets the entrypoint (main Taskfile) of the [Executor]. By +// default, Task will search for one of the default Taskfiles in the given // directory. -func ExecutorWithEntrypoint(entrypoint string) ExecutorOption { - return func(e *Executor) { - e.Entrypoint = entrypoint - } +func WithEntrypoint(entrypoint string) ExecutorOption { + return entrypointOption{entrypoint} } -// ExecutorWithTempDir sets the temporary directory that will be used by -// [Executor] for storing temporary files like checksums and cached remote -// files. By default, the temporary directory is set to the user's temporary -// directory. -func ExecutorWithTempDir(tempDir TempDir) ExecutorOption { - return func(e *Executor) { - e.TempDir = tempDir - } +type entrypointOption struct { + entrypoint string } -// ExecutorWithForce ensures that the [Executor] always runs a task, even when +func (o entrypointOption) ApplyToExecutor(e *Executor) { + e.Entrypoint = o.entrypoint +} + +// WithTempDir sets the temporary directory that will be used by [Executor] for +// storing temporary files like checksums and cached remote files. By default, +// the temporary directory is set to the user's temporary directory. +func WithTempDir(tempDir TempDir) ExecutorOption { + return tempDirOption{tempDir} +} + +type tempDirOption struct { + tempDir TempDir +} + +func (o tempDirOption) ApplyToExecutor(e *Executor) { + e.TempDir = o.tempDir +} + +// WithForce ensures that the [Executor] always runs a task, even when // fingerprinting or prompts would normally stop it. -func ExecutorWithForce(force bool) ExecutorOption { - return func(e *Executor) { - e.Force = force - } +func WithForce(force bool) ExecutorOption { + return forceOption{force} } -// ExecutorWithForceAll ensures that the [Executor] always runs all tasks -// (including subtasks), even when fingerprinting or prompts would normally stop -// them. -func ExecutorWithForceAll(forceAll bool) ExecutorOption { - return func(e *Executor) { - e.ForceAll = forceAll - } +type forceOption struct { + force bool } -// ExecutorWithInsecure allows the [Executor] to make insecure connections when -// reading remote taskfiles. By default, insecure connections are rejected. -func ExecutorWithInsecure(insecure bool) ExecutorOption { - return func(e *Executor) { - e.Insecure = insecure - } +func (o forceOption) ApplyToExecutor(e *Executor) { + e.Force = o.force } -// ExecutorWithDownload forces the [Executor] to download a fresh copy of the -// taskfile from the remote source. -func ExecutorWithDownload(download bool) ExecutorOption { - return func(e *Executor) { - e.Download = download - } +// WithForceAll ensures that the [Executor] always runs all tasks (including +// subtasks), even when fingerprinting or prompts would normally stop them. +func WithForceAll(forceAll bool) ExecutorOption { + return forceAllOption{forceAll} } -// ExecutorWithOffline stops the [Executor] from being able to make network -// connections. It will still be able to read local files and cached copies of -// remote files. -func ExecutorWithOffline(offline bool) ExecutorOption { - return func(e *Executor) { - e.Offline = offline - } +type forceAllOption struct { + forceAll bool } -// ExecutorWithTimeout sets the [Executor]'s timeout for fetching remote -// taskfiles. By default, the timeout is set to 10 seconds. -func ExecutorWithTimeout(timeout time.Duration) ExecutorOption { - return func(e *Executor) { - e.Timeout = timeout - } +func (o forceAllOption) ApplyToExecutor(e *Executor) { + e.ForceAll = o.forceAll } -// ExecutorWithWatch tells the [Executor] to keep running in the background and -// watch for changes to the fingerprint of the tasks that are run. When changes -// are detected, a new task run is triggered. -func ExecutorWithWatch(watch bool) ExecutorOption { - return func(e *Executor) { - e.Watch = watch - } +// WithInsecure allows the [Executor] to make insecure connections when reading +// remote taskfiles. By default, insecure connections are rejected. +func WithInsecure(insecure bool) ExecutorOption { + return insecureOption{insecure} } -// ExecutorWithVerbose tells the [Executor] to output more information about the -// tasks that are run. -func ExecutorWithVerbose(verbose bool) ExecutorOption { - return func(e *Executor) { - e.Verbose = verbose - } +type insecureOption struct { + insecure bool } -// ExecutorWithSilent tells the [Executor] to suppress all output except for the -// output of the tasks that are run. -func ExecutorWithSilent(silent bool) ExecutorOption { - return func(e *Executor) { - e.Silent = silent - } +func (o insecureOption) ApplyToExecutor(e *Executor) { + e.Insecure = o.insecure } -// ExecutorWithAssumeYes tells the [Executor] to assume "yes" for all prompts. -func ExecutorWithAssumeYes(assumeYes bool) ExecutorOption { - return func(e *Executor) { - e.AssumeYes = assumeYes - } +// WithDownload forces the [Executor] to download a fresh copy of the taskfile +// from the remote source. +func WithDownload(download bool) ExecutorOption { + return downloadOption{download} +} + +type downloadOption struct { + download bool +} + +func (o downloadOption) ApplyToExecutor(e *Executor) { + e.Download = o.download +} + +// WithOffline stops the [Executor] from being able to make network connections. +// It will still be able to read local files and cached copies of remote files. +func WithOffline(offline bool) ExecutorOption { + return offlineOption{offline} +} + +type offlineOption struct { + offline bool +} + +func (o offlineOption) ApplyToExecutor(e *Executor) { + e.Offline = o.offline +} + +// WithTimeout sets the [Executor]'s timeout for fetching remote taskfiles. By +// default, the timeout is set to 10 seconds. +func WithTimeout(timeout time.Duration) ExecutorOption { + return timeoutOption{timeout} +} + +type timeoutOption struct { + timeout time.Duration +} + +func (o timeoutOption) ApplyToExecutor(e *Executor) { + e.Timeout = o.timeout +} + +// WithWatch tells the [Executor] to keep running in the background and watch +// for changes to the fingerprint of the tasks that are run. When changes are +// detected, a new task run is triggered. +func WithWatch(watch bool) ExecutorOption { + return watchOption{watch} +} + +type watchOption struct { + watch bool +} + +func (o watchOption) ApplyToExecutor(e *Executor) { + e.Watch = o.watch +} + +// WithVerbose tells the [Executor] to output more information about the tasks +// that are run. +func WithVerbose(verbose bool) ExecutorOption { + return verboseOption{verbose} +} + +type verboseOption struct { + verbose bool +} + +func (o verboseOption) ApplyToExecutor(e *Executor) { + e.Verbose = o.verbose +} + +// WithSilent tells the [Executor] to suppress all output except for the output +// of the tasks that are run. +func WithSilent(silent bool) ExecutorOption { + return silentOption{silent} +} + +type silentOption struct { + silent bool +} + +func (o silentOption) ApplyToExecutor(e *Executor) { + e.Silent = o.silent +} + +// WithAssumeYes tells the [Executor] to assume "yes" for all prompts. +func WithAssumeYes(assumeYes bool) ExecutorOption { + return assumeYesOption{assumeYes} +} + +type assumeYesOption struct { + assumeYes bool +} + +func (o assumeYesOption) ApplyToExecutor(e *Executor) { + e.AssumeYes = o.assumeYes } // WithAssumeTerm is used for testing purposes to simulate a terminal. -func ExecutorWithAssumeTerm(assumeTerm bool) ExecutorOption { - return func(e *Executor) { - e.AssumeTerm = assumeTerm - } +func WithAssumeTerm(assumeTerm bool) ExecutorOption { + return assumeTermOption{assumeTerm} } -// ExecutorWithDry tells the [Executor] to output the commands that would be run -// without actually running them. -func ExecutorWithDry(dry bool) ExecutorOption { - return func(e *Executor) { - e.Dry = dry - } +type assumeTermOption struct { + assumeTerm bool } -// ExecutorWithSummary tells the [Executor] to output a summary of the given -// tasks instead of running them. -func ExecutorWithSummary(summary bool) ExecutorOption { - return func(e *Executor) { - e.Summary = summary - } +func (o assumeTermOption) ApplyToExecutor(e *Executor) { + e.AssumeTerm = o.assumeTerm } -// ExecutorWithParallel tells the [Executor] to run tasks given in the same call +// WithDry tells the [Executor] to output the commands that would be run without +// actually running them. +func WithDry(dry bool) ExecutorOption { + return dryOption{dry} +} + +type dryOption struct { + dry bool +} + +func (o dryOption) ApplyToExecutor(e *Executor) { + e.Dry = o.dry +} + +// WithSummary tells the [Executor] to output a summary of the given tasks +// instead of running them. +func WithSummary(summary bool) ExecutorOption { + return summaryOption{summary} +} + +type summaryOption struct { + summary bool +} + +func (o summaryOption) ApplyToExecutor(e *Executor) { + e.Summary = o.summary +} + +// WithParallel tells the [Executor] to run tasks given in the same call in +// parallel. +func WithParallel(parallel bool) ExecutorOption { + return parallelOption{parallel} +} + +type parallelOption struct { + parallel bool +} + +func (o parallelOption) ApplyToExecutor(e *Executor) { + e.Parallel = o.parallel +} + +// WithColor tells the [Executor] whether or not to output using colorized +// strings. +func WithColor(color bool) ExecutorOption { + return colorOption{color} +} + +type colorOption struct { + color bool +} + +func (o colorOption) ApplyToExecutor(e *Executor) { + e.Color = o.color +} + +// WithConcurrency sets the maximum number of tasks that the [Executor] can run // in parallel. -func ExecutorWithParallel(parallel bool) ExecutorOption { - return func(e *Executor) { - e.Parallel = parallel - } +func WithConcurrency(concurrency int) ExecutorOption { + return concurrencyOption{concurrency} } -// ExecutorWithColor tells the [Executor] whether or not to output using -// colorized strings. -func ExecutorWithColor(color bool) ExecutorOption { - return func(e *Executor) { - e.Color = color - } +type concurrencyOption struct { + concurrency int } -// ExecutorWithConcurrency sets the maximum number of tasks that the [Executor] -// can run in parallel. -func ExecutorWithConcurrency(concurrency int) ExecutorOption { - return func(e *Executor) { - e.Concurrency = concurrency - } +func (o concurrencyOption) ApplyToExecutor(e *Executor) { + e.Concurrency = o.concurrency } -// ExecutorWithInterval sets the interval at which the [Executor] will wait for +// WithInterval sets the interval at which the [Executor] will wait for // duplicated events before running a task. -func ExecutorWithInterval(interval time.Duration) ExecutorOption { - return func(e *Executor) { - e.Interval = interval - } +func WithInterval(interval time.Duration) ExecutorOption { + return intervalOption{interval} } -// ExecutorWithOutputStyle sets the output style of the [Executor]. By default, -// the output style is set to the style defined in the Taskfile. -func ExecutorWithOutputStyle(outputStyle ast.Output) ExecutorOption { - return func(e *Executor) { - e.OutputStyle = outputStyle - } +type intervalOption struct { + interval time.Duration } -// ExecutorWithTaskSorter sets the sorter that the [Executor] will use to sort -// tasks. By default, the sorter is set to sort tasks alphabetically, but with -// tasks with no namespace (in the root Taskfile) first. -func ExecutorWithTaskSorter(sorter sort.Sorter) ExecutorOption { - return func(e *Executor) { - e.TaskSorter = sorter - } +func (o intervalOption) ApplyToExecutor(e *Executor) { + e.Interval = o.interval } -// ExecutorWithStdin sets the [Executor]'s standard input [io.Reader]. -func ExecutorWithStdin(stdin io.Reader) ExecutorOption { - return func(e *Executor) { - e.Stdin = stdin - } +// WithOutputStyle sets the output style of the [Executor]. By default, the +// output style is set to the style defined in the Taskfile. +func WithOutputStyle(outputStyle ast.Output) ExecutorOption { + return outputStyleOption{outputStyle} } -// ExecutorWithStdout sets the [Executor]'s standard output [io.Writer]. -func ExecutorWithStdout(stdout io.Writer) ExecutorOption { - return func(e *Executor) { - e.Stdout = stdout - } +type outputStyleOption struct { + outputStyle ast.Output } -// ExecutorWithStderr sets the [Executor]'s standard error [io.Writer]. -func ExecutorWithStderr(stderr io.Writer) ExecutorOption { - return func(e *Executor) { - e.Stderr = stderr - } +func (o outputStyleOption) ApplyToExecutor(e *Executor) { + e.OutputStyle = o.outputStyle } -// ExecutorWithIO sets the [Executor]'s standard input, output, and error to the -// same [io.ReadWriter]. -func ExecutorWithIO(rw io.ReadWriter) ExecutorOption { - return func(e *Executor) { - e.Stdin = rw - e.Stdout = rw - e.Stderr = rw - } +// WithTaskSorter sets the sorter that the [Executor] will use to sort tasks. By +// default, the sorter is set to sort tasks alphabetically, but with tasks with +// no namespace (in the root Taskfile) first. +func WithTaskSorter(sorter sort.Sorter) ExecutorOption { + return taskSorterOption{sorter} } -// ExecutorWithVersionCheck tells the [Executor] whether or not to check the -// version of -func ExecutorWithVersionCheck(enableVersionCheck bool) ExecutorOption { - return func(e *Executor) { - e.EnableVersionCheck = enableVersionCheck - } +type taskSorterOption struct { + sorter sort.Sorter +} + +func (o taskSorterOption) ApplyToExecutor(e *Executor) { + e.TaskSorter = o.sorter +} + +// WithStdin sets the [Executor]'s standard input [io.Reader]. +func WithStdin(stdin io.Reader) ExecutorOption { + return stdinOption{stdin} +} + +type stdinOption struct { + stdin io.Reader +} + +func (o stdinOption) ApplyToExecutor(e *Executor) { + e.Stdin = o.stdin +} + +// WithStdout sets the [Executor]'s standard output [io.Writer]. +func WithStdout(stdout io.Writer) ExecutorOption { + return stdoutOption{stdout} +} + +type stdoutOption struct { + stdout io.Writer +} + +func (o stdoutOption) ApplyToExecutor(e *Executor) { + e.Stdout = o.stdout +} + +// WithStderr sets the [Executor]'s standard error [io.Writer]. +func WithStderr(stderr io.Writer) ExecutorOption { + return stderrOption{stderr} +} + +type stderrOption struct { + stderr io.Writer +} + +func (o stderrOption) ApplyToExecutor(e *Executor) { + e.Stderr = o.stderr +} + +// WithIO sets the [Executor]'s standard input, output, and error to the same +// [io.ReadWriter]. +func WithIO(rw io.ReadWriter) ExecutorOption { + return ioOption{rw} +} + +type ioOption struct { + rw io.ReadWriter +} + +func (o ioOption) ApplyToExecutor(e *Executor) { + e.Stdin = o.rw + e.Stdout = o.rw + e.Stderr = o.rw +} + +// WithVersionCheck tells the [Executor] whether or not to check the version of +func WithVersionCheck(enableVersionCheck bool) ExecutorOption { + return versionCheckOption{enableVersionCheck} +} + +type versionCheckOption struct { + enableVersionCheck bool +} + +func (o versionCheckOption) ApplyToExecutor(e *Executor) { + e.EnableVersionCheck = o.enableVersionCheck } diff --git a/executor_test.go b/executor_test.go index 3d922387..9b1e7839 100644 --- a/executor_test.go +++ b/executor_test.go @@ -148,8 +148,8 @@ func (tt *ExecutorTest) run(t *testing.T) { opts := append( tt.executorOpts, - task.ExecutorWithStdout(&buf), - task.ExecutorWithStderr(&buf), + task.WithStdout(&buf), + task.WithStderr(&buf), ) // If the test has input, create a reader for it and add it to the @@ -157,7 +157,7 @@ func (tt *ExecutorTest) run(t *testing.T) { if tt.input != "" { var reader bytes.Buffer reader.WriteString(tt.input) - opts = append(opts, task.ExecutorWithStdin(&reader)) + opts = append(opts, task.WithStdin(&reader)) } // Set up the task executor @@ -221,7 +221,7 @@ func TestEmptyTask(t *testing.T) { t.Parallel() NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/empty_task"), + task.WithDir("testdata/empty_task"), ), ) } @@ -230,7 +230,7 @@ func TestEmptyTaskfile(t *testing.T) { t.Parallel() NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/empty_taskfile"), + task.WithDir("testdata/empty_taskfile"), ), WithSetupError(), WithPostProcessFn(PPRemoveAbsolutePaths), @@ -242,15 +242,15 @@ func TestEnv(t *testing.T) { NewExecutorTest(t, WithName("env precedence disabled"), WithExecutorOptions( - task.ExecutorWithDir("testdata/env"), - task.ExecutorWithSilent(true), + task.WithDir("testdata/env"), + task.WithSilent(true), ), ) NewExecutorTest(t, WithName("env precedence enabled"), WithExecutorOptions( - task.ExecutorWithDir("testdata/env"), - task.ExecutorWithSilent(true), + task.WithDir("testdata/env"), + task.WithSilent(true), ), WithExperiment(&experiments.EnvPrecedence, 1), ) @@ -260,8 +260,8 @@ func TestVars(t *testing.T) { t.Parallel() NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/vars"), - task.ExecutorWithSilent(true), + task.WithDir("testdata/vars"), + task.WithSilent(true), ), ) } @@ -271,7 +271,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("required var missing"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("missing-var"), WithRunError(), @@ -279,7 +279,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("required var ok"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("missing-var"), WithVar("FOO", "bar"), @@ -287,7 +287,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("fails validation"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("validation-var"), WithVar("ENV", "dev"), @@ -297,7 +297,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("passes validation"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("validation-var"), WithVar("FOO", "one"), @@ -306,7 +306,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("required var missing + fails validation"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("validation-var"), WithRunError(), @@ -314,7 +314,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("required var missing + fails validation"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("validation-var-dynamic"), WithVar("FOO", "one"), @@ -323,7 +323,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("require before compile"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("require-before-compile"), WithRunError(), @@ -331,7 +331,7 @@ func TestRequires(t *testing.T) { NewExecutorTest(t, WithName("var defined in task"), WithExecutorOptions( - task.ExecutorWithDir("testdata/requires"), + task.WithDir("testdata/requires"), ), WithTask("var-defined-in-task"), ) @@ -373,9 +373,9 @@ func TestSpecialVars(t *testing.T) { NewExecutorTest(t, WithName(fmt.Sprintf("%s-%s", dir, test.target)), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), - task.ExecutorWithVersionCheck(true), + task.WithDir(dir), + task.WithSilent(true), + task.WithVersionCheck(true), ), WithTask(test.target), WithPostProcessFn(PPRemoveAbsolutePaths), @@ -388,8 +388,8 @@ func TestConcurrency(t *testing.T) { t.Parallel() NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/concurrency"), - task.ExecutorWithConcurrency(1), + task.WithDir("testdata/concurrency"), + task.WithConcurrency(1), ), WithPostProcessFn(PPSortedLines), ) @@ -399,8 +399,8 @@ func TestParams(t *testing.T) { t.Parallel() NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/params"), - task.ExecutorWithSilent(true), + task.WithDir("testdata/params"), + task.WithSilent(true), ), WithPostProcessFn(PPSortedLines), ) @@ -410,8 +410,8 @@ func TestDeps(t *testing.T) { t.Parallel() NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/deps"), - task.ExecutorWithSilent(true), + task.WithDir("testdata/deps"), + task.WithSilent(true), ), WithPostProcessFn(PPSortedLines), ) @@ -441,8 +441,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-foo 1 silent"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithSilent(true), ), WithTask("gen-foo"), ) @@ -453,8 +453,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-bar 1 silent"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithSilent(true), ), WithTask("gen-bar"), ) @@ -463,8 +463,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-baz silent"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithSilent(true), ), WithTask("gen-silent-baz"), ) @@ -479,8 +479,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-bar 2 silent"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithSilent(true), ), WithTask("gen-bar"), ) @@ -488,8 +488,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-bar 3 silent"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithSilent(true), ), WithTask("gen-bar"), ) @@ -501,8 +501,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-bar 4 silent"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithSilent(true), ), WithTask("gen-bar"), ) @@ -510,7 +510,7 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-foo 2"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("gen-foo"), ) @@ -518,7 +518,7 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-foo 3"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("gen-foo"), ) @@ -526,7 +526,7 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-bar 5"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("gen-bar"), ) @@ -534,7 +534,7 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-bar 6"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("gen-bar"), ) @@ -542,7 +542,7 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-baz 2"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("gen-silent-baz"), ) @@ -550,7 +550,7 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-baz 3"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("gen-silent-baz"), ) @@ -558,8 +558,8 @@ func TestStatus(t *testing.T) { NewExecutorTest(t, WithName("run gen-baz 4 verbose"), WithExecutorOptions( - task.ExecutorWithDir(dir), - task.ExecutorWithVerbose(true), + task.WithDir(dir), + task.WithVerbose(true), ), WithTask("gen-silent-baz"), WithPostProcessFn(PPRemoveAbsolutePaths), @@ -572,14 +572,14 @@ func TestPrecondition(t *testing.T) { NewExecutorTest(t, WithName("a precondition has been met"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("foo"), ) NewExecutorTest(t, WithName("a precondition was not met"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("impossible"), WithRunError(), @@ -587,7 +587,7 @@ func TestPrecondition(t *testing.T) { NewExecutorTest(t, WithName("precondition in dependency fails the task"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("depends_on_impossible"), WithRunError(), @@ -595,7 +595,7 @@ func TestPrecondition(t *testing.T) { NewExecutorTest(t, WithName("precondition in cmd fails the task"), WithExecutorOptions( - task.ExecutorWithDir(dir), + task.WithDir(dir), ), WithTask("executes_failing_task_as_cmd"), WithRunError(), @@ -608,7 +608,7 @@ func TestAlias(t *testing.T) { NewExecutorTest(t, WithName("alias"), WithExecutorOptions( - task.ExecutorWithDir("testdata/alias"), + task.WithDir("testdata/alias"), ), WithTask("f"), ) @@ -616,7 +616,7 @@ func TestAlias(t *testing.T) { NewExecutorTest(t, WithName("duplicate alias"), WithExecutorOptions( - task.ExecutorWithDir("testdata/alias"), + task.WithDir("testdata/alias"), ), WithTask("x"), WithRunError(), @@ -625,8 +625,8 @@ func TestAlias(t *testing.T) { NewExecutorTest(t, WithName("alias summary"), WithExecutorOptions( - task.ExecutorWithDir("testdata/alias"), - task.ExecutorWithSummary(true), + task.WithDir("testdata/alias"), + task.WithSummary(true), ), WithTask("f"), ) @@ -638,7 +638,7 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("up to date"), WithExecutorOptions( - task.ExecutorWithDir("testdata/label_uptodate"), + task.WithDir("testdata/label_uptodate"), ), WithTask("foo"), ) @@ -646,8 +646,8 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("summary"), WithExecutorOptions( - task.ExecutorWithDir("testdata/label_summary"), - task.ExecutorWithSummary(true), + task.WithDir("testdata/label_summary"), + task.WithSummary(true), ), WithTask("foo"), ) @@ -655,7 +655,7 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("status"), WithExecutorOptions( - task.ExecutorWithDir("testdata/label_status"), + task.WithDir("testdata/label_status"), ), WithTask("foo"), WithStatusError(), @@ -664,7 +664,7 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("var"), WithExecutorOptions( - task.ExecutorWithDir("testdata/label_var"), + task.WithDir("testdata/label_var"), ), WithTask("foo"), ) @@ -672,7 +672,7 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("label in summary"), WithExecutorOptions( - task.ExecutorWithDir("testdata/label_summary"), + task.WithDir("testdata/label_summary"), ), WithTask("foo"), ) @@ -701,8 +701,8 @@ func TestPromptInSummary(t *testing.T) { opts := []ExecutorTestOption{ WithName(test.name), WithExecutorOptions( - task.ExecutorWithDir("testdata/prompt"), - task.ExecutorWithAssumeTerm(true), + task.WithDir("testdata/prompt"), + task.WithAssumeTerm(true), ), WithTask("foo"), WithInput(test.input), @@ -720,8 +720,8 @@ func TestPromptWithIndirectTask(t *testing.T) { NewExecutorTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/prompt"), - task.ExecutorWithAssumeTerm(true), + task.WithDir("testdata/prompt"), + task.WithAssumeTerm(true), ), WithTask("bar"), WithInput("y\n"), @@ -734,9 +734,9 @@ func TestPromptAssumeYes(t *testing.T) { NewExecutorTest(t, WithName("--yes flag should skip prompt"), WithExecutorOptions( - task.ExecutorWithDir("testdata/prompt"), - task.ExecutorWithAssumeTerm(true), - task.ExecutorWithAssumeYes(true), + task.WithDir("testdata/prompt"), + task.WithAssumeTerm(true), + task.WithAssumeYes(true), ), WithTask("foo"), WithInput("\n"), @@ -745,8 +745,8 @@ func TestPromptAssumeYes(t *testing.T) { NewExecutorTest(t, WithName("task should raise errors.TaskCancelledError"), WithExecutorOptions( - task.ExecutorWithDir("testdata/prompt"), - task.ExecutorWithAssumeTerm(true), + task.WithDir("testdata/prompt"), + task.WithAssumeTerm(true), ), WithTask("foo"), WithInput("\n"), @@ -781,9 +781,9 @@ func TestForCmds(t *testing.T) { opts := []ExecutorTestOption{ WithName(test.name), WithExecutorOptions( - task.ExecutorWithDir("testdata/for/cmds"), - task.ExecutorWithSilent(true), - task.ExecutorWithForce(true), + task.WithDir("testdata/for/cmds"), + task.WithSilent(true), + task.WithForce(true), ), WithTask(test.name), WithPostProcessFn(PPRemoveAbsolutePaths), @@ -822,11 +822,11 @@ func TestForDeps(t *testing.T) { opts := []ExecutorTestOption{ WithName(test.name), WithExecutorOptions( - task.ExecutorWithDir("testdata/for/deps"), - task.ExecutorWithSilent(true), - task.ExecutorWithForce(true), + task.WithDir("testdata/for/deps"), + task.WithSilent(true), + task.WithForce(true), // Force output of each dep to be grouped together to prevent interleaving - task.ExecutorWithOutputStyle(ast.Output{Name: "group"}), + task.WithOutputStyle(ast.Output{Name: "group"}), ), WithTask(test.name), WithPostProcessFn(PPRemoveAbsolutePaths), @@ -868,9 +868,9 @@ func TestReference(t *testing.T) { NewExecutorTest(t, WithName(test.name), WithExecutorOptions( - task.ExecutorWithDir("testdata/var_references"), - task.ExecutorWithSilent(true), - task.ExecutorWithForce(true), + task.WithDir("testdata/var_references"), + task.WithSilent(true), + task.WithForce(true), ), WithTask(cmp.Or(test.call, "default")), ) @@ -936,9 +936,9 @@ func TestVarInheritance(t *testing.T) { NewExecutorTest(t, WithName(test.name), WithExecutorOptions( - task.ExecutorWithDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)), - task.ExecutorWithSilent(true), - task.ExecutorWithForce(true), + task.WithDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)), + task.WithSilent(true), + task.WithForce(true), ), WithTask(cmp.Or(test.call, "default")), ) diff --git a/formatter_test.go b/formatter_test.go index ec4ca1dc..7820b52f 100644 --- a/formatter_test.go +++ b/formatter_test.go @@ -116,8 +116,8 @@ func (tt *FormatterTest) run(t *testing.T) { opts := append( tt.executorOpts, - task.ExecutorWithStdout(&buf), - task.ExecutorWithStderr(&buf), + task.WithStdout(&buf), + task.WithStderr(&buf), ) // Set up the task executor @@ -170,7 +170,7 @@ func TestNoLabelInList(t *testing.T) { NewFormatterTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/label_list"), + task.WithDir("testdata/label_list"), ), WithListOptions(task.ListOptions{ ListOnlyTasksWithDescriptions: true, @@ -184,7 +184,7 @@ func TestListAllShowsNoDesc(t *testing.T) { NewFormatterTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/list_mixed_desc"), + task.WithDir("testdata/list_mixed_desc"), ), WithListOptions(task.ListOptions{ ListAllTasks: true, @@ -198,7 +198,7 @@ func TestListCanListDescOnly(t *testing.T) { NewFormatterTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/list_mixed_desc"), + task.WithDir("testdata/list_mixed_desc"), ), WithListOptions(task.ListOptions{ ListOnlyTasksWithDescriptions: true, @@ -211,7 +211,7 @@ func TestListDescInterpolation(t *testing.T) { NewFormatterTest(t, WithExecutorOptions( - task.ExecutorWithDir("testdata/list_desc_interpolation"), + task.WithDir("testdata/list_desc_interpolation"), ), WithListOptions(task.ListOptions{ ListOnlyTasksWithDescriptions: true, diff --git a/internal/flags/flags.go b/internal/flags/flags.go index 8c21193e..1c981f8b 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -176,50 +176,54 @@ func Validate() error { return nil } -// WithExecutorOptions is a special internal functional option that is used to pass flags -// from the CLI directly to the executor. -func WithExecutorOptions() task.ExecutorOption { - return func(e *task.Executor) { - // Set the sorter - var sorter sort.Sorter - switch TaskSort { - case "none": - sorter = sort.NoSort - case "alphanumeric": - sorter = sort.AlphaNumeric - } - - // Change the directory to the user's home directory if the global flag is set - dir := Dir - if Global { - home, err := os.UserHomeDir() - if err == nil { - dir = home - } - } - - e.Options( - task.ExecutorWithDir(dir), - task.ExecutorWithEntrypoint(Entrypoint), - task.ExecutorWithForce(Force), - task.ExecutorWithForceAll(ForceAll), - task.ExecutorWithInsecure(Insecure), - task.ExecutorWithDownload(Download), - task.ExecutorWithOffline(Offline), - task.ExecutorWithTimeout(Timeout), - task.ExecutorWithWatch(Watch), - task.ExecutorWithVerbose(Verbose), - task.ExecutorWithSilent(Silent), - task.ExecutorWithAssumeYes(AssumeYes), - task.ExecutorWithDry(Dry || Status), - task.ExecutorWithSummary(Summary), - task.ExecutorWithParallel(Parallel), - task.ExecutorWithColor(Color), - task.ExecutorWithConcurrency(Concurrency), - task.ExecutorWithInterval(Interval), - task.ExecutorWithOutputStyle(Output), - task.ExecutorWithTaskSorter(sorter), - task.ExecutorWithVersionCheck(true), - ) - } +// WithFlags is a special internal functional option that is used to pass flags +// from the CLI into any constructor that accepts functional options. +func WithFlags() task.ExecutorOption { + return &flagsOption{} +} + +type flagsOption struct{} + +func (o *flagsOption) ApplyToExecutor(e *task.Executor) { + // Set the sorter + var sorter sort.Sorter + switch TaskSort { + case "none": + sorter = sort.NoSort + case "alphanumeric": + sorter = sort.AlphaNumeric + } + + // Change the directory to the user's home directory if the global flag is set + dir := Dir + if Global { + home, err := os.UserHomeDir() + if err == nil { + dir = home + } + } + + e.Options( + task.WithDir(dir), + task.WithEntrypoint(Entrypoint), + task.WithForce(Force), + task.WithForceAll(ForceAll), + task.WithInsecure(Insecure), + task.WithDownload(Download), + task.WithOffline(Offline), + task.WithTimeout(Timeout), + task.WithWatch(Watch), + task.WithVerbose(Verbose), + task.WithSilent(Silent), + task.WithAssumeYes(AssumeYes), + task.WithDry(Dry || Status), + task.WithSummary(Summary), + task.WithParallel(Parallel), + task.WithColor(Color), + task.WithConcurrency(Concurrency), + task.WithInterval(Interval), + task.WithOutputStyle(Output), + task.WithTaskSorter(sorter), + task.WithVersionCheck(true), + ) } diff --git a/task_test.go b/task_test.go index d1ba8abf..becafd2b 100644 --- a/task_test.go +++ b/task_test.go @@ -298,14 +298,14 @@ func (fct fileContentTest) Run(t *testing.T) { } e := task.NewExecutor( - task.ExecutorWithDir(fct.Dir), - task.ExecutorWithTempDir(task.TempDir{ + task.WithDir(fct.Dir), + task.WithTempDir(task.TempDir{ Remote: filepathext.SmartJoin(fct.Dir, ".task"), Fingerprint: filepathext.SmartJoin(fct.Dir, ".task"), }), - task.ExecutorWithEntrypoint(fct.Entrypoint), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), + task.WithEntrypoint(fct.Entrypoint), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), ) require.NoError(t, e.Setup(), "e.Setup()") @@ -348,9 +348,9 @@ func TestGenerates(t *testing.T) { buff := bytes.NewBuffer(nil) e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(buff), - task.ExecutorWithStderr(buff), + task.WithDir(dir), + task.WithStdout(buff), + task.WithStderr(buff), ) require.NoError(t, e.Setup()) @@ -409,10 +409,10 @@ func TestStatusChecksum(t *testing.T) { // nolint:paralleltest // cannot run in Fingerprint: filepathext.SmartJoin(dir, ".task"), } e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithTempDir(tempDir), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithTempDir(tempDir), ) require.NoError(t, e.Setup()) @@ -449,15 +449,15 @@ func TestStatusVariables(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithTempDir(task.TempDir{ + task.WithDir(dir), + task.WithTempDir(task.TempDir{ Remote: filepathext.SmartJoin(dir, ".task"), Fingerprint: filepathext.SmartJoin(dir, ".task"), }), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(false), - task.ExecutorWithVerbose(true), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(false), + task.WithVerbose(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "build-checksum"})) @@ -485,15 +485,15 @@ func TestCmdsVariables(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithTempDir(task.TempDir{ + task.WithDir(dir), + task.WithTempDir(task.TempDir{ Remote: filepathext.SmartJoin(dir, ".task"), Fingerprint: filepathext.SmartJoin(dir, ".task"), }), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(false), - task.ExecutorWithVerbose(true), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(false), + task.WithVerbose(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "build-checksum"})) @@ -517,9 +517,9 @@ func TestCyclicDep(t *testing.T) { const dir = "testdata/cyclic" e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), + task.WithDir(dir), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), ) require.NoError(t, e.Setup()) assert.IsType(t, &errors.TaskCalledTooManyTimesError{}, e.Run(context.Background(), &task.Call{Task: "task-1"})) @@ -543,10 +543,10 @@ func TestTaskVersion(t *testing.T) { t.Parallel() e := task.NewExecutor( - task.ExecutorWithDir(test.Dir), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), - task.ExecutorWithVersionCheck(true), + task.WithDir(test.Dir), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), + task.WithVersionCheck(true), ) err := e.Setup() if test.wantErr { @@ -566,9 +566,9 @@ func TestTaskIgnoreErrors(t *testing.T) { const dir = "testdata/ignore_errors" e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), + task.WithDir(dir), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), ) require.NoError(t, e.Setup()) @@ -590,9 +590,9 @@ func TestExpand(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "pwd"})) @@ -610,10 +610,10 @@ func TestDry(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithDry(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithDry(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "build"})) @@ -635,14 +635,14 @@ func TestDryChecksum(t *testing.T) { _ = os.Remove(checksumFile) e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithTempDir(task.TempDir{ + task.WithDir(dir), + task.WithTempDir(task.TempDir{ Remote: filepathext.SmartJoin(dir, ".task"), Fingerprint: filepathext.SmartJoin(dir, ".task"), }), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), - task.ExecutorWithDry(true), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), + task.WithDry(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "default"})) @@ -743,36 +743,36 @@ func TestIncludesRemote(t *testing.T) { { name: "online, always download", executor: task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithTimeout(time.Minute), - task.ExecutorWithInsecure(true), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithVerbose(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithTimeout(time.Minute), + task.WithInsecure(true), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithVerbose(true), // Without caching - task.ExecutorWithAssumeYes(true), - task.ExecutorWithDownload(true), + task.WithAssumeYes(true), + task.WithDownload(true), ), }, { name: "offline, use cache", executor: task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithTimeout(time.Minute), - task.ExecutorWithInsecure(true), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithVerbose(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithTimeout(time.Minute), + task.WithInsecure(true), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithVerbose(true), // With caching - task.ExecutorWithAssumeYes(false), - task.ExecutorWithDownload(false), - task.ExecutorWithOffline(true), + task.WithAssumeYes(false), + task.WithDownload(false), + task.WithOffline(true), ), }, } @@ -814,10 +814,10 @@ func TestIncludeCycle(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) err := e.Setup() @@ -832,10 +832,10 @@ func TestIncludesIncorrect(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) err := e.Setup() @@ -903,17 +903,17 @@ func TestIncludesHttp(t *testing.T) { var buff SyncBuffer e := task.NewExecutor( - task.ExecutorWithEntrypoint(entrypoint), - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithInsecure(true), - task.ExecutorWithDownload(true), - task.ExecutorWithAssumeYes(true), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithVerbose(true), - task.ExecutorWithTimeout(time.Minute), + task.WithEntrypoint(entrypoint), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithInsecure(true), + task.WithDownload(true), + task.WithAssumeYes(true), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithVerbose(true), + task.WithTimeout(time.Minute), ) require.NoError(t, e.Setup()) defer func() { t.Log("output:", buff.buf.String()) }() @@ -1007,9 +1007,9 @@ func TestIncludesOptionalImplicitFalse(t *testing.T) { expected := fmt.Sprintf(message, wd, dir) e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), + task.WithDir(dir), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), ) err := e.Setup() @@ -1027,9 +1027,9 @@ func TestIncludesOptionalExplicitFalse(t *testing.T) { expected := fmt.Sprintf(message, wd, dir) e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), + task.WithDir(dir), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), ) err := e.Setup() @@ -1064,9 +1064,9 @@ func TestIncludesRelativePath(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1100,10 +1100,10 @@ func TestIncludesInternal(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -1143,11 +1143,11 @@ func TestIncludesFlatten(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithEntrypoint(dir+"/"+test.taskfile), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithEntrypoint(dir+"/"+test.taskfile), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) err := e.Setup() if test.expectedErr { @@ -1179,10 +1179,10 @@ func TestIncludesInterpolation(t *testing.T) { // nolint:paralleltest // cannot t.Run(test.name, func(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(filepath.Join(dir, test.name)), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(filepath.Join(dir, test.name)), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -1202,10 +1202,10 @@ func TestIncludesWithExclude(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/includes_with_excludes"), - task.ExecutorWithSilent(true), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/includes_with_excludes"), + task.WithSilent(true), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1245,10 +1245,10 @@ func TestIncludedTaskfileVarMerging(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -1280,10 +1280,10 @@ func TestInternalTask(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -1365,11 +1365,11 @@ func TestSummary(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSummary(true), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSummary(true), + task.WithSilent(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "task-with-summary"}, &task.Call{Task: "other-task-with-summary"})) @@ -1392,9 +1392,9 @@ func TestWhenNoDirAttributeItRunsInSameDirAsTaskfile(t *testing.T) { const dir = "testdata/" + expected var out bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&out), - task.ExecutorWithStderr(&out), + task.WithDir(dir), + task.WithStdout(&out), + task.WithStderr(&out), ) require.NoError(t, e.Setup()) @@ -1412,9 +1412,9 @@ func TestWhenDirAttributeAndDirExistsItRunsInThatDir(t *testing.T) { const dir = "testdata/dir/explicit_exists" var out bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&out), - task.ExecutorWithStderr(&out), + task.WithDir(dir), + task.WithStdout(&out), + task.WithStderr(&out), ) require.NoError(t, e.Setup()) @@ -1433,9 +1433,9 @@ func TestWhenDirAttributeItCreatesMissingAndRunsInThatDir(t *testing.T) { const target = "whereami" var out bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&out), - task.ExecutorWithStderr(&out), + task.WithDir(dir), + task.WithStdout(&out), + task.WithStderr(&out), ) // Ensure that the directory to be created doesn't actually exist. @@ -1462,9 +1462,9 @@ func TestDynamicVariablesRunOnTheNewCreatedDir(t *testing.T) { const target = "default" var out bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&out), - task.ExecutorWithStderr(&out), + task.WithDir(dir), + task.WithStdout(&out), + task.WithStderr(&out), ) // Ensure that the directory to be created doesn't actually exist. @@ -1506,10 +1506,10 @@ func TestDisplaysErrorOnVersion1Schema(t *testing.T) { t.Parallel() e := task.NewExecutor( - task.ExecutorWithDir("testdata/version/v1"), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(io.Discard), - task.ExecutorWithVersionCheck(true), + task.WithDir("testdata/version/v1"), + task.WithStdout(io.Discard), + task.WithStderr(io.Discard), + task.WithVersionCheck(true), ) err := e.Setup() require.Error(t, err) @@ -1521,10 +1521,10 @@ func TestDisplaysErrorOnVersion2Schema(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/version/v2"), - task.ExecutorWithStdout(io.Discard), - task.ExecutorWithStderr(&buff), - task.ExecutorWithVersionCheck(true), + task.WithDir("testdata/version/v2"), + task.WithStdout(io.Discard), + task.WithStderr(&buff), + task.WithVersionCheck(true), ) err := e.Setup() require.Error(t, err) @@ -1538,10 +1538,10 @@ func TestShortTaskNotation(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "default"})) @@ -1570,10 +1570,10 @@ func TestDotenvShouldErrorWhenIncludingDependantDotenvs(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/dotenv/error_included_envs"), - task.ExecutorWithSummary(true), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/dotenv/error_included_envs"), + task.WithSummary(true), + task.WithStdout(&buff), + task.WithStderr(&buff), ) err := e.Setup() @@ -1650,7 +1650,7 @@ func TestTaskDotenvParseErrorMessage(t *testing.T) { t.Parallel() e := task.NewExecutor( - task.ExecutorWithDir("testdata/dotenv/parse_error"), + task.WithDir("testdata/dotenv/parse_error"), ) path, _ := filepath.Abs(filepath.Join(e.Dir, ".env-with-error")) @@ -1735,10 +1735,10 @@ func TestExitImmediately(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -1769,10 +1769,10 @@ func TestRunOnceSharedDeps(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithForceAll(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithForceAll(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "build"})) @@ -1790,9 +1790,9 @@ func TestDeferredCmds(t *testing.T) { const dir = "testdata/deferred" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1817,9 +1817,9 @@ func TestExitCodeZero(t *testing.T) { const dir = "testdata/exit_code" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1833,9 +1833,9 @@ func TestExitCodeOne(t *testing.T) { const dir = "testdata/exit_code" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1862,10 +1862,10 @@ func TestIgnoreNilElements(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(test.dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(test.dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "default"})) @@ -1880,9 +1880,9 @@ func TestOutputGroup(t *testing.T) { const dir = "testdata/output_group" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1907,9 +1907,9 @@ func TestOutputGroupErrorOnlySwallowsOutputOnSuccess(t *testing.T) { const dir = "testdata/output_group_error_only" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1924,9 +1924,9 @@ func TestOutputGroupErrorOnlyShowsOutputOnFailure(t *testing.T) { const dir = "testdata/output_group_error_only" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1942,9 +1942,9 @@ func TestIncludedVars(t *testing.T) { const dir = "testdata/include_with_vars" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -1986,9 +1986,9 @@ func TestIncludedVarsMultiLevel(t *testing.T) { const dir = "testdata/include_with_vars_multi_level" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2031,10 +2031,10 @@ func TestErrorCode(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -2051,10 +2051,10 @@ func TestEvaluateSymlinksInPaths(t *testing.T) { // nolint:paralleltest // canno const dir = "testdata/evaluate_symlinks_in_paths" var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(false), + task.WithDir(dir), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(false), ) tests := []struct { name string @@ -2128,9 +2128,9 @@ func TestTaskfileWalk(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir(test.dir), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir(test.dir), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "default"})) @@ -2144,9 +2144,9 @@ func TestUserWorkingDirectory(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/user_working_dir"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/user_working_dir"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) wd, err := os.Getwd() require.NoError(t, err) @@ -2165,9 +2165,9 @@ func TestUserWorkingDirectoryWithIncluded(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/user_working_dir_with_includes"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/user_working_dir_with_includes"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) e.UserWorkingDir = wd @@ -2182,9 +2182,9 @@ func TestPlatforms(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/platforms"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/platforms"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "build-" + runtime.GOOS})) @@ -2196,9 +2196,9 @@ func TestPOSIXShellOptsGlobalLevel(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/shopts/global_level"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/shopts/global_level"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2212,9 +2212,9 @@ func TestPOSIXShellOptsTaskLevel(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/shopts/task_level"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/shopts/task_level"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2228,9 +2228,9 @@ func TestPOSIXShellOptsCommandLevel(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/shopts/command_level"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/shopts/command_level"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2244,9 +2244,9 @@ func TestBashShellOptsGlobalLevel(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/shopts/global_level"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/shopts/global_level"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2260,9 +2260,9 @@ func TestBashShellOptsTaskLevel(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/shopts/task_level"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/shopts/task_level"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2276,9 +2276,9 @@ func TestBashShellOptsCommandLevel(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/shopts/command_level"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), + task.WithDir("testdata/shopts/command_level"), + task.WithStdout(&buff), + task.WithStderr(&buff), ) require.NoError(t, e.Setup()) @@ -2292,10 +2292,10 @@ func TestSplitArgs(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/split_args"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), + task.WithDir("testdata/split_args"), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), ) require.NoError(t, e.Setup()) @@ -2329,10 +2329,10 @@ func TestSilence(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/silent"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(false), + task.WithDir("testdata/silent"), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(false), ) require.NoError(t, e.Setup()) @@ -2460,11 +2460,11 @@ func TestForce(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/force"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithForce(tt.force), - task.ExecutorWithForceAll(tt.forceAll), + task.WithDir("testdata/force"), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithForce(tt.force), + task.WithForceAll(tt.forceAll), ) require.NoError(t, e.Setup()) require.NoError(t, e.Run(context.Background(), &task.Call{Task: "task-with-dep"})) @@ -2519,11 +2519,11 @@ func TestWildcard(t *testing.T) { var buff bytes.Buffer e := task.NewExecutor( - task.ExecutorWithDir("testdata/wildcards"), - task.ExecutorWithStdout(&buff), - task.ExecutorWithStderr(&buff), - task.ExecutorWithSilent(true), - task.ExecutorWithForce(true), + task.WithDir("testdata/wildcards"), + task.WithStdout(&buff), + task.WithStderr(&buff), + task.WithSilent(true), + task.WithForce(true), ) require.NoError(t, e.Setup()) if test.wantErr {