lang: funcs: Rename template functions to remove periods
Due to a limitation in the template library, we need to rename some functions. It's probably worth looking into modifying this library or finding an alternate version.
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs"
|
||||
@@ -189,8 +190,8 @@ func (obj *TemplateFunc) run(templateText string, vars types.Value) (string, err
|
||||
// function in the simple package?
|
||||
// TODO: loop through this map in a sorted, deterministic order
|
||||
// XXX: should this use the scope instead (so imports are used properly) ?
|
||||
// XXX: dots are not valid here, so maybe replace dots with underscores so we can do fmt_print???
|
||||
for name, fn := range simple.RegisteredFuncs {
|
||||
name = safename(name) // TODO: rename since we can't include dot
|
||||
if _, exists := funcMap[name]; exists {
|
||||
obj.init.Logf("warning, existing function named: `%s` exists", name)
|
||||
continue
|
||||
@@ -326,6 +327,23 @@ func (obj *TemplateFunc) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// safename renames the functions so they're valid inside the template. This is
|
||||
// a limitation of the template library, and it might be worth moving to a new
|
||||
// one.
|
||||
func safename(name string) string {
|
||||
// TODO: should we pick a different replacement char?
|
||||
char := funcs.ReplaceChar // can't be any of: .-#
|
||||
result := strings.Replace(name, funcs.ModuleSep, char, -1)
|
||||
if result == name {
|
||||
// No change, so add a prefix for package-less functions... This
|
||||
// prevents conflicts from sys.func1 -> sys_func1 which would be
|
||||
// a conflict with a top-level function named sys_func1 which is
|
||||
// now renamed to _sys_func1.
|
||||
return char + name
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// wrap builds a function in the format expected by the template engine, and
|
||||
// returns it as an interface{}. It does so by wrapping our type system and
|
||||
// function API with what is expected from the reflection API. It returns a
|
||||
|
||||
@@ -30,6 +30,13 @@ const (
|
||||
// example when using `fmt.printf` or `math.sin` this is the char used.
|
||||
// It is included here for convenience when importing this package.
|
||||
ModuleSep = interfaces.ModuleSep
|
||||
|
||||
// ReplaceChar is a special char that is used to replace ModuleSep when
|
||||
// it can't be used for some reason. This currently only happens in the
|
||||
// golang template library. Even with this limitation in that library,
|
||||
// we don't want to allow this as the first or last character in a name.
|
||||
// NOTE: the template library will panic if it is one of: .-#
|
||||
ReplaceChar = "_"
|
||||
)
|
||||
|
||||
// registeredFuncs is a global map of all possible funcs which can be used. You
|
||||
@@ -56,6 +63,11 @@ func Register(name string, fn func() interfaces.Func) {
|
||||
if strings.HasPrefix(name, ModuleSep) || strings.HasSuffix(name, ModuleSep) {
|
||||
panic(fmt.Sprintf("a func named %s is invalid", name))
|
||||
}
|
||||
// TODO: this should be added but conflicts with our internal functions
|
||||
// can't start or end with an underscore
|
||||
//if strings.HasPrefix(name, ReplaceChar) || strings.HasSuffix(name, ReplaceChar) {
|
||||
// panic(fmt.Sprintf("a func named %s is invalid", name))
|
||||
//}
|
||||
|
||||
//gob.Register(fn())
|
||||
registeredFuncs[name] = fn
|
||||
|
||||
1
lang/interpret_test/TestAstFunc2/template-0.output
Normal file
1
lang/interpret_test/TestAstFunc2/template-0.output
Normal file
@@ -0,0 +1 @@
|
||||
Vertex: print[template-0]
|
||||
12
lang/interpret_test/TestAstFunc2/template-0/main.mcl
Normal file
12
lang/interpret_test/TestAstFunc2/template-0/main.mcl
Normal file
@@ -0,0 +1,12 @@
|
||||
import "datetime"
|
||||
|
||||
$secplus42 = 42 + $ayear
|
||||
|
||||
# note the order of the assignment (year can come later in the code)
|
||||
$ayear = 60 * 60 * 24 * 365 # is a year in seconds (31536000)
|
||||
|
||||
$tmplvalues = struct{time => $secplus42, hello => "world",}
|
||||
|
||||
print "template-0" {
|
||||
msg => template("Hello: {{ .hello }}, 42 sec + 1 year is: {{ .time }} seconds, aka: {{ datetime_print .time }}", $tmplvalues),
|
||||
}
|
||||
Reference in New Issue
Block a user