mirror of
https://github.com/go-task/task.git
synced 2026-08-29 10:08:27 +02:00
135 lines
3.4 KiB
Go
135 lines
3.4 KiB
Go
package ast
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
// ReferencesFingerprintVar reports whether the task references the variable
|
|
// produced by the given fingerprint method in fields compiled after it.
|
|
func (t *Task) ReferencesFingerprintVar(kind string) bool {
|
|
name := strings.ToUpper(kind)
|
|
if t == nil || name == "" {
|
|
return false
|
|
}
|
|
|
|
for _, status := range t.Status {
|
|
if stringReferencesFingerprintVar(status, name) {
|
|
return true
|
|
}
|
|
}
|
|
for _, cmd := range t.Cmds {
|
|
if cmdReferencesFingerprintVar(cmd, name) {
|
|
return true
|
|
}
|
|
}
|
|
for _, dep := range t.Deps {
|
|
if depReferencesFingerprintVar(dep, name) {
|
|
return true
|
|
}
|
|
}
|
|
for _, precondition := range t.Preconditions {
|
|
if preconditionReferencesFingerprintVar(precondition, name) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func cmdReferencesFingerprintVar(cmd *Cmd, name string) bool {
|
|
if cmd == nil {
|
|
return false
|
|
}
|
|
return stringReferencesFingerprintVar(cmd.Cmd, name) ||
|
|
stringReferencesFingerprintVar(cmd.Task, name) ||
|
|
stringReferencesFingerprintVar(cmd.If, name) ||
|
|
forReferencesFingerprintVar(cmd.For, name) ||
|
|
varsReferenceFingerprintVar(cmd.Vars, name)
|
|
}
|
|
|
|
func depReferencesFingerprintVar(dep *Dep, name string) bool {
|
|
if dep == nil {
|
|
return false
|
|
}
|
|
return stringReferencesFingerprintVar(dep.Task, name) ||
|
|
forReferencesFingerprintVar(dep.For, name) ||
|
|
varsReferenceFingerprintVar(dep.Vars, name)
|
|
}
|
|
|
|
func preconditionReferencesFingerprintVar(precondition *Precondition, name string) bool {
|
|
if precondition == nil {
|
|
return false
|
|
}
|
|
return stringReferencesFingerprintVar(precondition.Sh, name) ||
|
|
stringReferencesFingerprintVar(precondition.Msg, name)
|
|
}
|
|
|
|
func forReferencesFingerprintVar(f *For, name string) bool {
|
|
if f == nil {
|
|
return false
|
|
}
|
|
if valueReferencesFingerprintVar(f.List, name) {
|
|
return true
|
|
}
|
|
for _, row := range f.Matrix.All() {
|
|
if row != nil && (stringReferencesFingerprintVar(row.Ref, name) ||
|
|
valueReferencesFingerprintVar(row.Value, name)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func varsReferenceFingerprintVar(vars *Vars, name string) bool {
|
|
for _, v := range vars.All() {
|
|
if valueReferencesFingerprintVar(v.Value, name) ||
|
|
valueReferencesFingerprintVar(v.Live, name) ||
|
|
stringPointerReferencesFingerprintVar(v.Sh, name) ||
|
|
stringReferencesFingerprintVar(v.Ref, name) ||
|
|
stringReferencesFingerprintVar(v.Dir, name) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func valueReferencesFingerprintVar(value any, name string) bool {
|
|
if value == nil {
|
|
return false
|
|
}
|
|
if s, ok := value.(string); ok {
|
|
return stringReferencesFingerprintVar(s, name)
|
|
}
|
|
|
|
rv := reflect.ValueOf(value)
|
|
switch rv.Kind() {
|
|
case reflect.Pointer, reflect.Interface:
|
|
if rv.IsNil() {
|
|
return false
|
|
}
|
|
return valueReferencesFingerprintVar(rv.Elem().Interface(), name)
|
|
case reflect.Array, reflect.Slice:
|
|
for i := 0; i < rv.Len(); i++ {
|
|
if valueReferencesFingerprintVar(rv.Index(i).Interface(), name) {
|
|
return true
|
|
}
|
|
}
|
|
case reflect.Map:
|
|
for _, key := range rv.MapKeys() {
|
|
if valueReferencesFingerprintVar(key.Interface(), name) ||
|
|
valueReferencesFingerprintVar(rv.MapIndex(key).Interface(), name) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func stringPointerReferencesFingerprintVar(s *string, name string) bool {
|
|
return s != nil && stringReferencesFingerprintVar(*s, name)
|
|
}
|
|
|
|
func stringReferencesFingerprintVar(s string, name string) bool {
|
|
return strings.Contains(s, name)
|
|
}
|