feat: wildcard matching for task names #1489
Merged
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Fixes #836
Context
This PR is a proposal for a design that would allow basic wildcard matching for task names. At the moment, if users want to make a generic task that performs a common set of operations on many different services or directories (etc) they must either:
.CLI_ARGS
and the--
operatorBoth of these methods can be clunky to type into a CLI and are not very intuitive.
make
has the option to do wildcard matching (using%
). This PR is a proposal to do the equivalent in Task.Proposal
When a Taskfile has a task with a name that contains a wildcard (
*
) and the user callstask
with a task name that "matches" a wildcard task, that task will be run. Matches will occur by replacing any instances of*
with the(.*)
regex string and doing a regex match. The captured variables will be made available to the Task via theMATCH
variable in the form of an array. For example:> task start-foo Starting foo ...
Implementation
The first commit updates all usages of
ast.Call
to be passed by reference. Doing this allows methods that accept a call to update the call's variables. This means we can add any wildcard matches into thecall.Vars
without have to propagate them and change a bunch of function signatures.Other than this, the implementation is very simple, we are simply overriding the
omap.Get()
method by adding aGet()
method directly onast.Tasks
and then adding a simpleWildcardMatch()
function toast.Task
which will work out if a Task matches the call and retrieve the wildcard variablesNotes
I haven't written any docs yet since I'd like some feedback on the design/implementation. I'll add this once we've decided we're happy with it. What do people think about the naming? i.e.
*
andMATCH
. There were some other ideas discussed in #836, but I think starting with simple wildcard matching is probably a good start. I personally, would find this to be more than enough for my use cases.Final note. The
omap.Range()
function doesn't support yielding right now so there is a bit of a hack to get around this (seeTODO
in code). There is an interesting iterator proposal that will be introduced to Golang 1.22 as an experiment. This would be a really good solution to this, but we probably won't be able to add this until it is added to the language permanently (probably 1.23) and we drop support for 1.22 (so around a year from now).