Skip to content

Commit

Permalink
Add helper functions for the template
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsauter committed Oct 27, 2023
1 parent 730116f commit 5766162
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
6 changes: 6 additions & 0 deletions build/docs/render.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ The asciidoc template can access the value of the field `a` by referencing `{{.o

Note that only JSON and YAML formats are recognized as such. If a matching file does not end in either `.json` or `.y(a)ml`, its entire content is made available under the key `value`. For example, the glob pattern `*.log` might match the file `pipeline-run.log`, which would expose the content of the file as `pipeline_run.value` to the template.

The Go template has access to the following helper functions:

* `fromMultiYAML`. Turns a string of multiple YAML documents (separated with `---`) into a slice of maps.
* `toYAML`. Turns the given object into a YAML string.
* `parseTime`. Parses a string using the specified layout into a `time.Time`. This function is just a wrapper around link:https://pkg.go.dev/time#Parse[time.Parse], see its documentation for details how to specify various layouts. Once parsed, the time can be formatted with `{{$t.Format "<layout>"}}` as per link:https://pkg.go.dev/time#Time.Format[time.Format].
After the Go template has been rendered, link:https://github.com/asciidoctor/asciidoctor-pdf[asciidoctor-pdf] is used to turn each rendered asciidoc file into a PDF file. The resulting files are placed into the directory specified by `output-dir` (defaulting to `.ods/artifacts/org.opendevstack.pipeline.adoc.pdf` so that created PDFs are preserved as artifacts in Nexus). Theming is possible by specifying the `pdf-theme` parameter as explained in the link:https://docs.asciidoctor.org/pdf-converter/latest/theme/apply-theme/#theme-and-font-directories[Theme and font directories] documentation.
7 changes: 5 additions & 2 deletions cmd/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ func render(baseDir, templateGlob, outputDir string, dataSourceGlobs []string) e
strings.TrimPrefix(templateFile, baseDir),
strings.TrimPrefix(outputDir, baseDir),
)
tmpl, err := template.ParseFiles(templateFile)
templateBase := filepath.Base(templateFile)
tmpl, err := template.
New(templateBase).
Funcs(templateFuncs).
ParseFiles(templateFile)
if err != nil {
return fmt.Errorf("parse template %q: %s", templateFile, err)
}
templateBase := filepath.Base(templateFile)
err = renderTemplate(outputDir, templateBase, tmpl, data)
if err != nil {
return fmt.Errorf("render template %q: %s", templateBase, err)
Expand Down
42 changes: 42 additions & 0 deletions cmd/render/template_funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"html/template"
"strings"
"time"

"sigs.k8s.io/yaml"
)

var templateFuncs = template.FuncMap{
"fromMultiYAML": fromMultiYAML,
"toYAML": toYAML,
"parseTime": parseTime,
}

// fromMultiYAML turns a string of multiple YAML documents
// (https://yaml.org/spec/1.2.2/#22-structures) into a slice of maps.
func fromMultiYAML(marshalled string) ([]map[string]interface{}, error) {
parts := strings.Split(strings.TrimPrefix(strings.TrimSpace(marshalled), "---"), "---")
res := []map[string]interface{}{}
for _, p := range parts {
v := make(map[string]interface{})
err := yaml.Unmarshal([]byte(p), &v)
if err != nil {
return nil, err
}
res = append(res, v)
}
return res, nil
}

// toYAML turns the given object into a YAML string.
func toYAML(unmarshalled any) (string, error) {
b, err := yaml.Marshal(unmarshalled)
return string(b), err
}

// parseTime parses a string using the specified layout into a time.Time.
func parseTime(layout, t string) (time.Time, error) {
return time.Parse(layout, t)
}
6 changes: 6 additions & 0 deletions docs/render.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ The asciidoc template can access the value of the field `a` by referencing `{{.o

Note that only JSON and YAML formats are recognized as such. If a matching file does not end in either `.json` or `.y(a)ml`, its entire content is made available under the key `value`. For example, the glob pattern `*.log` might match the file `pipeline-run.log`, which would expose the content of the file as `pipeline_run.value` to the template.

The Go template has access to the following helper functions:

* `fromMultiYAML`. Turns a string of multiple YAML documents (separated with `---`) into a slice of maps.
* `toYAML`. Turns the given object into a YAML string.
* `parseTime`. Parses a string using the specified layout into a `time.Time`. This function is just a wrapper around link:https://pkg.go.dev/time#Parse[time.Parse], see its documentation for details how to specify various layouts. Once parsed, the time can be formatted with `{{$t.Format "<layout>"}}` as per link:https://pkg.go.dev/time#Time.Format[time.Format].

After the Go template has been rendered, link:https://github.com/asciidoctor/asciidoctor-pdf[asciidoctor-pdf] is used to turn each rendered asciidoc file into a PDF file. The resulting files are placed into the directory specified by `output-dir` (defaulting to `.ods/artifacts/org.opendevstack.pipeline.adoc.pdf` so that created PDFs are preserved as artifacts in Nexus). Theming is possible by specifying the `pdf-theme` parameter as explained in the link:https://docs.asciidoctor.org/pdf-converter/latest/theme/apply-theme/#theme-and-font-directories[Theme and font directories] documentation.


Expand Down

0 comments on commit 5766162

Please sign in to comment.