Repository: lyraproj/hiera
Pull request #84 (2020-10-10 23:25:36)

Ensure that interpolation lookups reset merge strategy
This commit fixes a problem with merge strategy being inherited from
the parent lookup when an interpolation lookup or alias was made.


Patch:
diff --git a/session/interpolate.go b/session/interpolate.go
index 162b972..3801612 100644
--- a/session/interpolate.go
+++ b/session/interpolate.go
@@ -4,11 +4,10 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/tada/catch"
-
 	"github.com/lyraproj/dgo/dgo"
 	"github.com/lyraproj/dgo/vf"
 	"github.com/lyraproj/hiera/api"
+	"github.com/tada/catch"
 )
 
 var iplPattern = regexp.MustCompile(`%{[^}]*}`)
@@ -138,7 +137,7 @@ func (ic *ivContext) InterpolateString(str string, allowMethods bool) (dgo.Value
 				}
 				return ``
 			default:
-				val := ic.Lookup(api.NewKey(expr), nil)
+				val := ic.ForSubLookup().Lookup(api.NewKey(expr), nil)
 				if methodKey.isAlias() {
 					result = val
 					return ``
diff --git a/session/invocation.go b/session/invocation.go
index 853dfa2..5c6f692 100644
--- a/session/invocation.go
+++ b/session/invocation.go
@@ -4,19 +4,15 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/tada/catch"
-
-	"github.com/lyraproj/hiera/merge"
-
-	"github.com/lyraproj/dgo/vf"
-
-	"github.com/lyraproj/dgo/typ"
-
 	"github.com/lyraproj/dgo/dgo"
+	"github.com/lyraproj/dgo/typ"
 	"github.com/lyraproj/dgo/util"
+	"github.com/lyraproj/dgo/vf"
 	"github.com/lyraproj/hiera/api"
 	"github.com/lyraproj/hiera/config"
+	"github.com/lyraproj/hiera/merge"
 	"github.com/lyraproj/hierasdk/hiera"
+	"github.com/tada/catch"
 )
 
 const hieraConfigsPrefix = `HieraConfig:`
@@ -400,6 +396,13 @@ func (ic *ivContext) ForData() api.Invocation {
 	return &lic
 }
 
+func (ic *ivContext) ForSubLookup() api.Invocation {
+	lic := *ic
+	lic.strategy = nil
+	lic.mode = topLevelMode
+	return &lic
+}
+
 func (ic *ivContext) LookupOptions() dgo.Map {
 	return ic.luOpts
 }


Test patch:
diff --git a/lookup/lookup_test.go b/lookup/lookup_test.go
index 6235e65..b8b993b 100644
--- a/lookup/lookup_test.go
+++ b/lookup/lookup_test.go
@@ -1,14 +1,22 @@
 package main_test
 
 import (
+	"context"
+	"io"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"sync"
 	"testing"
 
+	"github.com/lyraproj/dgo/dgo"
+	"github.com/lyraproj/dgo/vf"
+	"github.com/lyraproj/hiera/api"
 	"github.com/lyraproj/hiera/cli"
+	"github.com/lyraproj/hiera/hiera"
+	"github.com/lyraproj/hiera/provider"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -220,6 +228,27 @@ func TestLookup_aliasNothing(t *testing.T) {
 	})
 }
 
+func cmdLookup(cmdOpts *hiera.CommandOptions, opts dgo.Keyed, args []string, out io.Writer) error {
+	return hiera.TryWithParent(context.Background(), provider.ConfigLookupKey, opts, func(c api.Session) error {
+		hiera.LookupAndRender(c, cmdOpts, args, out)
+		return nil
+	})
+}
+
+// TestLookup_aliasNewInvocation tests that an alias uses a new invocation where the
+// lookup_options map is not inherited
+func TestLookup_aliasNewInvocation(t *testing.T) {
+	cmdOpts := &hiera.CommandOptions{}
+	cfgOpts := vf.MutableMap()
+	cfgOpts.Put(api.HieraConfig, "interpolate_fresh.yaml")
+	inTestdata(func() {
+		bs := &strings.Builder{}
+		err := cmdLookup(cmdOpts, cfgOpts, []string{"hash_with_alias"}, bs)
+		require.NoError(t, err)
+		require.Equal(t, "y: Y\neh: {}\nea: []\nx: X\n", bs.String())
+	})
+}
+
 func TestLookup_strictAliasNothing(t *testing.T) {
 	inTestdata(func() {
 		result, err := cli.ExecuteLookup(`strict_alias_nothing`)
diff --git a/lookup/testdata/interpolate_fresh.yaml b/lookup/testdata/interpolate_fresh.yaml
new file mode 100644
index 0000000..556199b
--- /dev/null
+++ b/lookup/testdata/interpolate_fresh.yaml
@@ -0,0 +1,11 @@
+version: 5
+
+defaults:
+  datadir: interpolate_fresh
+  data_hash: yaml_data
+
+hierarchy:
+  - name: Common
+    path: common.yaml
+  - name: Defaults
+    path: defaults.yaml
diff --git a/lookup/testdata/interpolate_fresh/common.yaml b/lookup/testdata/interpolate_fresh/common.yaml
new file mode 100644
index 0000000..036b48b
--- /dev/null
+++ b/lookup/testdata/interpolate_fresh/common.yaml
@@ -0,0 +1,12 @@
+empty_array: []
+
+empty_hash: {}
+
+hash_with_alias:
+  y: Y
+  eh: '%{alias("empty_hash")}'
+  ea: '%{alias("empty_array")}'
+
+lookup_options:
+  hash_with_alias:
+    merge: deep
diff --git a/lookup/testdata/interpolate_fresh/defaults.yaml b/lookup/testdata/interpolate_fresh/defaults.yaml
new file mode 100644
index 0000000..faa7c52
--- /dev/null
+++ b/lookup/testdata/interpolate_fresh/defaults.yaml
@@ -0,0 +1,12 @@
+empty_array:
+  - one
+  - two
+  - three
+
+empty_hash:
+  one: 1
+  two: 2
+  three: 3
+
+hash_with_alias:
+  x: X