mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
lang/funcs: Non-null refinements for various functions
cty's new "refinements" concept allows us to reduce the range of unknown values from our functions. This initial changeset focuses only on declaring which functions are guaranteed to return a non-null result, which is a helpful baseline refinement because it allows "== null" and "!= null" tests to produce known results even when the given value is otherwise unknown. This commit also includes some updates to test results that are now refined based on cty's own built-in refinement behaviors, just as a result of us having updated cty in the previous commit.
This commit is contained in:
parent
1ef550e59a
commit
c912970153
@ -27,7 +27,8 @@ var CidrHostFunc = function.New(&function.Spec{
|
||||
Type: cty.Number,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
var hostNum *big.Int
|
||||
if err := gocty.FromCtyValue(args[1], &hostNum); err != nil {
|
||||
@ -56,7 +57,8 @@ var CidrNetmaskFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
_, network, err := ipaddr.ParseCIDR(args[0].AsString())
|
||||
if err != nil {
|
||||
@ -88,7 +90,8 @@ var CidrSubnetFunc = function.New(&function.Spec{
|
||||
Type: cty.Number,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
var newbits int
|
||||
if err := gocty.FromCtyValue(args[1], &newbits); err != nil {
|
||||
@ -126,7 +129,8 @@ var CidrSubnetsFunc = function.New(&function.Spec{
|
||||
Name: "newbits",
|
||||
Type: cty.Number,
|
||||
},
|
||||
Type: function.StaticReturnType(cty.List(cty.String)),
|
||||
Type: function.StaticReturnType(cty.List(cty.String)),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
_, network, err := ipaddr.ParseCIDR(args[0].AsString())
|
||||
if err != nil {
|
||||
|
@ -35,6 +35,7 @@ var LengthFunc = function.New(&function.Spec{
|
||||
return cty.Number, errors.New("argument must be a string, a collection type, or a structural type")
|
||||
}
|
||||
},
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
coll := args[0]
|
||||
collTy := args[0].Type()
|
||||
@ -71,7 +72,8 @@ var AllTrueFunc = function.New(&function.Spec{
|
||||
Type: cty.List(cty.Bool),
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
result := cty.True
|
||||
for it := args[0].ElementIterator(); it.Next(); {
|
||||
@ -100,7 +102,8 @@ var AnyTrueFunc = function.New(&function.Spec{
|
||||
Type: cty.List(cty.Bool),
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
result := cty.False
|
||||
var hasUnknown bool
|
||||
@ -149,6 +152,7 @@ var CoalesceFunc = function.New(&function.Spec{
|
||||
}
|
||||
return retType, nil
|
||||
},
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
for _, argVal := range args {
|
||||
// We already know this will succeed because of the checks in our Type func above
|
||||
@ -181,7 +185,8 @@ var IndexFunc = function.New(&function.Spec{
|
||||
Type: cty.DynamicPseudoType,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
if !(args[0].Type().IsListType() || args[0].Type().IsTupleType()) {
|
||||
return cty.NilVal, errors.New("argument must be a list or tuple")
|
||||
@ -346,6 +351,7 @@ var MatchkeysFunc = function.New(&function.Spec{
|
||||
// the return type is based on args[0] (values)
|
||||
return args[0].Type(), nil
|
||||
},
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
if !args[0].IsKnown() {
|
||||
return cty.UnknownVal(cty.List(retType.ElementType())), nil
|
||||
@ -489,7 +495,8 @@ var SumFunc = function.New(&function.Spec{
|
||||
Type: cty.DynamicPseudoType,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
|
||||
if !args[0].CanIterateElements() {
|
||||
@ -558,7 +565,8 @@ var TransposeFunc = function.New(&function.Spec{
|
||||
Type: cty.Map(cty.List(cty.String)),
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Map(cty.List(cty.String))),
|
||||
Type: function.StaticReturnType(cty.Map(cty.List(cty.String))),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
inputMap := args[0]
|
||||
if !inputMap.IsWhollyKnown() {
|
||||
|
@ -71,11 +71,15 @@ func TestLength(t *testing.T) {
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.List(cty.Bool)),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).Refine().
|
||||
NotNull().
|
||||
NumberRangeLowerBound(cty.Zero, true).
|
||||
NumberRangeUpperBound(cty.NumberIntVal(math.MaxInt), true).
|
||||
NewValue(),
|
||||
},
|
||||
{
|
||||
cty.DynamicVal,
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
},
|
||||
{
|
||||
cty.StringVal("hello"),
|
||||
@ -120,11 +124,10 @@ func TestLength(t *testing.T) {
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.Number),
|
||||
},
|
||||
{
|
||||
cty.DynamicVal,
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).Refine().
|
||||
NotNull().
|
||||
NumberRangeLowerBound(cty.Zero, true).
|
||||
NewValue(),
|
||||
},
|
||||
{ // Marked collections return a marked length
|
||||
cty.ListVal([]cty.Value{
|
||||
@ -229,7 +232,7 @@ func TestAllTrue(t *testing.T) {
|
||||
},
|
||||
{
|
||||
cty.ListVal([]cty.Value{cty.UnknownVal(cty.Bool)}),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
@ -237,12 +240,12 @@ func TestAllTrue(t *testing.T) {
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
}),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.List(cty.Bool)),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
@ -310,7 +313,7 @@ func TestAnyTrue(t *testing.T) {
|
||||
},
|
||||
{
|
||||
cty.ListVal([]cty.Value{cty.UnknownVal(cty.Bool)}),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
@ -318,7 +321,7 @@ func TestAnyTrue(t *testing.T) {
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.False,
|
||||
}),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
@ -331,7 +334,7 @@ func TestAnyTrue(t *testing.T) {
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.List(cty.Bool)),
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
@ -409,17 +412,17 @@ func TestCoalesce(t *testing.T) {
|
||||
},
|
||||
{
|
||||
[]cty.Value{cty.UnknownVal(cty.Bool), cty.True},
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]cty.Value{cty.UnknownVal(cty.Bool), cty.StringVal("hello")},
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]cty.Value{cty.DynamicVal, cty.True},
|
||||
cty.UnknownVal(cty.Bool),
|
||||
cty.UnknownVal(cty.Bool).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{
|
||||
@ -1065,7 +1068,7 @@ func TestMatchkeys(t *testing.T) {
|
||||
cty.ListVal([]cty.Value{
|
||||
cty.StringVal("ref1"),
|
||||
}),
|
||||
cty.UnknownVal(cty.List(cty.String)),
|
||||
cty.UnknownVal(cty.List(cty.String)).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{ // different types that can be unified
|
||||
@ -1529,7 +1532,7 @@ func TestSum(t *testing.T) {
|
||||
cty.StringVal("b"),
|
||||
cty.StringVal("c"),
|
||||
}),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
"argument must be list, set, or tuple of number values",
|
||||
},
|
||||
{
|
||||
@ -1583,7 +1586,7 @@ func TestSum(t *testing.T) {
|
||||
cty.StringVal("a"),
|
||||
cty.NumberIntVal(38),
|
||||
}),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
"argument must be list, set, or tuple of number values",
|
||||
},
|
||||
{
|
||||
@ -1603,17 +1606,17 @@ func TestSum(t *testing.T) {
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
"",
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.List(cty.Number)),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
"",
|
||||
},
|
||||
{ // known list containing unknown values
|
||||
cty.ListVal([]cty.Value{cty.UnknownVal(cty.Number)}),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
"",
|
||||
},
|
||||
{ // numbers too large to represent as float64
|
||||
@ -1707,7 +1710,7 @@ func TestTranspose(t *testing.T) {
|
||||
cty.MapVal(map[string]cty.Value{
|
||||
"key1": cty.UnknownVal(cty.List(cty.String)),
|
||||
}),
|
||||
cty.UnknownVal(cty.Map(cty.List(cty.String))),
|
||||
cty.UnknownVal(cty.Map(cty.List(cty.String))).RefineNotNull(),
|
||||
false,
|
||||
},
|
||||
{ // bad map - empty value
|
||||
|
@ -27,8 +27,9 @@ import (
|
||||
)
|
||||
|
||||
var UUIDFunc = function.New(&function.Spec{
|
||||
Params: []function.Parameter{},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Params: []function.Parameter{},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
result, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
@ -49,7 +50,8 @@ var UUIDV5Func = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
var namespace uuidv5.UUID
|
||||
switch {
|
||||
@ -103,7 +105,8 @@ var BcryptFunc = function.New(&function.Spec{
|
||||
Name: "cost",
|
||||
Type: cty.Number,
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
defaultCost := 10
|
||||
|
||||
@ -150,7 +153,8 @@ var RsaDecryptFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
s := args[0].AsString()
|
||||
key := args[1].AsString()
|
||||
@ -225,7 +229,8 @@ func makeStringHashFunction(hf func() hash.Hash, enc func([]byte) string) functi
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
s := args[0].AsString()
|
||||
h := hf()
|
||||
@ -244,7 +249,8 @@ func makeFileHashFunction(baseDir string, hf func() hash.Hash, enc func([]byte)
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
path := args[0].AsString()
|
||||
f, err := openFile(baseDir, path)
|
||||
|
@ -13,8 +13,9 @@ import (
|
||||
|
||||
// TimestampFunc constructs a function that returns a string representation of the current date and time.
|
||||
var TimestampFunc = function.New(&function.Spec{
|
||||
Params: []function.Parameter{},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Params: []function.Parameter{},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(time.Now().UTC().Format(time.RFC3339)), nil
|
||||
},
|
||||
@ -44,7 +45,8 @@ var TimeAddFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
ts, err := parseTimestamp(args[0].AsString())
|
||||
if err != nil {
|
||||
@ -71,7 +73,8 @@ var TimeCmpFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
tsA, err := parseTimestamp(args[0].AsString())
|
||||
if err != nil {
|
||||
|
@ -56,13 +56,13 @@ func TestTimeadd(t *testing.T) {
|
||||
{ // Invalid format timestamp
|
||||
cty.StringVal("2017-11-22"),
|
||||
cty.StringVal("-1h"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
true,
|
||||
},
|
||||
{ // Invalid format duration (day is not supported by ParseDuration)
|
||||
cty.StringVal("2017-11-22T00:00:00Z"),
|
||||
cty.StringVal("1d"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
true,
|
||||
},
|
||||
}
|
||||
@ -132,31 +132,31 @@ func TestTimeCmp(t *testing.T) {
|
||||
{
|
||||
cty.StringVal("2017-11-22T00:00:00Z"),
|
||||
cty.StringVal("bloop"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
`not a valid RFC3339 timestamp: cannot use "bloop" as year`,
|
||||
},
|
||||
{
|
||||
cty.StringVal("2017-11-22 00:00:00Z"),
|
||||
cty.StringVal("2017-11-22T00:00:00Z"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
`not a valid RFC3339 timestamp: missing required time introducer 'T'`,
|
||||
},
|
||||
{
|
||||
cty.StringVal("2017-11-22T00:00:00Z"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.StringVal("2017-11-22T00:00:00Z"),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.UnknownVal(cty.Number).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ var Base64DecodeFunc = function.New(&function.Spec{
|
||||
AllowMarked: true,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
str, strMarks := args[0].Unmark()
|
||||
s := str.AsString()
|
||||
@ -50,7 +51,8 @@ var Base64EncodeFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(base64.StdEncoding.EncodeToString([]byte(args[0].AsString()))), nil
|
||||
},
|
||||
@ -68,7 +70,8 @@ var TextEncodeBase64Func = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
encoding, err := ianaindex.IANA.Encoding(args[1].AsString())
|
||||
if err != nil || encoding == nil {
|
||||
@ -111,7 +114,8 @@ var TextDecodeBase64Func = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
encoding, err := ianaindex.IANA.Encoding(args[1].AsString())
|
||||
if err != nil || encoding == nil {
|
||||
@ -154,7 +158,8 @@ var Base64GzipFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
s := args[0].AsString()
|
||||
|
||||
@ -181,7 +186,8 @@ var URLEncodeFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(url.QueryEscape(args[0].AsString())), nil
|
||||
},
|
||||
|
@ -235,25 +235,25 @@ func TestBase64TextEncode(t *testing.T) {
|
||||
{
|
||||
cty.StringVal("abc123!?$*&()'-=@~"),
|
||||
cty.StringVal("NOT-EXISTS"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
`"NOT-EXISTS" is not a supported IANA encoding name or alias in this Terraform version`,
|
||||
},
|
||||
{
|
||||
cty.StringVal("🤔"),
|
||||
cty.StringVal("cp437"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
`the given string contains characters that cannot be represented in IBM437`,
|
||||
},
|
||||
{
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.StringVal("windows-1250"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
{
|
||||
cty.StringVal("hello world"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
}
|
||||
@ -309,13 +309,13 @@ func TestBase64TextDecode(t *testing.T) {
|
||||
{
|
||||
cty.StringVal("doesn't matter"),
|
||||
cty.StringVal("NOT-EXISTS"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
`"NOT-EXISTS" is not a supported IANA encoding name or alias in this Terraform version`,
|
||||
},
|
||||
{
|
||||
cty.StringVal("<invalid base64>"),
|
||||
cty.StringVal("cp437"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
`the given value is has an invalid base64 symbol at offset 0`,
|
||||
},
|
||||
{
|
||||
@ -327,13 +327,13 @@ func TestBase64TextDecode(t *testing.T) {
|
||||
{
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.StringVal("windows-1250"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
{
|
||||
cty.StringVal("YQBiAGMAMQAyADMAIQA/ACQAKgAmACgAKQAnAC0APQBAAH4A"),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String),
|
||||
cty.UnknownVal(cty.String).RefineNotNull(),
|
||||
``,
|
||||
},
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ func MakeFileFunc(baseDir string, encBase64 bool) function.Function {
|
||||
AllowMarked: true,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
pathArg, pathMarks := args[0].Unmark()
|
||||
path := pathArg.AsString()
|
||||
@ -201,7 +202,8 @@ func MakeFileExistsFunc(baseDir string) function.Function {
|
||||
AllowMarked: true,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
pathArg, pathMarks := args[0].Unmark()
|
||||
path := pathArg.AsString()
|
||||
@ -273,7 +275,8 @@ func MakeFileSetFunc(baseDir string) function.Function {
|
||||
AllowMarked: true,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Set(cty.String)),
|
||||
Type: function.StaticReturnType(cty.Set(cty.String)),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
pathArg, pathMarks := args[0].Unmark()
|
||||
path := pathArg.AsString()
|
||||
@ -340,7 +343,8 @@ var BasenameFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(filepath.Base(args[0].AsString())), nil
|
||||
},
|
||||
@ -355,7 +359,8 @@ var DirnameFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(filepath.Dir(args[0].AsString())), nil
|
||||
},
|
||||
@ -369,7 +374,8 @@ var AbsPathFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
absPath, err := filepath.Abs(args[0].AsString())
|
||||
return cty.StringVal(filepath.ToSlash(absPath)), err
|
||||
@ -384,7 +390,8 @@ var PathExpandFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
|
||||
homePath, err := homedir.Expand(args[0].AsString())
|
||||
|
@ -24,7 +24,8 @@ var LogFunc = function.New(&function.Spec{
|
||||
Type: cty.Number,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
var num float64
|
||||
if err := gocty.FromCtyValue(args[0], &num); err != nil {
|
||||
@ -52,7 +53,8 @@ var PowFunc = function.New(&function.Spec{
|
||||
Type: cty.Number,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
var num float64
|
||||
if err := gocty.FromCtyValue(args[0], &num); err != nil {
|
||||
@ -77,7 +79,8 @@ var SignumFunc = function.New(&function.Spec{
|
||||
Type: cty.Number,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
Type: function.StaticReturnType(cty.Number),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
var num int
|
||||
if err := gocty.FromCtyValue(args[0], &num); err != nil {
|
||||
@ -115,6 +118,7 @@ var ParseIntFunc = function.New(&function.Spec{
|
||||
}
|
||||
return cty.Number, nil
|
||||
},
|
||||
RefineResult: refineNotNull,
|
||||
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
var numstr string
|
||||
|
9
internal/lang/funcs/refinements.go
Normal file
9
internal/lang/funcs/refinements.go
Normal file
@ -0,0 +1,9 @@
|
||||
package funcs
|
||||
|
||||
import (
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func refineNotNull(b *cty.RefinementBuilder) *cty.RefinementBuilder {
|
||||
return b.NotNull()
|
||||
}
|
@ -24,7 +24,8 @@ var StartsWithFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
str := args[0].AsString()
|
||||
prefix := args[1].AsString()
|
||||
@ -50,7 +51,8 @@ var EndsWithFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
Type: function.StaticReturnType(cty.Bool),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
str := args[0].AsString()
|
||||
suffix := args[1].AsString()
|
||||
@ -80,7 +82,8 @@ var ReplaceFunc = function.New(&function.Spec{
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||
str := args[0].AsString()
|
||||
substr := args[1].AsString()
|
||||
|
Loading…
Reference in New Issue
Block a user