mirror of
https://github.com/go-task/task.git
synced 2026-09-02 12:16:04 +02:00
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
|
|
// Package refs resolves the `ref` fields of a Taskfile into concrete values.
|
||
|
|
package refs
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"github.com/go-task/task/v3/internal/slicesext"
|
||
|
|
"github.com/go-task/task/v3/internal/templater"
|
||
|
|
"github.com/go-task/task/v3/taskfile/ast"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Declared lists resolve to a []any, but `keys` and `splitList` return a []string.
|
||
|
|
func AsList(v any) ([]any, bool) {
|
||
|
|
switch value := v.(type) {
|
||
|
|
case []any:
|
||
|
|
return value, true
|
||
|
|
case []string:
|
||
|
|
return slicesext.AsAny(value), true
|
||
|
|
case []int:
|
||
|
|
return slicesext.AsAny(value), true
|
||
|
|
}
|
||
|
|
return nil, false
|
||
|
|
}
|
||
|
|
|
||
|
|
func ResolveEnums(requires *ast.Requires, cache *templater.Cache) error {
|
||
|
|
if requires == nil || len(requires.Vars) == 0 {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
for _, v := range requires.Vars {
|
||
|
|
if v.Enum == nil || v.Enum.Ref == "" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
resolved := templater.ResolveRef(v.Enum.Ref, cache)
|
||
|
|
if cache.Err() != nil {
|
||
|
|
return cache.Err()
|
||
|
|
}
|
||
|
|
arr, ok := AsList(resolved)
|
||
|
|
if !ok {
|
||
|
|
return fmt.Errorf("enum reference %q must resolve to a list", v.Enum.Ref)
|
||
|
|
}
|
||
|
|
strValues := make([]string, 0, len(arr))
|
||
|
|
for _, item := range arr {
|
||
|
|
s, ok := item.(string)
|
||
|
|
if !ok {
|
||
|
|
return fmt.Errorf("enum reference %q must contain only strings", v.Enum.Ref)
|
||
|
|
}
|
||
|
|
strValues = append(strValues, s)
|
||
|
|
}
|
||
|
|
v.Enum.Value = strValues
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// A ref depending on dynamic vars may not resolve: the copy then has no enum
|
||
|
|
// value, which the interactive prompter treats as free-form input.
|
||
|
|
func ResolveEnum(v *ast.VarsWithValidation, vars *ast.Vars) *ast.VarsWithValidation {
|
||
|
|
if v.Enum == nil || v.Enum.Ref == "" || len(v.Enum.Value) > 0 {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
vCopy := v.DeepCopy()
|
||
|
|
cache := &templater.Cache{Vars: vars}
|
||
|
|
_ = ResolveEnums(&ast.Requires{Vars: []*ast.VarsWithValidation{vCopy}}, cache)
|
||
|
|
return vCopy
|
||
|
|
}
|