mirror of
https://github.com/go-task/task.git
synced 2025-05-17 22:32:40 +02:00
feat: wildcard matching of task names
This commit is contained in:
parent
1ef5cf71d0
commit
9a3d2bc3aa
@ -2,6 +2,8 @@ package ast
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
@ -51,6 +53,30 @@ func (t *Task) Name() string {
|
|||||||
return t.Task
|
return t.Task
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WildcardMatch will check if the given string matches the name of the Task and returns any wildcard values.
|
||||||
|
func (t *Task) WildcardMatch(name string) (bool, []string) {
|
||||||
|
// Convert the name into a regex string
|
||||||
|
regexStr := fmt.Sprintf("^%s$", strings.ReplaceAll(t.Task, "*", "(.*)"))
|
||||||
|
regex := regexp.MustCompile(regexStr)
|
||||||
|
wildcards := regex.FindStringSubmatch(name)
|
||||||
|
wildcardCount := strings.Count(t.Task, "*")
|
||||||
|
|
||||||
|
// If there are no wildcards, return false
|
||||||
|
if len(wildcards) == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the first match, which is the full string
|
||||||
|
wildcards = wildcards[1:]
|
||||||
|
|
||||||
|
// If there are more/less wildcards than matches, return false
|
||||||
|
if len(wildcards) != wildcardCount {
|
||||||
|
return false, wildcards
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, wildcards
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Task) UnmarshalYAML(node *yaml.Node) error {
|
func (t *Task) UnmarshalYAML(node *yaml.Node) error {
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
|
|
||||||
|
@ -14,6 +14,31 @@ type Tasks struct {
|
|||||||
omap.OrderedMap[string, *Task]
|
omap.OrderedMap[string, *Task]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tasks) Get(call *Call) *Task {
|
||||||
|
if call == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var task *Task
|
||||||
|
// If there is a direct match, return it
|
||||||
|
if task = t.OrderedMap.Get(call.Task); task != nil {
|
||||||
|
return task
|
||||||
|
}
|
||||||
|
if call.Vars == nil {
|
||||||
|
call.Vars = &Vars{}
|
||||||
|
}
|
||||||
|
// Attempt a wildcard match
|
||||||
|
// TODO: We need to add a yield func to the Range method so that we can stop looping when we find a match
|
||||||
|
// For now, we can just nil check the task before each loop
|
||||||
|
_ = t.Range(func(key string, value *Task) error {
|
||||||
|
if match, wildcards := value.WildcardMatch(call.Task); match && task == nil {
|
||||||
|
task = value
|
||||||
|
call.Vars.Set("MATCH", Var{Value: wildcards})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return task
|
||||||
|
}
|
||||||
|
|
||||||
func (t1 *Tasks) Merge(t2 Tasks, include *Include) {
|
func (t1 *Tasks) Merge(t2 Tasks, include *Include) {
|
||||||
_ = t2.Range(func(k string, v *Task) error {
|
_ = t2.Range(func(k string, v *Task) error {
|
||||||
// We do a deep copy of the task struct here to ensure that no data can
|
// We do a deep copy of the task struct here to ensure that no data can
|
||||||
|
16
testdata/wildcards/Taskfile.yml
vendored
Normal file
16
testdata/wildcards/Taskfile.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
version: 3
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
wildcard-*:
|
||||||
|
cmds:
|
||||||
|
- echo "Hello {{index .MATCH 0}}"
|
||||||
|
|
||||||
|
'*-wildcard-*':
|
||||||
|
cmds:
|
||||||
|
- echo "Hello {{index .MATCH 0}} {{index .MATCH 1}}"
|
||||||
|
|
||||||
|
start-*:
|
||||||
|
vars:
|
||||||
|
SERVICE: "{{index .MATCH 0}}"
|
||||||
|
cmds:
|
||||||
|
- echo "Starting {{.SERVICE}}"
|
Loading…
x
Reference in New Issue
Block a user