1
0
mirror of https://github.com/go-task/task.git synced 2024-12-14 10:52:43 +02:00
task/taskfile/ast/task.go

226 lines
5.8 KiB
Go
Raw Normal View History

package ast
import (
"fmt"
2024-01-27 17:51:43 +02:00
"regexp"
"strings"
"gopkg.in/yaml.v3"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"
)
// Task represents a task
type Task struct {
Task string
Cmds []*Cmd
Deps []*Dep
Label string
Desc string
Prompt string
Summary string
Requires *Requires
Aliases []string
Sources []*Glob
Generates []*Glob
Status []string
Preconditions []*Precondition
Dir string
Set []string
Shopt []string
Vars *Vars
Env *Vars
Dotenv []string
Silent bool
Interactive bool
Internal bool
Method string
Prefix string
IgnoreError bool
Run string
Platforms []*Platform
Watch bool
Location *Location
// Populated during merging
Namespace string
2022-03-19 23:41:03 +02:00
IncludeVars *Vars
IncludedTaskfileVars *Vars
}
func (t *Task) Name() string {
if t.Label != "" {
return t.Label
}
return t.Task
}
func (t *Task) LocalName() string {
name := t.Task
name = strings.TrimPrefix(name, t.Namespace)
name = strings.TrimPrefix(name, ":")
return name
}
2024-01-27 17:51:43 +02:00
// 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 {
switch node.Kind {
// Shortcut syntax for a task with a single command
case yaml.ScalarNode:
var cmd Cmd
if err := node.Decode(&cmd); err != nil {
return errors.NewTaskfileDecodeError(err, node)
}
t.Cmds = append(t.Cmds, &cmd)
return nil
// Shortcut syntax for a simple task with a list of commands
case yaml.SequenceNode:
var cmds []*Cmd
if err := node.Decode(&cmds); err != nil {
return errors.NewTaskfileDecodeError(err, node)
}
t.Cmds = cmds
return nil
// Full task object
case yaml.MappingNode:
var task struct {
Cmds []*Cmd
Cmd *Cmd
Deps []*Dep
Label string
Desc string
Prompt string
Summary string
Aliases []string
Sources []*Glob
Generates []*Glob
Status []string
Preconditions []*Precondition
Dir string
Set []string
Shopt []string
Vars *Vars
Env *Vars
Dotenv []string
Silent bool
Interactive bool
Internal bool
Method string
Prefix string
IgnoreError bool `yaml:"ignore_error"`
Run string
Platforms []*Platform
Requires *Requires
Watch bool
}
if err := node.Decode(&task); err != nil {
return errors.NewTaskfileDecodeError(err, node)
}
if task.Cmd != nil {
if task.Cmds != nil {
return errors.NewTaskfileDecodeError(nil, node).WithMessage("task cannot have both cmd and cmds")
}
t.Cmds = []*Cmd{task.Cmd}
} else {
t.Cmds = task.Cmds
}
t.Deps = task.Deps
t.Label = task.Label
t.Desc = task.Desc
t.Prompt = task.Prompt
t.Summary = task.Summary
t.Aliases = task.Aliases
t.Sources = task.Sources
t.Generates = task.Generates
t.Status = task.Status
t.Preconditions = task.Preconditions
t.Dir = task.Dir
t.Set = task.Set
t.Shopt = task.Shopt
t.Vars = task.Vars
t.Env = task.Env
t.Dotenv = task.Dotenv
t.Silent = task.Silent
t.Interactive = task.Interactive
t.Internal = task.Internal
t.Method = task.Method
t.Prefix = task.Prefix
t.IgnoreError = task.IgnoreError
t.Run = task.Run
t.Platforms = task.Platforms
t.Requires = task.Requires
t.Watch = task.Watch
return nil
}
return errors.NewTaskfileDecodeError(nil, node).WithTypeMessage("task")
}
2022-10-02 07:45:27 +02:00
// DeepCopy creates a new instance of Task and copies
// data by value from the source struct.
func (t *Task) DeepCopy() *Task {
if t == nil {
return nil
}
2022-10-02 07:45:27 +02:00
c := &Task{
Task: t.Task,
Cmds: deepcopy.Slice(t.Cmds),
Deps: deepcopy.Slice(t.Deps),
2022-10-02 07:45:27 +02:00
Label: t.Label,
Desc: t.Desc,
Prompt: t.Prompt,
2022-10-02 07:45:27 +02:00
Summary: t.Summary,
Aliases: deepcopy.Slice(t.Aliases),
Sources: deepcopy.Slice(t.Sources),
Generates: deepcopy.Slice(t.Generates),
Status: deepcopy.Slice(t.Status),
Preconditions: deepcopy.Slice(t.Preconditions),
2022-10-02 07:45:27 +02:00
Dir: t.Dir,
Set: deepcopy.Slice(t.Set),
Shopt: deepcopy.Slice(t.Shopt),
2022-10-02 07:45:27 +02:00
Vars: t.Vars.DeepCopy(),
Env: t.Env.DeepCopy(),
Dotenv: deepcopy.Slice(t.Dotenv),
2022-10-02 07:45:27 +02:00
Silent: t.Silent,
Interactive: t.Interactive,
Internal: t.Internal,
Method: t.Method,
Prefix: t.Prefix,
IgnoreError: t.IgnoreError,
Run: t.Run,
IncludeVars: t.IncludeVars.DeepCopy(),
IncludedTaskfileVars: t.IncludedTaskfileVars.DeepCopy(),
Platforms: deepcopy.Slice(t.Platforms),
Location: t.Location.DeepCopy(),
Requires: t.Requires.DeepCopy(),
Namespace: t.Namespace,
2022-10-02 07:45:27 +02:00
}
return c
}