gotpl-yaml-linter

module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: Apache-2.0

README

gotpl-linter — Go template YAML (Helm) linting & formatting

A small CLI that lints and formats Go-template YAML files, primarily Helm chart templates. It re-indents template blocks based on go-template control-structure depth (if / range / with / defineend) rather than YAML nesting, so nested {{- if }} / {{- end }} blocks line up consistently at two spaces per level.

Built with Go 1.22.

Install

go install github.com/imunhatep/gotpl-yaml-linter/cmd/gotpl-linter@latest

gotpl-linter --help
Container image

Released images are published to GHCR for linux/amd64 and linux/arm64. The working directory inside the image is /work, so mount the chart there:

podman run --rm -v "$PWD:/work:ro" \
  ghcr.io/imunhatep/gotpl-yaml-linter:latest lint -p /work/templates

Usage

The tool has two commands:

  • lint — validate formatting; writes nothing. Exits non-zero if any file is not correctly formatted. Use this in CI.
  • fmt — format files in place, rewriting any file that differs.
NAME:
   gotpl-linter - Go template YAML (Helm) formatting and linting tool

USAGE:
   gotpl-linter [global options] command [command options]

COMMANDS:
   fmt      format yaml tpl files in place
   lint     validate yaml gotpl formatting (no changes written)
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --verbose value, --vv value  Log verbosity (default: 3) [$APP_DEBUG]
   --help, -h                   show help
   --version, -v                print the version

--vv sets log verbosity: 0 fatal, 1 error, 2 warn, 3 info (default), 4 debug, 5+ trace. It can also be set via the APP_DEBUG environment variable.

Command options

Both lint and fmt take the same flags:

Flag Alias Default Description
--path -p ./ Directory to scan for template files
--filter -f * Glob pattern to match files (single directory level, non-recursive)
--show -s false Print the expected formatting to stdout
--trim -t false Rewrite non-{{- template openings to {{- so they can be re-indented

Note: --filter is a single-level glob matched against <path>/<filter>; it does not recurse into subdirectories.

Re-indentation and rendered output

Re-indentation only changes the leading whitespace of template lines. That whitespace is stripped at render time only when the line's opening action left-trims ({{-). A line that opens with a plain {{ has its leading whitespace rendered literally into the output, so re-indenting it would shift the emitted YAML.

  • By default the tool is output-safe: lines that do not left-trim are left exactly as they are (their block depth is still tracked, so surrounding {{- lines indent correctly). Lines that already use {{- are re-indented.
  • With --trim (-t) the tool rewrites each non-{{- opening to {{- and then re-indents it. This normalises indentation everywhere but can change the rendered output, so review the diff before committing.
Lint

Validate that files are correctly formatted. Nothing is written; a non-zero exit code indicates at least one file is not formatted as expected.

gotpl-linter --vv 10 lint --path ./templates --filter '*.yaml'
Format

Rewrite files in place to the expected formatting.

gotpl-linter --vv 10 fmt --path ./templates --filter '*.yaml'

Add --show to either command to print the expected output:

gotpl-linter lint -p ./templates -f '*.yaml' --show

Examples

Formatting reindents template control lines to two spaces per block level. Plain YAML lines are left untouched — only go-template lines are re-indented.

Example 1

Input:

{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
{{- include  "isControllerTagValid" . -}}
    {{- include "ingress-nginx.labels" . | nindent 4 }}
{{- end }}

Output:

{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
  {{- include  "isControllerTagValid" . -}}
  {{- include "ingress-nginx.labels" . | nindent 4 }}
{{- end }}
Example 2

Input:

{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
{{- include  "isControllerTagValid" . -}}
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    {{- include "ingress-nginx.labels" . | nindent 4 }}
    app.kubernetes.io/component: controller
    {{- with .Values.controller.labels }}
    {{- toYaml . | nindent 4 }}
    {{- end }}
  name: {{ include "ingress-nginx.controller.fullname" . }}
  namespace: {{ .Release.Namespace }}
  {{- if .Values.controller.annotations }}
  annotations: {{ toYaml .Values.controller.annotations | nindent 4 }}
  {{- end }}
{{- end }}

Output:

{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
  {{- include  "isControllerTagValid" . -}}
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
  {{- include "ingress-nginx.labels" . | nindent 4 }}
    app.kubernetes.io/component: controller
  {{- with .Values.controller.labels }}
    {{- toYaml . | nindent 4 }}
  {{- end }}
  name: {{ include "ingress-nginx.controller.fullname" . }}
  namespace: {{ .Release.Namespace }}
  {{- if .Values.controller.annotations }}
  annotations: {{ toYaml .Values.controller.annotations | nindent 4 }}
  {{- end }}
{{- end }}
Example 3

Input:

{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
{{- include  "isControllerTagValid" . -}}
    {{- include "ingress-nginx.labels" . | nindent 4 }}
    {{- with .Values.controller.labels }}
    {{- toYaml . | nindent 4 }}
    {{- end }}
  {{- if .Values.controller.annotations }}
    {{- with .Values.controller.labels }}
    {{- toYaml . | nindent 8 }}
    {{- end }}
  {{- end }}
      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
  {{- if not .Values.controller.autoscaling.enabled }}
  {{- end }}
{{- end }}

Output:

{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
  {{- include  "isControllerTagValid" . -}}
  {{- include "ingress-nginx.labels" . | nindent 4 }}
  {{- with .Values.controller.labels }}
    {{- toYaml . | nindent 4 }}
  {{- end }}
  {{- if .Values.controller.annotations }}
    {{- with .Values.controller.labels }}
      {{- toYaml . | nindent 8 }}
    {{- end }}
  {{- end }}
  {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
  {{- if not .Values.controller.autoscaling.enabled }}
  {{- end }}
{{- end }}

Build from source

make                  # build binary into dist/
make test             # gofmt check + go vet + golint + go test
make xb               # cross-build for linux/darwin/windows
make image            # build a single-arch container image for the local host
make image-multiarch  # build a linux/amd64 + linux/arm64 manifest

Directories

Path Synopsis
cmd
gotpl-linter command
app

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL