Search code examples
kubernetes-helmgo-templates

How to handle indentation when including an empty template in Helm?


I have a named template that holds a list of values.

{{- define "mychart.labels" }}
  {{- $labels := .Values.labels }}
  {{- if $labels }}
    {{- toYaml $labels }}
  {{- end }}
{{- end -}}

I include it like this

...
labels:
  {{- include "mychart.labels" | nindent 2 }}
annotations:
...

Problem is that when there are no labels defined I get an blank line with 2 spaces (I will represent spaces with _)

...
labels:
__
annotations:
...

I want to avoid this. I want no line when labels are not present.

...
labels:
annotations:
...

I know it can be done by first checking whether the template is empty or not using if and then include it. But using if around every include feels cumbersome and I feel there must be a inbuilt way to handle this that I am unaware of.

I thought I can change nindent to ident and add a line break at start of template if .Values.labels are given. This way no empty line will be added when .Values.labels are not given. I tried to redefine the template as follows:

{{- define "mychart.labels" }}
  {{- $labels := .Values.labels }}
  {{- if $labels }}
{{ toYaml $labels }}
  {{- end }}
{{- end -}}

and include it like this

...
labels:
  {{- include "mychart.labels" | indent 2 }}
annotations:
...

It looked like it worked but I got 2 spaces at the end of the previous line. They were added by indent.

...
labels:__
annotations:
...

Is there any clean way to get the behaviour I want?

Edit: This question is different from How to remove the new line added with .toYaml in helm? as I face this even when the template is completely empty

{{- define "mychart.labels" -}}
{{- end -}}

So the question or solutions don't apply in this case.


Solution

  • In your template code

    labels:
      {{- include "mychart.labels" | nindent 2 }}
    annotations:                             #   ^ here
    

    there is an unconditional newline after the include | nindent expression. To remove that newline, you'd have to put a hyphen inside the curly braces, but note that this will also remove any leading spaces on the following line (is annotations: inside a metadata: block and there are 2 leading spaces?). You would need also to make sure that, if your helper template emits anything, it ends with a newline.

    labels: {{- include "mychart.labels" . | nindent 2 -}}
    annotations: ...                                 # ^ add this hyphen
    
    {{- define "mychart.labels" -}}
    {{- if .Values.includeFooLabel }}
    foo: bar
    {{ end -}}  # keep the newline preceding this line
    {{- end -}}
    

    Another approach I've used is to use the with statement, which both is a conditional and also rebinds . to the conditional expression if it's true. You can use this to avoid repeating the include expression. If I was writing this, I might use this to avoid emitting the labels: entirely if it's not used.

    {{- with include "mychart.labels" . }}
    labels:
    {{ . | indent 2 }}
    {{- end -}}
    

    Trying to control this in detail tends to mean keeping track of where exactly the newlines and spaces are, and where you've suppressed them. The _ you've added in the question indicate you are aware of this.


    One reasonable answer is to just ignore the problem entirely. The extra newlines won't change the semantic meaning of the YAML file, so you'll only see this if someone looks directly at the helm template output; and in that case yours won't be the only rendered chart that has extra newlines like this.