From aba5d61ad634d7bc37b9cbebd273dd8e2461a2b8 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Wed, 27 Mar 2024 18:01:57 +0100 Subject: [PATCH 1/3] Add terraformVersion to functions merger --- schema/functions_merge.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/schema/functions_merge.go b/schema/functions_merge.go index c68dc634..83d18f52 100644 --- a/schema/functions_merge.go +++ b/schema/functions_merge.go @@ -6,13 +6,15 @@ package schema import ( "fmt" + "github.com/hashicorp/go-version" "github.com/hashicorp/hcl-lang/schema" tfmod "github.com/hashicorp/terraform-schema/module" ) type FunctionsMerger struct { - coreFunctions map[string]schema.FunctionSignature - schemaReader SchemaReader + coreFunctions map[string]schema.FunctionSignature + terraformVersion *version.Version + schemaReader SchemaReader } func NewFunctionsMerger(coreFunctions map[string]schema.FunctionSignature) *FunctionsMerger { @@ -25,6 +27,10 @@ func (m *FunctionsMerger) SetSchemaReader(sr SchemaReader) { m.schemaReader = sr } +func (m *FunctionsMerger) SetTerraformVersion(v *version.Version) { + m.terraformVersion = v +} + func (m *FunctionsMerger) FunctionsForModule(meta *tfmod.Meta) (map[string]schema.FunctionSignature, error) { if m.coreFunctions == nil { return nil, coreFunctionsRequiredErr{} From 0ac1d45747094e8e39558e0889b147a1d3de0f90 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Wed, 27 Mar 2024 18:02:17 +0100 Subject: [PATCH 2/3] Only include provider-defined functions for Terraform >= 1.8 --- schema/core_schema.go | 1 + schema/functions_merge.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/schema/core_schema.go b/schema/core_schema.go index fc2afd48..cbade25c 100644 --- a/schema/core_schema.go +++ b/schema/core_schema.go @@ -30,6 +30,7 @@ var ( v1_5 = version.Must(version.NewVersion("1.5")) v1_6 = version.Must(version.NewVersion("1.6")) v1_7 = version.Must(version.NewVersion("1.7")) + v1_8 = version.Must(version.NewVersion("1.8")) ) // CoreModuleSchemaForVersion finds a module schema which is relevant diff --git a/schema/functions_merge.go b/schema/functions_merge.go index 83d18f52..e0a961e5 100644 --- a/schema/functions_merge.go +++ b/schema/functions_merge.go @@ -40,6 +40,10 @@ func (m *FunctionsMerger) FunctionsForModule(meta *tfmod.Meta) (map[string]schem return m.coreFunctions, nil } + if m.terraformVersion.LessThan(v1_8) { + return m.coreFunctions, nil + } + mergedFunctions := make(map[string]schema.FunctionSignature, len(m.coreFunctions)) for fName, fSig := range m.coreFunctions { mergedFunctions[fName] = *fSig.Copy() From ec799b9b2e3eeddf2e3258f8bfe29d84df6cfc18 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Wed, 27 Mar 2024 18:02:38 +0100 Subject: [PATCH 3/3] Add functions merger test case --- schema/functions_merge_test.go | 93 ++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/schema/functions_merge_test.go b/schema/functions_merge_test.go index 411637ef..d279366a 100644 --- a/schema/functions_merge_test.go +++ b/schema/functions_merge_test.go @@ -57,7 +57,32 @@ func TestFunctionsMerger_FunctionsForModule_noMeta(t *testing.T) { } } -func TestFunctionsMerger_FunctionsForModule(t *testing.T) { +var providerSchemaWithFunctions = map[string]*tfjson.ProviderSchema{ + "registry.terraform.io/hashicorp/test": { + ConfigSchema: &tfjson.Schema{}, + DataSourceSchemas: map[string]*tfjson.Schema{}, + ResourceSchemas: map[string]*tfjson.Schema{}, + Functions: map[string]*tfjson.FunctionSignature{ + "bar": { + Parameters: []*tfjson.FunctionParameter{ + {Name: "baz", Type: cty.String, Description: "baz param"}, + }, + Description: "bar function", + ReturnType: cty.String, + }, + "alleven": { + VariadicParameter: &tfjson.FunctionParameter{ + Name: "numbers", + Type: cty.List(cty.Number), + }, + Description: "Returns true if all passed arguments are even numbers", + ReturnType: cty.Bool, + }, + }, + }, +} + +func TestFunctionsMerger_FunctionsForModule_18(t *testing.T) { coreFunctions := map[string]schema.FunctionSignature{ "foo": { Params: []function.Parameter{ @@ -71,40 +96,13 @@ func TestFunctionsMerger_FunctionsForModule(t *testing.T) { fm.SetSchemaReader(&testJsonSchemaReader{ ps: &tfjson.ProviderSchemas{ FormatVersion: "1.0", - Schemas: map[string]*tfjson.ProviderSchema{ - "registry.terraform.io/hashicorp/test": { - ConfigSchema: &tfjson.Schema{}, - DataSourceSchemas: map[string]*tfjson.Schema{}, - ResourceSchemas: map[string]*tfjson.Schema{}, - Functions: map[string]*tfjson.FunctionSignature{ - "bar": { - Parameters: []*tfjson.FunctionParameter{ - {Name: "baz", Type: cty.String, Description: "baz param"}, - }, - Description: "bar function", - ReturnType: cty.String, - }, - "alleven": { - VariadicParameter: &tfjson.FunctionParameter{ - Name: "numbers", - Type: cty.List(cty.Number), - }, - Description: "Returns true if all passed arguments are even numbers", - ReturnType: cty.Bool, - }, - }, - }, - }, + Schemas: providerSchemaWithFunctions, }, }) + fm.SetTerraformVersion(version.Must(version.NewVersion("1.8"))) testProvider := addr.NewDefaultProvider("test") - versionConstraints, err := version.NewConstraint("1.0.0") - - if err != nil { - t.Fatalf("unexpected error: %#v", err) - } - + versionConstraints := version.MustConstraints(version.NewConstraint("1.0.0")) meta := &tfmod.Meta{ ProviderReferences: map[tfmod.ProviderRef]tfaddr.Provider{ {LocalName: "localtest"}: testProvider, @@ -149,3 +147,36 @@ func TestFunctionsMerger_FunctionsForModule(t *testing.T) { t.Fatalf("functions mismatch: %s", diff) } } + +func TestFunctionsMerger_FunctionsForModule_17(t *testing.T) { + fm := NewFunctionsMerger(map[string]schema.FunctionSignature{}) + fm.SetSchemaReader(&testJsonSchemaReader{ + ps: &tfjson.ProviderSchemas{ + FormatVersion: "1.0", + Schemas: providerSchemaWithFunctions, + }, + }) + fm.SetTerraformVersion(version.Must(version.NewVersion("1.7"))) + + testProvider := addr.NewDefaultProvider("test") + versionConstraints := version.MustConstraints(version.NewConstraint("1.0.0")) + meta := &tfmod.Meta{ + ProviderReferences: map[tfmod.ProviderRef]tfaddr.Provider{ + {LocalName: "localtest"}: testProvider, + }, + ProviderRequirements: tfmod.ProviderRequirements{ + testProvider: versionConstraints, + }, + } + + expectedFunctions := map[string]schema.FunctionSignature{} + + givenFunctions, err := fm.FunctionsForModule(meta) + if err != nil { + t.Fatalf("unexpected error: %#v", err) + } + + if diff := cmp.Diff(expectedFunctions, givenFunctions, ctydebug.CmpOptions); diff != "" { + t.Fatalf("functions mismatch: %s", diff) + } +}