mirror of
https://github.com/go-task/task.git
synced 2025-04-13 11:50:50 +02:00
fix: deep copy included tasks
This commit is contained in:
parent
bb79fa1dc3
commit
d33906b6e4
23
taskfile/copy.go
Normal file
23
taskfile/copy.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package taskfile
|
||||||
|
|
||||||
|
import "golang.org/x/exp/constraints"
|
||||||
|
|
||||||
|
func deepCopySlice[T any](orig []T) []T {
|
||||||
|
if orig == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c := make([]T, len(orig))
|
||||||
|
copy(c, orig)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func deepCopyMap[K constraints.Ordered, V any](orig map[K]V) map[K]V {
|
||||||
|
if orig == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c := make(map[K]V, len(orig))
|
||||||
|
for k, v := range orig {
|
||||||
|
c[k] = v
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
@ -120,6 +120,23 @@ func (it *IncludedTaskfile) UnmarshalYAML(unmarshal func(interface{}) error) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopy creates a new instance of IncludedTaskfile and copies
|
||||||
|
// data by value from the source struct.
|
||||||
|
func (it *IncludedTaskfile) DeepCopy() *IncludedTaskfile {
|
||||||
|
if it == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &IncludedTaskfile{
|
||||||
|
Taskfile: it.Taskfile,
|
||||||
|
Dir: it.Dir,
|
||||||
|
Optional: it.Optional,
|
||||||
|
Internal: it.Internal,
|
||||||
|
AdvancedImport: it.AdvancedImport,
|
||||||
|
Vars: it.Vars.DeepCopy(),
|
||||||
|
BaseDir: it.BaseDir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FullTaskfilePath returns the fully qualified path to the included taskfile
|
// FullTaskfilePath returns the fully qualified path to the included taskfile
|
||||||
func (it *IncludedTaskfile) FullTaskfilePath() (string, error) {
|
func (it *IncludedTaskfile) FullTaskfilePath() (string, error) {
|
||||||
return it.resolvePath(it.Taskfile)
|
return it.resolvePath(it.Taskfile)
|
||||||
|
@ -39,19 +39,14 @@ func Merge(t1, t2 *Taskfile, includedTaskfile *IncludedTaskfile, namespaces ...s
|
|||||||
t1.Tasks = make(Tasks)
|
t1.Tasks = make(Tasks)
|
||||||
}
|
}
|
||||||
for k, v := range t2.Tasks {
|
for k, v := range t2.Tasks {
|
||||||
// FIXME(@andreynering): Refactor this block, otherwise we can
|
// We do a deep copy of the task struct here to ensure that no data can
|
||||||
// have serious side-effects in the future, since we're editing
|
// be changed elsewhere once the taskfile is merged.
|
||||||
// the original references instead of deep copying them.
|
task := v.DeepCopy()
|
||||||
task := v
|
|
||||||
|
|
||||||
// Set the task to internal if EITHER the included task or the included
|
// Set the task to internal if EITHER the included task or the included
|
||||||
// taskfile are marked as internal
|
// taskfile are marked as internal
|
||||||
task.Internal = task.Internal || includedTaskfile.Internal
|
task.Internal = task.Internal || includedTaskfile.Internal
|
||||||
|
|
||||||
// Deep copy the aliases so we can use them later
|
|
||||||
origAliases := make([]string, len(task.Aliases))
|
|
||||||
copy(origAliases, task.Aliases)
|
|
||||||
|
|
||||||
// Add namespaces to dependencies, commands and aliases
|
// Add namespaces to dependencies, commands and aliases
|
||||||
for _, dep := range task.Deps {
|
for _, dep := range task.Deps {
|
||||||
dep.Task = taskNameWithNamespace(dep.Task, namespaces...)
|
dep.Task = taskNameWithNamespace(dep.Task, namespaces...)
|
||||||
@ -67,8 +62,8 @@ func Merge(t1, t2 *Taskfile, includedTaskfile *IncludedTaskfile, namespaces ...s
|
|||||||
// Add namespace aliases
|
// Add namespace aliases
|
||||||
if includedTaskfile != nil {
|
if includedTaskfile != nil {
|
||||||
for _, namespaceAlias := range includedTaskfile.Aliases {
|
for _, namespaceAlias := range includedTaskfile.Aliases {
|
||||||
for _, alias := range origAliases {
|
for _, alias := range v.Aliases {
|
||||||
task.Aliases = append(v.Aliases, taskNameWithNamespace(alias, namespaceAlias))
|
task.Aliases = append(task.Aliases, taskNameWithNamespace(alias, namespaceAlias))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,3 +98,35 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
t.Run = task.Run
|
t.Run = task.Run
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopy creates a new instance of Task and copies
|
||||||
|
// data by value from the source struct.
|
||||||
|
func (t *Task) DeepCopy() *Task {
|
||||||
|
c := &Task{
|
||||||
|
Task: t.Task,
|
||||||
|
Cmds: deepCopySlice(t.Cmds),
|
||||||
|
Deps: deepCopySlice(t.Deps),
|
||||||
|
Label: t.Label,
|
||||||
|
Desc: t.Desc,
|
||||||
|
Summary: t.Summary,
|
||||||
|
Aliases: deepCopySlice(t.Aliases),
|
||||||
|
Sources: deepCopySlice(t.Sources),
|
||||||
|
Generates: deepCopySlice(t.Generates),
|
||||||
|
Status: deepCopySlice(t.Status),
|
||||||
|
Preconditions: deepCopySlice(t.Preconditions),
|
||||||
|
Dir: t.Dir,
|
||||||
|
Vars: t.Vars.DeepCopy(),
|
||||||
|
Env: t.Env.DeepCopy(),
|
||||||
|
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(),
|
||||||
|
IncludedTaskfile: t.IncludedTaskfile.DeepCopy(),
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
@ -34,6 +34,18 @@ func (vs *Vars) UnmarshalYAML(node *yaml.Node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopy creates a new instance of Vars and copies
|
||||||
|
// data by value from the source struct.
|
||||||
|
func (vs *Vars) DeepCopy() *Vars {
|
||||||
|
if vs == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &Vars{
|
||||||
|
Keys: deepCopySlice(vs.Keys),
|
||||||
|
Mapping: deepCopyMap(vs.Mapping),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Merge merges the given Vars into the caller one
|
// Merge merges the given Vars into the caller one
|
||||||
func (vs *Vars) Merge(other *Vars) {
|
func (vs *Vars) Merge(other *Vars) {
|
||||||
_ = other.Range(func(key string, value Var) error {
|
_ = other.Range(func(key string, value Var) error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user