Skip to content

Conversation

pd93
Copy link
Member

@pd93 pd93 commented Feb 22, 2025

This PR migrates the Executor to use the functional options pattern. This follows other similar changes to taskfile.Reader and taskfile.Snippet. This allows package API users to easily construct an Executor with sensible defaults and only supply a list of things they want to override.

Our internal CLI implementation has a special functional option in internal/flags called WithFlags which will gather all the CLI flags and pass them in as functional options.

@vmaerten vmaerten self-requested a review February 23, 2025 09:36
Copy link
Member

@vmaerten vmaerten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good refactor as always!

Copy link
Member

@andreynering andreynering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Claps

executor.go Outdated
Comment on lines 231 to 301
func WithStdin(stdin io.Reader) ExecutorOption {
return func(e *Executor) {
e.Stdin = stdin
}
}

func WithStdout(stdout io.Writer) ExecutorOption {
return func(e *Executor) {
e.Stdout = stdout
}
}

func WithStderr(stderr io.Writer) ExecutorOption {
return func(e *Executor) {
e.Stderr = stderr
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory we could have an additional function that accepts all three, for shortness. Optional suggestion, though.

func WithIO(stdin io.Reader, stdout, stderr io.Writer) ExecutorOption { return func(e *Executor) { e.Stdin = stdin e.Stdout = stdout e.Stderr = stderr	} }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, it makes more sense to keep these separate if you're passing different values into each of them. Sometimes you might only want to pass in 1 or 2 of them and leave the others blank. However, I think if you're setting them all to the same value, we could have something like this:

func WithIO(rw io.ReadWriter) ExecutorOption { return func(e *Executor) { e.Stdin = rw e.Stdout = rw e.Stderr = rw	} }

This would be super handy in the new tests I've been writing where we want to write everything to a single buffer.

@pd93 pd93 added the area: package api Changes related to the usage of Task as a Go package. label Feb 23, 2025
@pd93 pd93 force-pushed the executor-functional-options branch from ec2aa2e to 60ff636 Compare February 23, 2025 23:35
@pd93
Copy link
Member Author

pd93 commented Feb 23, 2025

Couple of minor changes:

  • Added the missing ExecutorWithVersionCheck functional option in cmd/task
  • Added prefixes to the functional options like in taskfile.Snippet
    • This helps with any potential naming conflicts in the future.
  • A bunch of docstrings for everything.
@pd93 pd93 merged commit ffeb3bc into main Mar 10, 2025
14 checks passed
@pd93 pd93 deleted the executor-functional-options branch March 10, 2025 20:38
pd93 added a commit that referenced this pull request Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: package api Changes related to the usage of Task as a Go package.

3 participants