Technical architecture

1. Go Libraries used

2. Template system

template system doc 1

There is the choice between Go template/text or template/html libraries. I chosen template/text to avoid some escaping that are not needed in bash.

Go template/text or template/html don’t provide any execution context to the filters (FuncMap).

I’m not using Template.ParseGlob because I have to call it twice to include files of root directory and sub directories with 2 glob patterns. But a bug in text/template makes the template be initialized again after each calls to ParseGlob function. So I compute manually list of templates in internal/render/render.go NewTemplate function.

I simulated a context by pushing the context to the render function. So the data associated to the template has the following structure:

type Context struct {
 Template *template.Template
 Name     string
 RootData any
 Data     any
}
  • Template points to the first template that has been rendered
  • Name is the name of the first template that has been rendered
  • RootData are the data that have been sent at the start of the rendering
  • Data are the data sent to the sub template (possibly a part of RootData or the whole RootData)

Then each filter has to be called with the right context. The special filter include allows to include a sub template overriding context Data.

Template filter functions, internal/render/functions/index.go includes:

  • Sprig filter functions
    • Sprig is not maintained anymore, a possible alternate fork is sprout but it misses a lot of functions.
  • my own templates functions
    • string functions
      • stringLength
      • format allow to format string like in this example
        • {{ format "${%sLongDescription[@]}" .functionName }}
    • templates functions
      • include: allows to include a template by template name allowing to use filter
      • includeFile: allows to include a template by filename
      • includeFileAsTemplate: same as includeFile but interpreting the file as a template
      • dynamicFile: resolve first matching filepath in paths provided as argument

3. Compiler

see Compile command.