config: add replace function
This commit is contained in:
parent
8e76a02a56
commit
2f33a24385
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -15,11 +16,15 @@ var Funcs map[string]ast.Function
|
|||
|
||||
func init() {
|
||||
Funcs = map[string]ast.Function{
|
||||
"concat": interpolationFuncConcat(),
|
||||
"file": interpolationFuncFile(),
|
||||
"join": interpolationFuncJoin(),
|
||||
"element": interpolationFuncElement(),
|
||||
"replace": interpolationFuncReplace(),
|
||||
"split": interpolationFuncSplit(),
|
||||
|
||||
// Concat is a little useless now since we supported embeddded
|
||||
// interpolations but we keep it around for backwards compat reasons.
|
||||
"concat": interpolationFuncConcat(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +84,33 @@ func interpolationFuncJoin() ast.Function {
|
|||
}
|
||||
}
|
||||
|
||||
// interpolationFuncReplace implements the "replace" function that does
|
||||
// string replacement.
|
||||
func interpolationFuncReplace() ast.Function {
|
||||
return ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeString, ast.TypeString, ast.TypeString},
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func(args []interface{}) (interface{}, error) {
|
||||
s := args[0].(string)
|
||||
search := args[1].(string)
|
||||
replace := args[2].(string)
|
||||
|
||||
// We search/replace using a regexp if the string is surrounded
|
||||
// in forward slashes.
|
||||
if len(search) > 0 && search[0] == '/' && search[len(search)-1] == '/' {
|
||||
re, err := regexp.Compile(search[1 : len(search)-1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return re.ReplaceAllString(s, replace), nil
|
||||
}
|
||||
|
||||
return strings.Replace(s, search, replace, -1), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// interpolationFuncSplit implements the "split" function that allows
|
||||
// strings to split into multi-variable values
|
||||
func interpolationFuncSplit() ast.Function {
|
||||
|
|
|
@ -107,6 +107,39 @@ func TestInterpolateFuncJoin(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestInterpolateFuncReplace(t *testing.T) {
|
||||
testFunction(t, testFunctionConfig{
|
||||
Cases: []testFunctionCase{
|
||||
// Regular search and replace
|
||||
{
|
||||
`${replace("hello", "hel", "bel")}`,
|
||||
"bello",
|
||||
false,
|
||||
},
|
||||
|
||||
// Search string doesn't match
|
||||
{
|
||||
`${replace("hello", "nope", "bel")}`,
|
||||
"hello",
|
||||
false,
|
||||
},
|
||||
|
||||
// Regular expression
|
||||
{
|
||||
`${replace("hello", "/l/", "L")}`,
|
||||
"heLLo",
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
`${replace("helo", "/(l)/", "$1$1")}`,
|
||||
"hello",
|
||||
false,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestInterpolateFuncSplit(t *testing.T) {
|
||||
testFunction(t, testFunctionConfig{
|
||||
Cases: []testFunctionCase{
|
||||
|
@ -225,7 +258,9 @@ func testFunction(t *testing.T, config testFunctionConfig) {
|
|||
}
|
||||
|
||||
if !reflect.DeepEqual(out, tc.Result) {
|
||||
t.Fatalf("%d: bad: %#v", i, out)
|
||||
t.Fatalf(
|
||||
"%d: bad output for input: %s\n\nOutput: %#v",
|
||||
i, tc.Input, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue