mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
Extend hcl2 support with more functions
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
44
vendor/github.com/zclconf/go-cty/cty/function/function.go
generated
vendored
44
vendor/github.com/zclconf/go-cty/cty/function/function.go
generated
vendored
@ -244,19 +244,21 @@ func (f Function) Call(args []cty.Value) (val cty.Value, err error) {
|
||||
return cty.UnknownVal(expectedType), nil
|
||||
}
|
||||
|
||||
if val.IsMarked() && !spec.AllowMarked {
|
||||
unwrappedVal, marks := val.Unmark()
|
||||
// In order to avoid additional overhead on applications that
|
||||
// are not using marked values, we copy the given args only
|
||||
// if we encounter a marked value we need to unmark. However,
|
||||
// as a consequence we end up doing redundant copying if multiple
|
||||
// marked values need to be unwrapped. That seems okay because
|
||||
// argument lists are generally small.
|
||||
newArgs := make([]cty.Value, len(args))
|
||||
copy(newArgs, args)
|
||||
newArgs[i] = unwrappedVal
|
||||
resultMarks = append(resultMarks, marks)
|
||||
args = newArgs
|
||||
if !spec.AllowMarked {
|
||||
unwrappedVal, marks := val.UnmarkDeep()
|
||||
if len(marks) > 0 {
|
||||
// In order to avoid additional overhead on applications that
|
||||
// are not using marked values, we copy the given args only
|
||||
// if we encounter a marked value we need to unmark. However,
|
||||
// as a consequence we end up doing redundant copying if multiple
|
||||
// marked values need to be unwrapped. That seems okay because
|
||||
// argument lists are generally small.
|
||||
newArgs := make([]cty.Value, len(args))
|
||||
copy(newArgs, args)
|
||||
newArgs[i] = unwrappedVal
|
||||
resultMarks = append(resultMarks, marks)
|
||||
args = newArgs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,13 +268,15 @@ func (f Function) Call(args []cty.Value) (val cty.Value, err error) {
|
||||
if !val.IsKnown() && !spec.AllowUnknown {
|
||||
return cty.UnknownVal(expectedType), nil
|
||||
}
|
||||
if val.IsMarked() && !spec.AllowMarked {
|
||||
unwrappedVal, marks := val.Unmark()
|
||||
newArgs := make([]cty.Value, len(args))
|
||||
copy(newArgs, args)
|
||||
newArgs[len(posArgs)+i] = unwrappedVal
|
||||
resultMarks = append(resultMarks, marks)
|
||||
args = newArgs
|
||||
if !spec.AllowMarked {
|
||||
unwrappedVal, marks := val.UnmarkDeep()
|
||||
if len(marks) > 0 {
|
||||
newArgs := make([]cty.Value, len(args))
|
||||
copy(newArgs, args)
|
||||
newArgs[len(posArgs)+i] = unwrappedVal
|
||||
resultMarks = append(resultMarks, marks)
|
||||
args = newArgs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go
generated
vendored
38
vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go
generated
vendored
@ -138,6 +138,13 @@ var ElementFunc = function.New(&function.Spec{
|
||||
},
|
||||
Type: func(args []cty.Value) (cty.Type, error) {
|
||||
list := args[0]
|
||||
index := args[1]
|
||||
if index.IsKnown() {
|
||||
if index.LessThan(cty.NumberIntVal(0)).True() {
|
||||
return cty.DynamicPseudoType, fmt.Errorf("cannot use element function with a negative index")
|
||||
}
|
||||
}
|
||||
|
||||
listTy := list.Type()
|
||||
switch {
|
||||
case listTy.IsListType():
|
||||
@ -173,6 +180,10 @@ var ElementFunc = function.New(&function.Spec{
|
||||
return cty.DynamicVal, fmt.Errorf("invalid index: %s", err)
|
||||
}
|
||||
|
||||
if args[1].LessThan(cty.NumberIntVal(0)).True() {
|
||||
return cty.DynamicVal, fmt.Errorf("cannot use element function with a negative index")
|
||||
}
|
||||
|
||||
if !args[0].IsKnown() {
|
||||
return cty.UnknownVal(retType), nil
|
||||
}
|
||||
@ -240,6 +251,10 @@ var CoalesceListFunc = function.New(&function.Spec{
|
||||
return cty.UnknownVal(retType), nil
|
||||
}
|
||||
|
||||
if arg.IsNull() {
|
||||
continue
|
||||
}
|
||||
|
||||
if arg.LengthInt() > 0 {
|
||||
return arg, nil
|
||||
}
|
||||
@ -492,6 +507,11 @@ var FlattenFunc = function.New(&function.Spec{
|
||||
// We can flatten lists with unknown values, as long as they are not
|
||||
// lists themselves.
|
||||
func flattener(flattenList cty.Value) ([]cty.Value, bool) {
|
||||
if !flattenList.Length().IsKnown() {
|
||||
// If we don't know the length of what we're flattening then we can't
|
||||
// predict the length of our result yet either.
|
||||
return nil, false
|
||||
}
|
||||
out := make([]cty.Value, 0)
|
||||
for it := flattenList.ElementIterator(); it.Next(); {
|
||||
_, val := it.Element()
|
||||
@ -742,16 +762,10 @@ var MergeFunc = function.New(&function.Spec{
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
outputMap := make(map[string]cty.Value)
|
||||
|
||||
// if all inputs are null, return a null value rather than an object
|
||||
// with null attributes
|
||||
allNull := true
|
||||
for _, arg := range args {
|
||||
if arg.IsNull() {
|
||||
continue
|
||||
} else {
|
||||
allNull = false
|
||||
}
|
||||
|
||||
for it := arg.ElementIterator(); it.Next(); {
|
||||
k, v := it.Element()
|
||||
outputMap[k.AsString()] = v
|
||||
@ -759,9 +773,10 @@ var MergeFunc = function.New(&function.Spec{
|
||||
}
|
||||
|
||||
switch {
|
||||
case allNull:
|
||||
return cty.NullVal(retType), nil
|
||||
case retType.IsMapType():
|
||||
if len(outputMap) == 0 {
|
||||
return cty.MapValEmpty(retType.ElementType()), nil
|
||||
}
|
||||
return cty.MapVal(outputMap), nil
|
||||
case retType.IsObjectType(), retType.Equals(cty.DynamicPseudoType):
|
||||
return cty.ObjectVal(outputMap), nil
|
||||
@ -869,6 +884,10 @@ var SetProductFunc = function.New(&function.Spec{
|
||||
|
||||
total := 1
|
||||
for _, arg := range args {
|
||||
if !arg.Length().IsKnown() {
|
||||
return cty.UnknownVal(retType), nil
|
||||
}
|
||||
|
||||
// Because of our type checking function, we are guaranteed that
|
||||
// all of the arguments are known, non-null values of types that
|
||||
// support LengthInt.
|
||||
@ -1016,7 +1035,8 @@ func sliceIndexes(args []cty.Value) (int, int, bool, error) {
|
||||
var startIndex, endIndex, length int
|
||||
var startKnown, endKnown, lengthKnown bool
|
||||
|
||||
if args[0].Type().IsTupleType() || args[0].IsKnown() { // if it's a tuple then we always know the length by the type, but lists must be known
|
||||
// If it's a tuple then we always know the length by the type, but collections might be unknown or have unknown length
|
||||
if args[0].Type().IsTupleType() || args[0].Length().IsKnown() {
|
||||
length = args[0].LengthInt()
|
||||
lengthKnown = true
|
||||
}
|
||||
|
11
vendor/github.com/zclconf/go-cty/cty/function/stdlib/datetime.go
generated
vendored
11
vendor/github.com/zclconf/go-cty/cty/function/stdlib/datetime.go
generated
vendored
@ -362,9 +362,14 @@ func splitDateFormat(data []byte, atEOF bool) (advance int, token []byte, err er
|
||||
for i := 1; i < len(data); i++ {
|
||||
if data[i] == esc {
|
||||
if (i + 1) == len(data) {
|
||||
// We need at least one more byte to decide if this is an
|
||||
// escape or a terminator.
|
||||
return 0, nil, nil
|
||||
if atEOF {
|
||||
// We have a closing quote and are at the end of our input
|
||||
return len(data), data, nil
|
||||
} else {
|
||||
// We need at least one more byte to decide if this is an
|
||||
// escape or a terminator.
|
||||
return 0, nil, nil
|
||||
}
|
||||
}
|
||||
if data[i+1] == esc {
|
||||
i++ // doubled-up quotes are an escape sequence
|
||||
|
2
vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go
generated
vendored
2
vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go
generated
vendored
@ -85,7 +85,7 @@ var FormatListFunc = function.New(&function.Spec{
|
||||
argTy := arg.Type()
|
||||
switch {
|
||||
case (argTy.IsListType() || argTy.IsSetType() || argTy.IsTupleType()) && !arg.IsNull():
|
||||
if !argTy.IsTupleType() && !arg.IsKnown() {
|
||||
if !argTy.IsTupleType() && !(arg.IsKnown() && arg.Length().IsKnown()) {
|
||||
// We can't iterate this one at all yet then, so we can't
|
||||
// yet produce a result.
|
||||
unknowns[i] = true
|
||||
|
5
vendor/github.com/zclconf/go-cty/cty/function/stdlib/json.go
generated
vendored
5
vendor/github.com/zclconf/go-cty/cty/function/stdlib/json.go
generated
vendored
@ -12,6 +12,7 @@ var JSONEncodeFunc = function.New(&function.Spec{
|
||||
Name: "val",
|
||||
Type: cty.DynamicPseudoType,
|
||||
AllowDynamicType: true,
|
||||
AllowNull: true,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
@ -24,6 +25,10 @@ var JSONEncodeFunc = function.New(&function.Spec{
|
||||
return cty.UnknownVal(retType), nil
|
||||
}
|
||||
|
||||
if val.IsNull() {
|
||||
return cty.StringVal("null"), nil
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(val, val.Type())
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
|
41
vendor/github.com/zclconf/go-cty/cty/function/stdlib/set.go
generated
vendored
41
vendor/github.com/zclconf/go-cty/cty/function/stdlib/set.go
generated
vendored
@ -44,7 +44,7 @@ var SetUnionFunc = function.New(&function.Spec{
|
||||
Type: setOperationReturnType,
|
||||
Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
|
||||
return s1.Union(s2)
|
||||
}),
|
||||
}, true),
|
||||
})
|
||||
|
||||
var SetIntersectionFunc = function.New(&function.Spec{
|
||||
@ -63,7 +63,7 @@ var SetIntersectionFunc = function.New(&function.Spec{
|
||||
Type: setOperationReturnType,
|
||||
Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
|
||||
return s1.Intersection(s2)
|
||||
}),
|
||||
}, false),
|
||||
})
|
||||
|
||||
var SetSubtractFunc = function.New(&function.Spec{
|
||||
@ -82,7 +82,7 @@ var SetSubtractFunc = function.New(&function.Spec{
|
||||
Type: setOperationReturnType,
|
||||
Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
|
||||
return s1.Subtract(s2)
|
||||
}),
|
||||
}, false),
|
||||
})
|
||||
|
||||
var SetSymmetricDifferenceFunc = function.New(&function.Spec{
|
||||
@ -100,8 +100,8 @@ var SetSymmetricDifferenceFunc = function.New(&function.Spec{
|
||||
},
|
||||
Type: setOperationReturnType,
|
||||
Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
|
||||
return s1.Subtract(s2)
|
||||
}),
|
||||
return s1.SymmetricDifference(s2)
|
||||
}, false),
|
||||
})
|
||||
|
||||
// SetHasElement determines whether the given set contains the given value as an
|
||||
@ -163,8 +163,23 @@ func SetSymmetricDifference(sets ...cty.Value) (cty.Value, error) {
|
||||
func setOperationReturnType(args []cty.Value) (ret cty.Type, err error) {
|
||||
var etys []cty.Type
|
||||
for _, arg := range args {
|
||||
etys = append(etys, arg.Type().ElementType())
|
||||
ty := arg.Type().ElementType()
|
||||
|
||||
// Do not unify types for empty dynamic pseudo typed collections. These
|
||||
// will always convert to any other concrete type.
|
||||
if arg.IsKnown() && arg.LengthInt() == 0 && ty.Equals(cty.DynamicPseudoType) {
|
||||
continue
|
||||
}
|
||||
|
||||
etys = append(etys, ty)
|
||||
}
|
||||
|
||||
// If all element types were skipped (due to being empty dynamic collections),
|
||||
// the return type should also be a set of dynamic pseudo type.
|
||||
if len(etys) == 0 {
|
||||
return cty.Set(cty.DynamicPseudoType), nil
|
||||
}
|
||||
|
||||
newEty, _ := convert.UnifyUnsafe(etys)
|
||||
if newEty == cty.NilType {
|
||||
return cty.NilType, fmt.Errorf("given sets must all have compatible element types")
|
||||
@ -172,13 +187,21 @@ func setOperationReturnType(args []cty.Value) (ret cty.Type, err error) {
|
||||
return cty.Set(newEty), nil
|
||||
}
|
||||
|
||||
func setOperationImpl(f func(s1, s2 cty.ValueSet) cty.ValueSet) function.ImplFunc {
|
||||
func setOperationImpl(f func(s1, s2 cty.ValueSet) cty.ValueSet, allowUnknowns bool) function.ImplFunc {
|
||||
return func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
first := args[0]
|
||||
first, err = convert.Convert(first, retType)
|
||||
if err != nil {
|
||||
return cty.NilVal, function.NewArgError(0, err)
|
||||
}
|
||||
if !allowUnknowns && !first.IsWhollyKnown() {
|
||||
// This set function can produce a correct result only when all
|
||||
// elements are known, because eventually knowing the unknown
|
||||
// values may cause the result to have fewer known elements, or
|
||||
// might cause a result with no unknown elements at all to become
|
||||
// one with a different length.
|
||||
return cty.UnknownVal(retType), nil
|
||||
}
|
||||
|
||||
set := first.AsValueSet()
|
||||
for i, arg := range args[1:] {
|
||||
@ -186,6 +209,10 @@ func setOperationImpl(f func(s1, s2 cty.ValueSet) cty.ValueSet) function.ImplFun
|
||||
if err != nil {
|
||||
return cty.NilVal, function.NewArgError(i+1, err)
|
||||
}
|
||||
if !allowUnknowns && !arg.IsWhollyKnown() {
|
||||
// (For the same reason as we did this check for "first" above.)
|
||||
return cty.UnknownVal(retType), nil
|
||||
}
|
||||
|
||||
argSet := arg.AsValueSet()
|
||||
set = f(set, argSet)
|
||||
|
Reference in New Issue
Block a user