mirror of https://github.com/databricks/cli.git
Allow multiple lookup functions for interpolation (#128)
This commit is contained in:
parent
3f8e233a18
commit
94a86972e5
|
@ -2,6 +2,7 @@ package interpolation
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
@ -39,16 +40,23 @@ func (s *stringField) dependsOn() []string {
|
|||
return out
|
||||
}
|
||||
|
||||
func (s *stringField) interpolate(fn LookupFunction, lookup map[string]string) {
|
||||
func (s *stringField) interpolate(fns []LookupFunction, lookup map[string]string) {
|
||||
out := re.ReplaceAllStringFunc(s.Get(), func(s string) string {
|
||||
// Turn the whole match into the submatch.
|
||||
match := re.FindStringSubmatch(s)
|
||||
for _, fn := range fns {
|
||||
v, err := fn(match[1], lookup)
|
||||
if errors.Is(err, ErrSkipInterpolation) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// No substitution.
|
||||
return s
|
||||
})
|
||||
|
||||
s.Set(out)
|
||||
|
@ -163,7 +171,7 @@ func (a *accumulator) start(v any) {
|
|||
a.walk([]string{}, rv, nilSetter{})
|
||||
}
|
||||
|
||||
func (a *accumulator) expand(fn LookupFunction) error {
|
||||
func (a *accumulator) expand(fns ...LookupFunction) error {
|
||||
for path, v := range a.strings {
|
||||
ds := v.dependsOn()
|
||||
if len(ds) == 0 {
|
||||
|
@ -176,24 +184,24 @@ func (a *accumulator) expand(fn LookupFunction) error {
|
|||
return fmt.Errorf("cannot interpolate %s: %w", path, err)
|
||||
}
|
||||
|
||||
v.interpolate(fn, m)
|
||||
v.interpolate(fns, m)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type interpolate struct {
|
||||
fn LookupFunction
|
||||
fns []LookupFunction
|
||||
}
|
||||
|
||||
func (m *interpolate) expand(v any) error {
|
||||
a := accumulator{}
|
||||
a.start(v)
|
||||
return a.expand(m.fn)
|
||||
return a.expand(m.fns...)
|
||||
}
|
||||
|
||||
func Interpolate(fn LookupFunction) bundle.Mutator {
|
||||
return &interpolate{fn: fn}
|
||||
func Interpolate(fns ...LookupFunction) bundle.Mutator {
|
||||
return &interpolate{fns: fns}
|
||||
}
|
||||
|
||||
func (m *interpolate) Name() string {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package interpolation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -10,6 +11,9 @@ import (
|
|||
// LookupFunction returns the value to rewrite a path expression to.
|
||||
type LookupFunction func(path string, depends map[string]string) (string, error)
|
||||
|
||||
// ErrSkipInterpolation can be used to fall through from [LookupFunction].
|
||||
var ErrSkipInterpolation = errors.New("skip interpolation")
|
||||
|
||||
// DefaultLookup looks up the specified path in the map.
|
||||
// It returns an error if it doesn't exist.
|
||||
func DefaultLookup(path string, lookup map[string]string) (string, error) {
|
||||
|
@ -29,7 +33,7 @@ func pathPrefixMatches(prefix []string, path string) bool {
|
|||
func ExcludeLookupsInPath(exclude ...string) LookupFunction {
|
||||
return func(path string, lookup map[string]string) (string, error) {
|
||||
if pathPrefixMatches(exclude, path) {
|
||||
return fmt.Sprintf("${%s}", path), nil
|
||||
return "", ErrSkipInterpolation
|
||||
}
|
||||
|
||||
return DefaultLookup(path, lookup)
|
||||
|
@ -39,10 +43,10 @@ func ExcludeLookupsInPath(exclude ...string) LookupFunction {
|
|||
// 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)
|
||||
if !pathPrefixMatches(include, path) {
|
||||
return "", ErrSkipInterpolation
|
||||
}
|
||||
|
||||
return fmt.Sprintf("${%s}", path), nil
|
||||
return DefaultLookup(path, lookup)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,9 @@ func fixture() interpolationFixture {
|
|||
func TestExcludePath(t *testing.T) {
|
||||
tmp := fixture()
|
||||
m := interpolate{
|
||||
fn: ExcludeLookupsInPath("a"),
|
||||
fns: []LookupFunction{
|
||||
ExcludeLookupsInPath("a"),
|
||||
},
|
||||
}
|
||||
|
||||
err := m.expand(&tmp)
|
||||
|
@ -46,7 +48,9 @@ func TestExcludePath(t *testing.T) {
|
|||
func TestIncludePath(t *testing.T) {
|
||||
tmp := fixture()
|
||||
m := interpolate{
|
||||
fn: IncludeLookupsInPath("a"),
|
||||
fns: []LookupFunction{
|
||||
IncludeLookupsInPath("a"),
|
||||
},
|
||||
}
|
||||
|
||||
err := m.expand(&tmp)
|
||||
|
@ -57,3 +61,21 @@ func TestIncludePath(t *testing.T) {
|
|||
assert.Equal(t, "1", tmp.C["ax"])
|
||||
assert.Equal(t, "${b.x}", tmp.C["bx"])
|
||||
}
|
||||
|
||||
func TestIncludePathMultiple(t *testing.T) {
|
||||
tmp := fixture()
|
||||
m := interpolate{
|
||||
fns: []LookupFunction{
|
||||
IncludeLookupsInPath("a"),
|
||||
IncludeLookupsInPath("b"),
|
||||
},
|
||||
}
|
||||
|
||||
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, "2", tmp.C["bx"])
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue