Skip to content
Draft
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
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ docker run --rm -v "$PWD:/work" ghcr.io/digitalstudium/helmfmt:latest \
--files templates/deployment.yaml templates/service.yaml
```

### Helmfile templates

[Helmfile](https://helmfile.readthedocs.io/) value files use extra template
functions on top of Helm/Sprig (`env`, `requiredEnv`, `exec`, `readFile`,
`fetchSecretValue`, ...). `helmfmt` accepts these functions as well, so it also
formats helmfile files. The `.gotmpl` extension (e.g. `helmfile.yaml.gotmpl`,
`values/demo.yaml.gotmpl`) is included by default:

```bash
helmfmt --check --files helmfile.yaml.gotmpl values/demo.yaml.gotmpl
cat values/demo.yaml | helmfmt --check
```

---

## Configuration
Expand All @@ -239,7 +252,7 @@ docker run --rm -v "$PWD:/work" ghcr.io/digitalstudium/helmfmt:latest \
```json
{
"indent_size": 2,
"extensions": [".yaml", ".yml", ".tpl"],
"extensions": [".yaml", ".yml", ".tpl", ".gotmpl"],
"rules": {
"indent": {
"tpl": {
Expand Down
32 changes: 21 additions & 11 deletions format.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,16 @@ var (
func stub(args ...interface{}) interface{} { return nil }

// helmFuncMap returns a template.FuncMap containing stub registrations for
// every sprig function (minus env/expandenv which Helm drops) plus Helm's own
// additions. Only the presence of each name matters for parse-time syntax
// validation; the stubs are never executed.
// every sprig function (minus env/expandenv which Helm drops), Helm's own
// additions, and the template functions helmfile registers on top of
// Helm/Sprig (env, requiredEnv, exec, readFile, ...). Only the presence of
// each name matters for parse-time syntax validation; the stubs are never
// executed.
//
// The sprigStubNames slice is generated by `go generate` from the actual
// sprig.TxtFuncMap(), so it stays in sync when sprig adds new functions.
func helmFuncMap() template.FuncMap {
f := make(template.FuncMap, len(sprigStubNames)+10)
f := make(template.FuncMap, len(sprigStubNames)+25)
for _, name := range sprigStubNames {
f[name] = stub
}
Expand All @@ -64,18 +66,26 @@ func helmFuncMap() template.FuncMap {
for _, name := range helmExtras {
f[name] = stub
}
// Helmfile-specific functions not in Helm/sprig
helmfileExtras := []string{
"env", "requiredEnv", "exec", "envExec",
"readFile", "readDir", "readDirEntries",
"getOrNil", "setValueAtPath",
"fetchSecretValue", "expandSecretRefs", "kustomizeBuild",
}
for _, name := range helmfileExtras {
f[name] = stub
}
return f
}

// validateTemplateSyntax validates the given template source string using
// Helm function set. Returns an error if the template has invalid syntax.
// validateTemplateSyntax validates the given template source string using the
// combined Helm/helmfile function set. Returns an error if the template has
// invalid syntax.
func validateTemplateSyntax(src string) error {

// Get Helm's built-in function map
helmFuncMap := helmFuncMap()

// Create and parse template with helm function map
_, err := template.New("validation").Funcs(helmFuncMap).Parse(src)
// Create and parse template with the function map
_, err := template.New("validation").Funcs(helmFuncMap()).Parse(src)
if err != nil {
return fmt.Errorf("invalid template syntax: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func loadConfig() *Config {
// Default config
config := &Config{
IndentSize: 2,
Extensions: []string{".yaml", ".yml", ".tpl"},
Extensions: []string{".yaml", ".yml", ".tpl", ".gotmpl"},
Rules: RulesConfig{
Indent: map[string]RuleConfig{
"tpl": {Disabled: true, Exclude: []string{}},
Expand Down
3 changes: 3 additions & 0 deletions templates_test/helmfile_values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: "Helmfile .gotmpl values with env/requiredEnv"
input_file: "templates/helmfile_values.yaml.gotmpl"
expected_file: "templates_expected/helmfile_values.yaml.gotmpl"
7 changes: 7 additions & 0 deletions templates_test/templates/helmfile_values.yaml.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{- if env "FEATURE_ENABLED" }}
{{ range $name := .Values.releases }}
{{- $token := requiredEnv "GITHUB_TOKEN" }}
name: {{ $name }}
registry: {{ env "REGISTRY" | default "private.azurecr.io" }}
{{- end }}
{{- end }}
7 changes: 7 additions & 0 deletions templates_test/templates_expected/helmfile_values.yaml.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{- if env "FEATURE_ENABLED" }}
{{ range $name := .Values.releases }}
{{- $token := requiredEnv "GITHUB_TOKEN" }}
name: {{ $name }}
registry: {{ env "REGISTRY" | default "private.azurecr.io" }}
{{- end }}
{{- end }}
Loading