Bump our hcl fork to include fix for Provider defined functions in parentheses (#3402)

Signed-off-by: James Humphries <james@james-humphries.co.uk>
This commit is contained in:
James Humphries
2025-10-22 10:40:53 +01:00
committed by GitHub
parent 2a04940157
commit cea35d6206
4 changed files with 107 additions and 4 deletions

2
go.mod
View File

@@ -317,7 +317,7 @@ require (
sigs.k8s.io/yaml v1.6.0 // indirect
)
replace github.com/hashicorp/hcl/v2 v2.20.1 => github.com/opentofu/hcl/v2 v2.20.2-0.20250121132637-504036cd70e7
replace github.com/hashicorp/hcl/v2 v2.20.1 => github.com/opentofu/hcl/v2 v2.20.2-0.20251021132045-587d123c2828
tool (
github.com/hashicorp/copywrite

4
go.sum
View File

@@ -674,8 +674,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opentofu/hcl/v2 v2.20.2-0.20250121132637-504036cd70e7 h1:QHUIrylb/q3pQdQcnAr74cGWsXS1lmA8GqP+RWFMK6U=
github.com/opentofu/hcl/v2 v2.20.2-0.20250121132637-504036cd70e7/go.mod h1:k+HgkLpoWu9OS81sy4j1XKDXaWm/rLysG33v5ibdDnc=
github.com/opentofu/hcl/v2 v2.20.2-0.20251021132045-587d123c2828 h1:r2WiJxljn/Cxwpq9zMZ5HomJcNwmGNjKmeZnFsxkpBg=
github.com/opentofu/hcl/v2 v2.20.2-0.20251021132045-587d123c2828/go.mod h1:k+HgkLpoWu9OS81sy4j1XKDXaWm/rLysG33v5ibdDnc=
github.com/opentofu/registry-address/v2 v2.0.0-20250611143131-d0a99bd8acdd h1:YAAnzmyOoMvm5SuGXL4hhlfBgqz92XDfORGPV3kmQFc=
github.com/opentofu/registry-address/v2 v2.0.0-20250611143131-d0a99bd8acdd/go.mod h1:7M92SvuJm1WBriIpa4j0XmruU9pxkgPXmRdc6FfAvAk=
github.com/opentofu/svchost v0.0.0-20250610175836-86c9e5e3d8c8 h1:J3pmsVB+nGdfNp5HWdEAC96asYgc7S6J724ICrYDCTk=

View File

@@ -25,7 +25,8 @@ var impureFunctions = []string{
"uuid",
}
// This should probably be replaced with addrs.Function everywhere
// CoreNamespace defines the string prefix used for all core namespaced functions
// TODO: This should probably be replaced with addrs.Function everywhere
const CoreNamespace = addrs.FunctionNamespaceCore + "::"
// Functions returns the set of functions that should be used to when evaluating

View File

@@ -0,0 +1,102 @@
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package lang
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/opentofu/opentofu/internal/addrs"
)
func TestReferencesInExpr(t *testing.T) {
// Note for developers, this list is non-exhaustive right now
// and there are many more expression types. This test is mainly to ensure that provider
// defined function references are returned from references with parentheses
// to resolve issue opentofu/opentofu#3401
tests := map[string]struct {
exprSrc string
wantFuncRefs []string // List of expected provider function references
}{
"no functions": {
exprSrc: `"literal"`,
wantFuncRefs: nil,
},
"provider function without parentheses": {
exprSrc: `provider::testing::echo("hello")`,
wantFuncRefs: []string{"provider::testing::echo"},
},
"provider function with parentheses": {
exprSrc: `(provider::testing::echo("hello"))`,
wantFuncRefs: []string{"provider::testing::echo"},
},
"provider function in binary expression": {
exprSrc: `(provider::testing::add(1, 2)) + 3`,
wantFuncRefs: []string{"provider::testing::add"},
},
"nested parentheses": {
exprSrc: `((provider::testing::echo("hello")))`,
wantFuncRefs: []string{"provider::testing::echo"},
},
"provider function in conditional true": {
exprSrc: `true ? provider::testing::echo("yes") : "no"`,
wantFuncRefs: []string{"provider::testing::echo"},
},
"provider function in conditional false": {
exprSrc: `false ? "yes" : provider::testing::echo("no")`,
wantFuncRefs: []string{"provider::testing::echo"},
},
"provider function in conditional condition": {
exprSrc: `provider::testing::is_true() ? "yes" : "no"`,
wantFuncRefs: []string{"provider::testing::is_true"},
},
"multiple provider functions": {
exprSrc: `(provider::testing::add(1, 2)) + (provider::testing::mul(3, 4))`,
wantFuncRefs: []string{"provider::testing::add", "provider::testing::mul"},
},
"provider function with alias": {
exprSrc: `(provider::testing::custom::echo("hello"))`,
wantFuncRefs: []string{"provider::testing::custom::echo"},
},
"core function not included": {
exprSrc: `(core::max(1, 2))`,
wantFuncRefs: nil, // core functions are not provider functions
},
"builtin function not included": {
exprSrc: `(length([1, 2, 3]))`,
wantFuncRefs: nil, // builtin functions are not provider functions
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
expr, diags := hclsyntax.ParseExpression([]byte(test.exprSrc), "test.tf", hcl.Pos{Line: 1, Column: 1})
if diags.HasErrors() {
t.Fatalf("Failed to parse expression: %s", diags.Error())
}
refs, refDiags := ReferencesInExpr(addrs.ParseRef, expr)
if refDiags.HasErrors() {
t.Errorf("Unexpected diagnostics: %s", refDiags.Err())
}
// Extract provider function references
var gotFuncRefs []string
for _, ref := range refs {
if provFunc, ok := ref.Subject.(addrs.ProviderFunction); ok {
gotFuncRefs = append(gotFuncRefs, provFunc.String())
}
}
if diff := cmp.Diff(test.wantFuncRefs, gotFuncRefs); diff != "" {
t.Errorf("Wrong provider function references (-want +got):\n%s", diff)
}
})
}
}