diff --git a/README.md b/README.md index 8c311587..d4a6f6f6 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,8 @@ e75a60548dc9 = 1 # a key can be either container name (nginx) or ID The templates used by docker-gen are written using the Go [text/template](http://golang.org/pkg/text/template/) language. In addition to the [built-in functions](http://golang.org/pkg/text/template/#hdr-Functions) supplied by Go, docker-gen uses [sprig](https://masterminds.github.io/sprig/) and some additional functions to make it simpler (or possible) to generate your desired output. +For parsing several templates, split path with `;` (for example `template = "nginx.tmpl;header.tmpl"`). This makes possible to use go nested templates through standard `template` function. + #### Emit Structure Within the templates, the object emitted by docker-gen will be a structure consisting of following Go structs: @@ -365,6 +367,7 @@ For example, this is a JSON version of an emitted RuntimeContainer struct: * *`groupByKeys $containers $fieldPath`*: Returns the same as `groupBy` but only returns the keys of the map. * *`groupByMulti $containers $fieldPath $sep`*: Like `groupBy`, but the string value specified by `$fieldPath` is first split by `$sep` into a list of strings. A container whose `$fieldPath` value contains a list of strings will show up in the map output under each of those strings. * *`groupByLabel $containers $label`*: Returns the same as `groupBy` but grouping by the given label's value. +* *`include $file`*: Returns content of `$file`, and empty string if file reading error. * *`intersect $slice1 $slice2`*: Returns the strings that exist in both string slices. * *`json $value`*: Returns the JSON representation of `$value` as a `string`. * *`keys $map`*: Returns the keys from `$map`. If `$map` is `nil`, a `nil` is returned. If `$map` is not a `map`, an error will be thrown. diff --git a/internal/template/functions.go b/internal/template/functions.go index 41b3e7de..c82139ea 100644 --- a/internal/template/functions.go +++ b/internal/template/functions.go @@ -8,6 +8,7 @@ import ( "io" "io/ioutil" "log" + "os" "reflect" "strings" ) @@ -31,6 +32,14 @@ func keys(input interface{}) (interface{}, error) { return k, nil } +func include(file string) string { + data, err := os.ReadFile(file) + if err != nil { + return "" + } + return string(data) +} + func intersect(l1, l2 []string) []string { m := make(map[string]bool) m2 := make(map[string]bool) diff --git a/internal/template/functions_test.go b/internal/template/functions_test.go index 3e872a82..497016bf 100644 --- a/internal/template/functions_test.go +++ b/internal/template/functions_test.go @@ -78,6 +78,16 @@ func TestKeysNil(t *testing.T) { } } +func TestInclude(t *testing.T) { + data := include("some_random_file") + assert.Equal(t, "", data) + + _ = os.WriteFile("/tmp/docker-gen-test-temp-file", []byte("some string"), 0o777) + data = include("/tmp/docker-gen-test-temp-file") + assert.Equal(t, "some string", data) + _ = os.Remove("/tmp/docker-gen-test-temp-file") +} + func TestIntersect(t *testing.T) { i := intersect([]string{"foo.fo.com", "bar.com"}, []string{"foo.bar.com"}) assert.Len(t, i, 0, "Expected no match") diff --git a/internal/template/template.go b/internal/template/template.go index c6711e29..a20562c8 100644 --- a/internal/template/template.go +++ b/internal/template/template.go @@ -54,6 +54,7 @@ func newTemplate(name string) *template.Template { "groupByMulti": groupByMulti, "groupByLabel": groupByLabel, "json": marshalJson, + "include": include, "intersect": intersect, "keys": keys, "replace": strings.Replace, @@ -207,13 +208,14 @@ func GenerateFile(config config.Config, containers context.Context) bool { } func executeTemplate(templatePath string, containers context.Context) []byte { - tmpl, err := newTemplate(filepath.Base(templatePath)).ParseFiles(templatePath) + templatePathList := strings.Split(templatePath, ";") + tmpl, err := newTemplate(filepath.Base(templatePath)).ParseFiles(templatePathList...) if err != nil { log.Fatalf("Unable to parse template: %s", err) } buf := new(bytes.Buffer) - err = tmpl.ExecuteTemplate(buf, filepath.Base(templatePath), &containers) + err = tmpl.ExecuteTemplate(buf, filepath.Base(templatePathList[0]), &containers) if err != nil { log.Fatalf("Template error: %s\n", err) }