Skip to content

Commit

Permalink
Template function fixes and renaming (docker-archive#384)
Browse files Browse the repository at this point in the history
Signed-off-by: David Chung <[email protected]>
  • Loading branch information
David Chung committed Feb 3, 2017
1 parent 4b179b1 commit f823896
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 16 deletions.
32 changes: 29 additions & 3 deletions pkg/template/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func SplitLines(o interface{}) ([]string, error) {

// FromJSON decode the input JSON encoded as string or byte slice into a map.
func FromJSON(o interface{}) (interface{}, error) {
ret := map[string]interface{}{}
var ret interface{}
switch o := o.(type) {
case string:
err := json.Unmarshal([]byte(o), &ret)
Expand Down Expand Up @@ -136,11 +136,37 @@ func (t *Template) DefaultFuncs() map[string]interface{} {
return make([]struct{}, c)
},

"var": func(name, doc string, v ...interface{}) interface{} {
"def": func(name string, args ...interface{}) (string, error) {
if _, has := t.defaults[name]; has {
// not sure if this is good, but should complain loudly
return "", fmt.Errorf("already defined: %v", name)
}
var doc string
var value interface{}
switch len(args) {
case 1:
// just value, no docs
value = args[0]
case 2:
// docs and value
doc = fmt.Sprintf("%v", args[0])
value = args[1]
}
t.defaults[name] = defaultValue{
Name: name,
Value: value,
Doc: doc,
}
return "", nil
},

"ref": func(name string) interface{} {
if found, has := t.binds[name]; has {
return found
} else if v, has := t.defaults[name]; has {
return v.Value
}
return v // default
return nil
},

"global": func(name string, v interface{}) interface{} {
Expand Down
8 changes: 8 additions & 0 deletions pkg/template/funcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ func TestQueryObjectEncodeDecode(t *testing.T) {
require.NoError(t, err)

require.Equal(t, decoded, decoded2)

decoded, err = FromJSON("[]")
require.NoError(t, err)
require.Equal(t, []interface{}{}, decoded)

decoded, err = FromJSON(`{"foo":"bar"}`)
require.NoError(t, err)
require.Equal(t, map[string]interface{}{"foo": "bar"}, decoded)
}

func TestQueryObject(t *testing.T) {
Expand Down
30 changes: 19 additions & 11 deletions pkg/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,23 @@ type Options struct {
SocketDir string
}

type defaultValue struct {
Name string
Value interface{}
Doc string
}

// Template is the templating engine
type Template struct {
options Options

url string
body []byte
parsed *template.Template
funcs map[string]interface{}
binds map[string]interface{}
lock sync.Mutex
url string
body []byte
parsed *template.Template
funcs map[string]interface{}
binds map[string]interface{}
defaults map[string]defaultValue
lock sync.Mutex
}

// NewTemplate fetches the content at the url and returns a template. If the string begins
Expand Down Expand Up @@ -84,11 +91,12 @@ func NewTemplateFromBytes(buff []byte, contextURL string, opt Options) (*Templat
}

return &Template{
options: opt,
url: contextURL,
body: buff,
funcs: map[string]interface{}{},
binds: map[string]interface{}{},
options: opt,
url: contextURL,
body: buff,
funcs: map[string]interface{}{},
binds: map[string]interface{}{},
defaults: map[string]defaultValue{},
}, nil
}

Expand Down
17 changes: 15 additions & 2 deletions pkg/template/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ func TestVarAndGlobal(t *testing.T) {
str := `{{ q "locations[?state == 'WA'].name | sort(@) | {WashingtonCities: join(', ', @)}" . | global "washington-cities"}}
{{/* The query above is exported and referenced somewhere else */}}
{{ from_json "[\"SF\",\"LA\"]" | def "california-cities" "Default value for California cities" }}
{{ from_json "{\"SF\":\"94109\",\"LA\":\"90210\"}" | def "zip-codes" "Default value for zip codes" }}
{
"test" : "hello",
"val" : true,
"result" : {{var "washington-cities" "A json with washington cities" | to_json}}
"result" : {{ref "washington-cities" | to_json}},
"california" : {{ ref "california-cities" | to_json}},
"sf_zip" : {{ ref "zip-codes" | q "SF" | to_json }}
}
`

Expand All @@ -59,12 +64,20 @@ func TestVarAndGlobal(t *testing.T) {
expected := `
{
"test" : "hello",
"val" : true,
"result" : {
"WashingtonCities": "Bellevue, Olympia, Seattle"
}
},
"california" : [
"SF",
"LA"
],
"sf_zip" : "94109"
}
`
require.Equal(t, expected, view)
Expand Down

0 comments on commit f823896

Please sign in to comment.