Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ver=0.1.2
ver=0.2.0
bindir=bin
container_cli=docker
cmd_dir=./cmd/tpl/
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@ tpl '{{ . }}'

## Templates

The root templates name is `_tpl.root` and positional arguments are parsed into this root template. That means while its possible to specify multiple arguments, they will overwrite each other unless they use the `define` keyword to define a named template that can be referenced later when executing the template. If a named templates is specified multiple times, the last one will override the previous ones.
The default templates name is `_gotpl_default` and positional arguments are parsed into this root template. That means while its possible to specify multiple arguments, they will overwrite each other unless they use the `define` keyword to define a named template that can be referenced later when executing the template. If a named template is parsed multiple times, the last one will override the previous ones.

Templates from the flags --file and --glob are parsed in the order they are specified. So the override rules of the text/template package apply. If a file with the same name is specified multiple times, the last one wins. Even if they are in different directories.

The behavior of the cli tries to stay consistent with the actual behavior of the go template engine.

By default the root template is executed if at least one positional argument has been provided. Otherwise the first parsed file name is used to to determine which named template to execute since the root templates body is empty. It is always possible to choose another template to execute by using the --name flag.
If the default template exists it will be used unless the --name flag is specified. If no default template exists because no positional argument has been provided, the template with the given file name is used, as long as only one file has been parsed. If multiple files have been parsed, the --name flag is required to avoid ambiguity.

```bash
tpl '{{ . }}' --file foo.tpl --glob templates/*.tpl
tpl '{{ . }}' --file foo.tpl --glob templates/*.tpl # default will be used
tpl --file foo.tpl # foo.tpl will be used
tpl --file foo.tpl --glob templates/*.tpl --name foo.tpl # the --name flag is required to select a template by name
```

The ability to parse multiple templates makes sense when defining helper snippets and other named templates to reference using the builtin `template` keyword or the custom `include` function which can be used in pipelines.
Expand Down
25 changes: 16 additions & 9 deletions cmd/tpl/tpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ var (
options []string
decoder string
noNewline bool
version = "0.1.2"
version = "0.2.0"
commit = "unknown"
debugMode bool
reflectMode bool
)

const rootTemplateName = "_tpl.root"
const defaultTemplateName = "_gotpl_default"

func main() {

Expand All @@ -41,8 +41,9 @@ func main() {

err := run()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
flag.Usage()
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
os.Exit(1)
}

Expand All @@ -56,7 +57,7 @@ func run() error {
var err error

// create the root template
tpl := template.New(rootTemplateName)
tpl := template.New(defaultTemplateName)
tpl.Option(options...)
tpl.Funcs(textfunc.MapClosure(sprig.TxtFuncMap(), tpl))

Expand All @@ -72,6 +73,7 @@ func run() error {
// to align with go's template package
fileIndex := 0
globIndex := 0

for _, arg := range os.Args[1:] {
if arg == "-f" || arg == "--file" {
// parse next file
Expand Down Expand Up @@ -103,12 +105,17 @@ func run() error {
return errors.New("no templates found")
}

// determine the template name to use
// determine the template to use
if templateName == "" {
if flag.NArg() > 0 {
templateName = rootTemplateName
} else if globIndex > 0 || fileIndex > 0 {
if len(flag.Args()) > 0 {
templateName = defaultTemplateName
} else if len(templates) == 1 {
templateName = templates[0].Name()
} else {
return errors.New(fmt.Sprintf(
"the --name flag is required when multiple templates are defined and no default template exists%s",
tpl.DefinedTemplates(),
))
}
}

Expand Down Expand Up @@ -209,7 +216,7 @@ func setFlagUsage() {
fmt.Printf("Examples:\n")
fmt.Printf(" tpl '{{ . }}' < data.json\n")
fmt.Printf(" tpl --file my-template.tpl < data.json\n")
fmt.Printf(" tpl --glob templates/* < data.json\n")
fmt.Printf(" tpl --glob templates/* --name foo.tpl < data.json\n")
}

}
Expand Down