1
0
mirror of https://github.com/go-task/task.git synced 2026-10-23 11:48:55 +03:00

refactor: functional options (#3037)

This commit is contained in:
Pete Davison
2026-09-26 17:09:27 +01:00
committed by GitHub
parent 2ecc2d275c
commit 4ac77269fb
7 changed files with 323 additions and 304 deletions

View File

@@ -137,7 +137,7 @@ func (e *Executor) fingerprinter() *fingerprint.Fingerprinter {
// WithDir sets the working directory of the [Executor]. By default, the
// directory is set to the user's current working directory.
func WithDir(dir string) ExecutorOption {
func WithDir(dir string) *dirOption {
return &dirOption{dir}
}
@@ -152,7 +152,7 @@ func (o *dirOption) ApplyToExecutor(e *Executor) {
// 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 WithEntrypoint(entrypoint string) ExecutorOption {
func WithEntrypoint(entrypoint string) *entrypointOption {
return &entrypointOption{entrypoint}
}
@@ -167,7 +167,7 @@ func (o *entrypointOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithTempDir(tempDir TempDir) *tempDirOption {
return &tempDirOption{tempDir}
}
@@ -183,7 +183,7 @@ func (o *tempDirOption) ApplyToExecutor(e *Executor) {
// during [Executor.Setup]. Relative paths are resolved from the root Taskfile
// directory. Use [WithTempDir] when the remote and fingerprint directories have
// already been resolved.
func WithTempDirPath(path string) ExecutorOption {
func WithTempDirPath(path string) *tempDirPathOption {
return &tempDirPathOption{path: path}
}
@@ -197,7 +197,7 @@ func (o *tempDirPathOption) ApplyToExecutor(e *Executor) {
// WithForce ensures that the [Executor] always runs a task, even when
// fingerprinting or prompts would normally stop it.
func WithForce(force bool) ExecutorOption {
func WithForce(force bool) *forceOption {
return &forceOption{force}
}
@@ -211,7 +211,7 @@ func (o *forceOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithForceAll(forceAll bool) *forceAllOption {
return &forceAllOption{forceAll}
}
@@ -225,7 +225,7 @@ func (o *forceAllOption) ApplyToExecutor(e *Executor) {
// WithInsecure allows the [Executor] to make insecure connections when reading
// remote taskfiles. By default, insecure connections are rejected.
func WithInsecure(insecure bool) ExecutorOption {
func WithInsecure(insecure bool) *insecureOption {
return &insecureOption{insecure}
}
@@ -239,7 +239,7 @@ func (o *insecureOption) ApplyToExecutor(e *Executor) {
// WithDownload forces the [Executor] to download a fresh copy of the taskfile
// from the remote source.
func WithDownload(download bool) ExecutorOption {
func WithDownload(download bool) *downloadOption {
return &downloadOption{download}
}
@@ -253,7 +253,7 @@ func (o *downloadOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithOffline(offline bool) *offlineOption {
return &offlineOption{offline}
}
@@ -267,7 +267,7 @@ func (o *offlineOption) ApplyToExecutor(e *Executor) {
// WithTrustedHosts configures the [Executor] with a list of trusted hosts for remote
// Taskfiles. Hosts in this list will not prompt for user confirmation.
func WithTrustedHosts(trustedHosts []string) ExecutorOption {
func WithTrustedHosts(trustedHosts []string) *trustedHostsOption {
return &trustedHostsOption{trustedHosts}
}
@@ -295,7 +295,7 @@ func (o *remoteHeadersOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithTimeout(timeout time.Duration) *timeoutOption {
return &timeoutOption{timeout}
}
@@ -309,7 +309,7 @@ func (o *timeoutOption) ApplyToExecutor(e *Executor) {
// WithCacheExpiryDuration sets the duration after which the cache is considered
// expired. By default, the cache is 0 (disabled).
func WithCacheExpiryDuration(duration time.Duration) ExecutorOption {
func WithCacheExpiryDuration(duration time.Duration) *cacheExpiryDurationOption {
return &cacheExpiryDurationOption{duration: duration}
}
@@ -322,7 +322,7 @@ func (o *cacheExpiryDurationOption) ApplyToExecutor(r *Executor) {
}
// WithRemoteCacheDir sets the directory where remote taskfiles are cached.
func WithRemoteCacheDir(dir string) ExecutorOption {
func WithRemoteCacheDir(dir string) *remoteCacheDirOption {
return &remoteCacheDirOption{dir: dir}
}
@@ -335,7 +335,7 @@ func (o *remoteCacheDirOption) ApplyToExecutor(e *Executor) {
}
// WithCACert sets the path to a custom CA certificate for TLS connections.
func WithCACert(caCert string) ExecutorOption {
func WithCACert(caCert string) *caCertOption {
return &caCertOption{caCert: caCert}
}
@@ -348,7 +348,7 @@ func (o *caCertOption) ApplyToExecutor(e *Executor) {
}
// WithCert sets the path to a client certificate for TLS connections.
func WithCert(cert string) ExecutorOption {
func WithCert(cert string) *certOption {
return &certOption{cert: cert}
}
@@ -361,7 +361,7 @@ func (o *certOption) ApplyToExecutor(e *Executor) {
}
// WithCertKey sets the path to a client certificate key for TLS connections.
func WithCertKey(certKey string) ExecutorOption {
func WithCertKey(certKey string) *certKeyOption {
return &certKeyOption{certKey: certKey}
}
@@ -376,7 +376,7 @@ func (o *certKeyOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithWatch(watch bool) *watchOption {
return &watchOption{watch}
}
@@ -390,7 +390,7 @@ func (o *watchOption) ApplyToExecutor(e *Executor) {
// WithVerbose tells the [Executor] to output more information about the tasks
// that are run.
func WithVerbose(verbose bool) ExecutorOption {
func WithVerbose(verbose bool) *verboseOption {
return &verboseOption{verbose}
}
@@ -404,7 +404,7 @@ func (o *verboseOption) ApplyToExecutor(e *Executor) {
// WithSilent tells the [Executor] to suppress all output except for the output
// of the tasks that are run.
func WithSilent(silent bool) ExecutorOption {
func WithSilent(silent bool) *silentOption {
return &silentOption{silent}
}
@@ -417,7 +417,7 @@ func (o *silentOption) ApplyToExecutor(e *Executor) {
}
// WithDisableFuzzy tells the [Executor] to disable fuzzy matching for task names.
func WithDisableFuzzy(disableFuzzy bool) ExecutorOption {
func WithDisableFuzzy(disableFuzzy bool) *disableFuzzyOption {
return &disableFuzzyOption{disableFuzzy}
}
@@ -430,7 +430,7 @@ func (o *disableFuzzyOption) ApplyToExecutor(e *Executor) {
}
// WithAssumeYes tells the [Executor] to assume "yes" for all prompts.
func WithAssumeYes(assumeYes bool) ExecutorOption {
func WithAssumeYes(assumeYes bool) *assumeYesOption {
return &assumeYesOption{assumeYes}
}
@@ -443,7 +443,7 @@ func (o *assumeYesOption) ApplyToExecutor(e *Executor) {
}
// WithAssumeTerm is used for testing purposes to simulate a terminal.
func WithAssumeTerm(assumeTerm bool) ExecutorOption {
func WithAssumeTerm(assumeTerm bool) *assumeTermOption {
return &assumeTermOption{assumeTerm}
}
@@ -456,7 +456,7 @@ func (o *assumeTermOption) ApplyToExecutor(e *Executor) {
}
// WithInteractive tells the [Executor] to prompt for missing required variables.
func WithInteractive(interactive bool) ExecutorOption {
func WithInteractive(interactive bool) *interactiveOption {
return &interactiveOption{interactive}
}
@@ -470,7 +470,7 @@ func (o *interactiveOption) ApplyToExecutor(e *Executor) {
// WithDry tells the [Executor] to output the commands that would be run without
// actually running them.
func WithDry(dry bool) ExecutorOption {
func WithDry(dry bool) *dryOption {
return &dryOption{dry}
}
@@ -484,7 +484,7 @@ func (o *dryOption) ApplyToExecutor(e *Executor) {
// WithSummary tells the [Executor] to output a summary of the given tasks
// instead of running them.
func WithSummary(summary bool) ExecutorOption {
func WithSummary(summary bool) *summaryOption {
return &summaryOption{summary}
}
@@ -498,7 +498,7 @@ func (o *summaryOption) ApplyToExecutor(e *Executor) {
// WithParallel tells the [Executor] to run tasks given in the same call in
// parallel.
func WithParallel(parallel bool) ExecutorOption {
func WithParallel(parallel bool) *parallelOption {
return &parallelOption{parallel}
}
@@ -512,7 +512,7 @@ func (o *parallelOption) ApplyToExecutor(e *Executor) {
// WithColor tells the [Executor] whether or not to output using colorized
// strings.
func WithColor(color bool) ExecutorOption {
func WithColor(color bool) *colorOption {
return &colorOption{color}
}
@@ -526,7 +526,7 @@ func (o *colorOption) ApplyToExecutor(e *Executor) {
// WithConcurrency sets the maximum number of tasks that the [Executor] can run
// in parallel.
func WithConcurrency(concurrency int) ExecutorOption {
func WithConcurrency(concurrency int) *concurrencyOption {
return &concurrencyOption{concurrency}
}
@@ -540,7 +540,7 @@ func (o *concurrencyOption) ApplyToExecutor(e *Executor) {
// WithInterval sets the interval at which the [Executor] will wait for
// duplicated events before running a task.
func WithInterval(interval time.Duration) ExecutorOption {
func WithInterval(interval time.Duration) *intervalOption {
return &intervalOption{interval}
}
@@ -554,7 +554,7 @@ func (o *intervalOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithOutputStyle(outputStyle ast.Output) *outputStyleOption {
return &outputStyleOption{outputStyle}
}
@@ -569,7 +569,7 @@ func (o *outputStyleOption) ApplyToExecutor(e *Executor) {
// 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 {
func WithTaskSorter(sorter sort.Sorter) *taskSorterOption {
return &taskSorterOption{sorter}
}
@@ -582,7 +582,7 @@ func (o *taskSorterOption) ApplyToExecutor(e *Executor) {
}
// WithStdin sets the [Executor]'s standard input [io.Reader].
func WithStdin(stdin io.Reader) ExecutorOption {
func WithStdin(stdin io.Reader) *stdinOption {
return &stdinOption{stdin}
}
@@ -595,7 +595,7 @@ func (o *stdinOption) ApplyToExecutor(e *Executor) {
}
// WithStdout sets the [Executor]'s standard output [io.Writer].
func WithStdout(stdout io.Writer) ExecutorOption {
func WithStdout(stdout io.Writer) *stdoutOption {
return &stdoutOption{stdout}
}
@@ -608,7 +608,7 @@ func (o *stdoutOption) ApplyToExecutor(e *Executor) {
}
// WithStderr sets the [Executor]'s standard error [io.Writer].
func WithStderr(stderr io.Writer) ExecutorOption {
func WithStderr(stderr io.Writer) *stderrOption {
return &stderrOption{stderr}
}
@@ -622,7 +622,7 @@ func (o *stderrOption) ApplyToExecutor(e *Executor) {
// WithIO sets the [Executor]'s standard input, output, and error to the same
// [io.ReadWriter].
func WithIO(rw io.ReadWriter) ExecutorOption {
func WithIO(rw io.ReadWriter) *ioOption {
return &ioOption{rw}
}
@@ -638,7 +638,7 @@ func (o *ioOption) ApplyToExecutor(e *Executor) {
// WithVersionCheck tells the [Executor] whether or not to check the schema
// version of the Taskfile before running.
func WithVersionCheck(enableVersionCheck bool) ExecutorOption {
func WithVersionCheck(enableVersionCheck bool) *versionCheckOption {
return &versionCheckOption{enableVersionCheck}
}
@@ -652,7 +652,7 @@ func (o *versionCheckOption) ApplyToExecutor(e *Executor) {
// WithFailfast tells the [Executor] to stop running tasks as soon as any task
// returns an error.
func WithFailfast(failfast bool) ExecutorOption {
func WithFailfast(failfast bool) *failfastOption {
return &failfastOption{failfast}
}

View File

@@ -88,9 +88,9 @@ func (e *Executor) readTaskfile(node taskfile.Node) error {
taskfile.WithTrustedHosts(e.TrustedHosts),
taskfile.WithTempDir(e.TempDir.Remote),
taskfile.WithCacheExpiryDuration(e.CacheExpiryDuration),
taskfile.WithReaderCACert(e.CACert),
taskfile.WithReaderCert(e.Cert),
taskfile.WithReaderCertKey(e.CertKey),
taskfile.WithCACert(e.CACert),
taskfile.WithCert(e.Cert),
taskfile.WithCertKey(e.CertKey),
taskfile.WithReaderHeaders(e.RemoteHeaders),
taskfile.WithDebugFunc(debugFunc),
taskfile.WithPromptFunc(promptFunc),

View File

@@ -1,7 +1,9 @@
package taskfile
type (
NodeOption func(*baseNode)
NodeOption interface {
ApplyToBaseNode(n *baseNode)
}
// baseNode is a generic node that implements the Parent() methods of the
// NodeReader interface. It does not implement the Read() method and it
// designed to be embedded in other node types so that this boilerplate code
@@ -25,24 +27,12 @@ func NewBaseNode(dir string, opts ...NodeOption) *baseNode {
// Apply options
for _, opt := range opts {
opt(node)
opt.ApplyToBaseNode(node)
}
return node
}
func WithParent(parent Node) NodeOption {
return func(node *baseNode) {
node.parent = parent
}
}
func WithChecksum(checksum string) NodeOption {
return func(node *baseNode) {
node.checksum = checksum
}
}
func (node *baseNode) Parent() Node {
return node.parent
}
@@ -58,28 +48,3 @@ func (node *baseNode) Checksum() string {
func (node *baseNode) Verify(checksum string) bool {
return node.checksum == "" || node.checksum == checksum
}
func WithCACert(caCert string) NodeOption {
return func(node *baseNode) {
node.caCert = caCert
}
}
func WithCert(cert string) NodeOption {
return func(node *baseNode) {
node.cert = cert
}
}
func WithCertKey(certKey string) NodeOption {
return func(node *baseNode) {
node.certKey = certKey
}
}
// WithHeaders sets the HTTP headers to send, keyed by host.
func WithHeaders(headersByHost HeadersByHost) NodeOption {
return func(node *baseNode) {
node.headersByHost = headersByHost
}
}

278
taskfile/options.go Normal file
View File

@@ -0,0 +1,278 @@
package taskfile
import "time"
// WithInsecure allows the [Reader] to make insecure connections when reading
// remote taskfiles. By default, insecure connections are rejected.
func WithInsecure(insecure bool) *insecureOption {
return &insecureOption{insecure: insecure}
}
type insecureOption struct {
insecure bool
}
func (o *insecureOption) ApplyToReader(r *Reader) {
r.insecure = o.insecure
}
// WithDownload forces the [Reader] to download a fresh copy of the taskfile
// from the remote source.
func WithDownload(download bool) *downloadOption {
return &downloadOption{download: download}
}
type downloadOption struct {
download bool
}
func (o *downloadOption) ApplyToReader(r *Reader) {
r.download = o.download
}
// WithOffline stops the [Reader] 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) *offlineOption {
return &offlineOption{offline: offline}
}
type offlineOption struct {
offline bool
}
func (o *offlineOption) ApplyToReader(r *Reader) {
r.offline = o.offline
}
// WithTrustedHosts configures the [Reader] with a list of trusted hosts for remote
// Taskfiles. Hosts in this list will not prompt for user confirmation.
func WithTrustedHosts(trustedHosts []string) *trustedHostsOption {
return &trustedHostsOption{trustedHosts: trustedHosts}
}
type trustedHostsOption struct {
trustedHosts []string
}
func (o *trustedHostsOption) ApplyToReader(r *Reader) {
r.trustedHosts = o.trustedHosts
}
// WithTempDir sets the temporary directory that will be used by the [Reader].
// By default, the reader uses [os.TempDir].
func WithTempDir(tempDir string) *tempDirOption {
return &tempDirOption{tempDir: tempDir}
}
type tempDirOption struct {
tempDir string
}
func (o *tempDirOption) ApplyToReader(r *Reader) {
r.tempDir = o.tempDir
}
// WithCacheExpiryDuration sets the duration after which the cache is considered
// expired. By default, the cache is considered expired after 24 hours.
func WithCacheExpiryDuration(duration time.Duration) *cacheExpiryDurationOption {
return &cacheExpiryDurationOption{duration: duration}
}
type cacheExpiryDurationOption struct {
duration time.Duration
}
func (o *cacheExpiryDurationOption) ApplyToReader(r *Reader) {
r.cacheExpiryDuration = o.duration
}
// WithDebugFunc sets the debug function to be used by the [Reader]. If set,
// this function will be called with debug messages. This can be useful if the
// caller wants to log debug messages from the [Reader]. By default, no debug
// function is set and the logs are not written.
func WithDebugFunc(debugFunc DebugFunc) *debugFuncOption {
return &debugFuncOption{debugFunc: debugFunc}
}
type debugFuncOption struct {
debugFunc DebugFunc
}
func (o *debugFuncOption) ApplyToReader(r *Reader) {
r.debugFunc = o.debugFunc
}
// WithPromptFunc sets the prompt function to be used by the [Reader]. If set,
// this function will be called with prompt messages. The function should
// optionally log the message to the user and return nil if the prompt is
// accepted and the execution should continue. Otherwise, it should return an
// error which describes why the prompt was rejected. This can then be caught
// and used later when calling the [Reader.Read] method. By default, no prompt
// function is set and all prompts are automatically accepted.
func WithPromptFunc(promptFunc PromptFunc) *promptFuncOption {
return &promptFuncOption{promptFunc: promptFunc}
}
type promptFuncOption struct {
promptFunc PromptFunc
}
func (o *promptFuncOption) ApplyToReader(r *Reader) {
r.promptFunc = o.promptFunc
}
// WithCACert sets the path to a custom CA certificate for TLS connections.
func WithCACert(caCert string) *caCertOption {
return &caCertOption{caCert: caCert}
}
type caCertOption struct {
caCert string
}
func (o *caCertOption) ApplyToReader(r *Reader) {
r.caCert = o.caCert
}
func (o *caCertOption) ApplyToBaseNode(n *baseNode) {
n.caCert = o.caCert
}
// WithCert sets the path to a client certificate for TLS connections.
func WithCert(cert string) *certOption {
return &certOption{cert: cert}
}
type certOption struct {
cert string
}
func (o *certOption) ApplyToReader(r *Reader) {
r.cert = o.cert
}
func (o *certOption) ApplyToBaseNode(n *baseNode) {
n.cert = o.cert
}
// WithCertKey sets the path to a client certificate key for TLS connections.
func WithCertKey(certKey string) *certKeyOption {
return &certKeyOption{certKey: certKey}
}
type certKeyOption struct {
certKey string
}
func (o *certKeyOption) ApplyToReader(r *Reader) {
r.certKey = o.certKey
}
func (o *certKeyOption) ApplyToBaseNode(n *baseNode) {
n.certKey = o.certKey
}
// WithReaderHeaders sets the HTTP headers to send to each configured host.
func WithReaderHeaders(headersByHost HeadersByHost) *readerHeadersOption {
return &readerHeadersOption{headersByHost: headersByHost}
}
type readerHeadersOption struct {
headersByHost HeadersByHost
}
func (o *readerHeadersOption) ApplyToReader(r *Reader) {
r.headersByHost = o.headersByHost
}
// WithParent sets the parent node for the node base.
func WithParent(parent Node) *parentOption {
return &parentOption{parent: parent}
}
type parentOption struct {
parent Node
}
func (o *parentOption) ApplyToBaseNode(n *baseNode) {
n.parent = o.parent
}
// WithChecksum sets the checksum for the node base.
func WithChecksum(checksum string) *checksumOption {
return &checksumOption{checksum: checksum}
}
type checksumOption struct {
checksum string
}
func (o *checksumOption) ApplyToBaseNode(n *baseNode) {
n.checksum = o.checksum
}
// WithHeaders sets the HTTP headers to send, keyed by host.
func WithHeaders(headersByHost HeadersByHost) *headersOption {
return &headersOption{headersByHost: headersByHost}
}
type headersOption struct {
headersByHost HeadersByHost
}
func (o *headersOption) ApplyToBaseNode(n *baseNode) {
n.headersByHost = o.headersByHost
}
// WithLine specifies the line number that the [Snippet] should center around
// and point to.
func WithLine(line int) *lineOption {
return &lineOption{line: line}
}
type lineOption struct {
line int
}
func (o *lineOption) ApplyToSnippet(s *Snippet) {
s.line = o.line
}
// WithColumn specifies the column number that the [Snippet] should point to.
func WithColumn(column int) *columnOption {
return &columnOption{column: column}
}
type columnOption struct {
column int
}
func (o *columnOption) ApplyToSnippet(s *Snippet) {
s.column = o.column
}
// WithPadding specifies the number of lines to include before and after the
// selected line in the [Snippet].
func WithPadding(padding int) *paddingOption {
return &paddingOption{padding: padding}
}
type paddingOption struct {
padding int
}
func (o *paddingOption) ApplyToSnippet(s *Snippet) {
s.padding = o.padding
}
// WithNoIndicators specifies that the [Snippet] should not include line or
// column indicators.
func WithNoIndicators() *noIndicatorsOption {
return &noIndicatorsOption{}
}
type noIndicatorsOption struct{}
func (o *noIndicatorsOption) ApplyToSnippet(s *Snippet) {
s.noIndicators = true
}

View File

@@ -85,177 +85,6 @@ func (r *Reader) Options(opts ...ReaderOption) {
}
}
// WithInsecure allows the [Reader] to make insecure connections when reading
// remote taskfiles. By default, insecure connections are rejected.
func WithInsecure(insecure bool) ReaderOption {
return &insecureOption{insecure: insecure}
}
type insecureOption struct {
insecure bool
}
func (o *insecureOption) ApplyToReader(r *Reader) {
r.insecure = o.insecure
}
// WithDownload forces the [Reader] to download a fresh copy of the taskfile
// from the remote source.
func WithDownload(download bool) ReaderOption {
return &downloadOption{download: download}
}
type downloadOption struct {
download bool
}
func (o *downloadOption) ApplyToReader(r *Reader) {
r.download = o.download
}
// WithOffline stops the [Reader] 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) ReaderOption {
return &offlineOption{offline: offline}
}
type offlineOption struct {
offline bool
}
func (o *offlineOption) ApplyToReader(r *Reader) {
r.offline = o.offline
}
// WithTrustedHosts configures the [Reader] with a list of trusted hosts for remote
// Taskfiles. Hosts in this list will not prompt for user confirmation.
func WithTrustedHosts(trustedHosts []string) ReaderOption {
return &trustedHostsOption{trustedHosts: trustedHosts}
}
type trustedHostsOption struct {
trustedHosts []string
}
func (o *trustedHostsOption) ApplyToReader(r *Reader) {
r.trustedHosts = o.trustedHosts
}
// WithTempDir sets the temporary directory that will be used by the [Reader].
// By default, the reader uses [os.TempDir].
func WithTempDir(tempDir string) ReaderOption {
return &tempDirOption{tempDir: tempDir}
}
type tempDirOption struct {
tempDir string
}
func (o *tempDirOption) ApplyToReader(r *Reader) {
r.tempDir = o.tempDir
}
// WithCacheExpiryDuration sets the duration after which the cache is considered
// expired. By default, the cache is considered expired after 24 hours.
func WithCacheExpiryDuration(duration time.Duration) ReaderOption {
return &cacheExpiryDurationOption{duration: duration}
}
type cacheExpiryDurationOption struct {
duration time.Duration
}
func (o *cacheExpiryDurationOption) ApplyToReader(r *Reader) {
r.cacheExpiryDuration = o.duration
}
// WithDebugFunc sets the debug function to be used by the [Reader]. If set,
// this function will be called with debug messages. This can be useful if the
// caller wants to log debug messages from the [Reader]. By default, no debug
// function is set and the logs are not written.
func WithDebugFunc(debugFunc DebugFunc) ReaderOption {
return &debugFuncOption{debugFunc: debugFunc}
}
type debugFuncOption struct {
debugFunc DebugFunc
}
func (o *debugFuncOption) ApplyToReader(r *Reader) {
r.debugFunc = o.debugFunc
}
// WithPromptFunc sets the prompt function to be used by the [Reader]. If set,
// this function will be called with prompt messages. The function should
// optionally log the message to the user and return nil if the prompt is
// accepted and the execution should continue. Otherwise, it should return an
// error which describes why the prompt was rejected. This can then be caught
// and used later when calling the [Reader.Read] method. By default, no prompt
// function is set and all prompts are automatically accepted.
func WithPromptFunc(promptFunc PromptFunc) ReaderOption {
return &promptFuncOption{promptFunc: promptFunc}
}
type promptFuncOption struct {
promptFunc PromptFunc
}
func (o *promptFuncOption) ApplyToReader(r *Reader) {
r.promptFunc = o.promptFunc
}
// WithReaderCACert sets the path to a custom CA certificate for TLS connections.
func WithReaderCACert(caCert string) ReaderOption {
return &readerCACertOption{caCert: caCert}
}
type readerCACertOption struct {
caCert string
}
func (o *readerCACertOption) ApplyToReader(r *Reader) {
r.caCert = o.caCert
}
// WithReaderCert sets the path to a client certificate for TLS connections.
func WithReaderCert(cert string) ReaderOption {
return &readerCertOption{cert: cert}
}
type readerCertOption struct {
cert string
}
func (o *readerCertOption) ApplyToReader(r *Reader) {
r.cert = o.cert
}
// WithReaderCertKey sets the path to a client certificate key for TLS connections.
func WithReaderCertKey(certKey string) ReaderOption {
return &readerCertKeyOption{certKey: certKey}
}
type readerCertKeyOption struct {
certKey string
}
func (o *readerCertKeyOption) ApplyToReader(r *Reader) {
r.certKey = o.certKey
}
// WithReaderHeaders sets the HTTP headers to send to each configured host.
func WithReaderHeaders(headersByHost HeadersByHost) ReaderOption {
return &readerHeadersOption{headersByHost: headersByHost}
}
type readerHeadersOption struct {
headersByHost HeadersByHost
}
func (o *readerHeadersOption) ApplyToReader(r *Reader) {
r.headersByHost = o.headersByHost
}
// Read will read the Taskfile defined by the [Reader]'s [Node] and recurse
// through any [ast.Includes] it finds, reading each included Taskfile and
// building an [ast.TaskfileGraph] as it goes. If any errors occur, they will be

View File

@@ -84,59 +84,6 @@ func (s *Snippet) Options(opts ...SnippetOption) {
}
}
// WithLine specifies the line number that the [Snippet] should center around
// and point to.
func WithLine(line int) SnippetOption {
return &lineOption{line: line}
}
type lineOption struct {
line int
}
func (o *lineOption) ApplyToSnippet(s *Snippet) {
s.line = o.line
}
// WithColumn specifies the column number that the [Snippet] should point to.
func WithColumn(column int) SnippetOption {
return &columnOption{column: column}
}
type columnOption struct {
column int
}
func (o *columnOption) ApplyToSnippet(s *Snippet) {
s.column = o.column
}
// WithPadding specifies the number of lines to include before and after the
// selected line in the [Snippet].
func WithPadding(padding int) SnippetOption {
return &paddingOption{padding: padding}
}
type paddingOption struct {
padding int
}
func (o *paddingOption) ApplyToSnippet(s *Snippet) {
s.padding = o.padding
}
// WithNoIndicators specifies that the [Snippet] should not include line or
// column indicators.
func WithNoIndicators() SnippetOption {
return &noIndicatorsOption{}
}
type noIndicatorsOption struct{}
func (o *noIndicatorsOption) ApplyToSnippet(s *Snippet) {
s.noIndicators = true
}
func (s *Snippet) String() string {
buf := &bytes.Buffer{}

View File

@@ -44,7 +44,7 @@ func (r *Reader) Options(opts ...ReaderOption) {
// this function will be called with debug messages. This can be useful if the
// caller wants to log debug messages from the [Reader]. By default, no debug
// function is set and the logs are not written.
func WithDebugFunc(debugFunc DebugFunc) ReaderOption {
func WithDebugFunc(debugFunc DebugFunc) *debugFuncOption {
return &debugFuncOption{debugFunc: debugFunc}
}