Function to limit interpolation to specific path (#127)

New function `IncludeLookupsInPath` is counterpart to
`ExcludeLookupsInPath`.
This commit is contained in:
Pieter Noordhuis 2022-12-12 10:30:17 +01:00 committed by GitHub
parent cb16ad1184
commit 3f8e233a18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 10 deletions

View File

@ -20,16 +20,29 @@ func DefaultLookup(path string, lookup map[string]string) (string, error) {
return v, nil return v, nil
} }
func pathPrefixMatches(prefix []string, path string) bool {
parts := strings.Split(path, Delimiter)
return len(parts) >= len(prefix) && slices.Compare(prefix, parts[0:len(prefix)]) == 0
}
// ExcludeLookupsInPath is a lookup function that skips lookups for the specified path. // ExcludeLookupsInPath is a lookup function that skips lookups for the specified path.
func ExcludeLookupsInPath(exclude ...string) LookupFunction { func ExcludeLookupsInPath(exclude ...string) LookupFunction {
return func(path string, lookup map[string]string) (string, error) { return func(path string, lookup map[string]string) (string, error) {
parts := strings.Split(path, Delimiter) if pathPrefixMatches(exclude, path) {
// Skip interpolation of this path.
if len(parts) >= len(exclude) && slices.Compare(exclude, parts[0:len(exclude)]) == 0 {
return fmt.Sprintf("${%s}", path), nil return fmt.Sprintf("${%s}", path), nil
} }
return DefaultLookup(path, lookup) return DefaultLookup(path, lookup)
} }
} }
// IncludeLookupsInPath is a lookup function that limits lookups to the specified path.
func IncludeLookupsInPath(include ...string) LookupFunction {
return func(path string, lookup map[string]string) (string, error) {
if pathPrefixMatches(include, path) {
return DefaultLookup(path, lookup)
}
return fmt.Sprintf("${%s}", path), nil
}
}

View File

@ -7,12 +7,14 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestExcludePath(t *testing.T) { type interpolationFixture struct {
tmp := struct { A map[string]string `json:"a"`
A map[string]string `json:"a"` B map[string]string `json:"b"`
B map[string]string `json:"b"` C map[string]string `json:"c"`
C map[string]string `json:"c"` }
}{
func fixture() interpolationFixture {
return interpolationFixture{
A: map[string]string{ A: map[string]string{
"x": "1", "x": "1",
}, },
@ -24,7 +26,10 @@ func TestExcludePath(t *testing.T) {
"bx": "${b.x}", "bx": "${b.x}",
}, },
} }
}
func TestExcludePath(t *testing.T) {
tmp := fixture()
m := interpolate{ m := interpolate{
fn: ExcludeLookupsInPath("a"), fn: ExcludeLookupsInPath("a"),
} }
@ -37,3 +42,18 @@ func TestExcludePath(t *testing.T) {
assert.Equal(t, "${a.x}", tmp.C["ax"]) assert.Equal(t, "${a.x}", tmp.C["ax"])
assert.Equal(t, "2", tmp.C["bx"]) assert.Equal(t, "2", tmp.C["bx"])
} }
func TestIncludePath(t *testing.T) {
tmp := fixture()
m := interpolate{
fn: IncludeLookupsInPath("a"),
}
err := m.expand(&tmp)
require.NoError(t, err)
assert.Equal(t, "1", tmp.A["x"])
assert.Equal(t, "2", tmp.B["x"])
assert.Equal(t, "1", tmp.C["ax"])
assert.Equal(t, "${b.x}", tmp.C["bx"])
}