Skip to content

Commit

Permalink
Merge pull request #44 from k1LoW/escape-delims
Browse files Browse the repository at this point in the history
Escape/unescape delimiters
  • Loading branch information
k1LoW authored Mar 8, 2024
2 parents 977a4c8 + a1b3a34 commit 98be53a
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 6 deletions.
66 changes: 66 additions & 0 deletions expand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,72 @@ func TestReplaceYAMLWithExprRepFn(t *testing.T) {
`v: "{{ hello }}"`,
`v: "{\"foo\":\"ba\\nr\"}"`,
},
{
map[string]any{
"hello": map[string]any{
"foo": "ba\nr",
},
},
false,
true,
`v: "\{\{ hello \}\}"`,
`v: "{{ hello }}"`,
},
{
map[string]any{
"hello": map[string]any{
"foo": "bar",
},
},
false,
true,
`v: '\{\{ hello \}\}'`,
`v: '{{ hello }}'`,
},
{
map[string]any{
"hello": map[string]any{
"foo": "bar",
},
},
false,
true,
`v: '\{\{ {{ hello }} \}\}'`,
`v: '{{ {"foo":"bar"} }}'`,
},
{
map[string]any{
"hello": map[string]any{
"foo": "bar",
},
},
false,
true,
`v: '\\{\{ hello \\}\}'`,
`v: '\{\{ hello \}\}'`,
},
{
map[string]any{
"hello": map[string]any{
"foo": "bar",
},
},
false,
true,
`v: '\\\{\{ hello \\\}\}'`,
`v: '\\{\{ hello \\}\}'`,
},
{
map[string]any{
"hello": map[string]any{
"foo": "bar",
},
},
false,
true,
`v: '\\{\\{ hello \\}\\}'`,
`v: '\\{\\{ hello \\}\\}'`,
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
Expand Down
34 changes: 28 additions & 6 deletions repfn.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ import (
"strconv"
"strings"

"github.com/expr-lang/expr"
"github.com/buildkite/interpolate"
"github.com/expr-lang/expr"
)

type repFn func(in string) (string, error)

var envPlaceholderRe = regexp.MustCompile(`\${.+}`)

func InterpolateRepFn(mapping func(string) (string, bool)) repFn {
const repToken = "__NOT_INTERPOLATE_START__"
const notRep = "__NOT_INTERPOLATE_START__"
mapper := Mapper{mapping: mapping}
return func(in string) (string, error) {
if !envPlaceholderRe.MatchString(in) {
return in, nil
}
r := strings.NewReplacer("${", "${", "$", repToken)
rr := strings.NewReplacer(repToken, "$")
r := strings.NewReplacer("${", "${", "$", notRep)
rr := strings.NewReplacer(notRep, "$")

replace, err := interpolate.Interpolate(mapper, r.Replace(in))
if err != nil {
Expand All @@ -37,7 +37,7 @@ func ExprRepFn(delimStart, delimEnd string, env any) repFn {
const strDQuote = `"`
return func(in string) (string, error) {
if !strings.Contains(in, delimStart) {
return in, nil
return unescapeDelims(delimStart, delimEnd, in), nil
}

if strings.Count(in, strDQuote) >= 2 {
Expand Down Expand Up @@ -94,7 +94,7 @@ func ExprRepFn(delimStart, delimEnd string, env any) repFn {
oldnew = append(oldnew, m[0], s)
}
rep := strings.NewReplacer(oldnew...)
return rep.Replace(in), nil
return unescapeDelims(delimStart, delimEnd, rep.Replace(in)), nil
}
}

Expand Down Expand Up @@ -135,3 +135,25 @@ func trySubstr(delimStart, delimEnd, in string) ([]string, int) {
id := strings.TrimSuffix(strings.TrimPrefix(wd, delimStart), delimEnd)
return []string{wd, id}, se + len(delimEnd)
}

func unescapeDelims(delimStart, delimEnd, in string) string {
const (
eeStartRep = "__E_E_DELIM_START__" //
eeEndRep = "__E_E_DELIM_END__"
)
var (
escapedDelimStart string
escapedDelimEnd string
)
for _, r := range delimStart {
escapedDelimStart += fmt.Sprintf("\\%s", string(r))
}
escapedescapedDelimStart := fmt.Sprintf("\\%s", escapedDelimStart)
for _, r := range delimEnd {
escapedDelimEnd += fmt.Sprintf("\\%s", string(r))
}
escapedescapedDelimEnd := fmt.Sprintf("\\%s", escapedDelimEnd)
rep := strings.NewReplacer(escapedescapedDelimStart, eeStartRep, escapedescapedDelimEnd, eeEndRep, escapedDelimStart, delimStart, escapedDelimEnd, delimEnd)
rep2 := strings.NewReplacer(eeStartRep, escapedDelimStart, eeEndRep, escapedDelimEnd)
return rep2.Replace(rep.Replace(in))
}

0 comments on commit 98be53a

Please sign in to comment.