twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
13.4k stars 493 forks source link

Boolean functions in templates #888

Closed fwsmit closed 4 years ago

fwsmit commented 4 years ago

I'm not sure if this is a feature request or a bug, because I believe at some point this worked in chezmoi.

When I create templates in chezmoi, it's mostly to change configs slightly for different systems based on the hostname. If I have the same changes I want to have on the systems foo and bar, I would like to say: {{- if eq .chezmoi.hostname "foo" | eq .chezmoi.hostname "bar"}} Config for foo and bar {{- end }} When I do chezmoi apply, it says <eq .chezmoi.hostname "bar">: error calling eq: incompatible types for comparison

It would be nice if most of the things higlighted in this webpage would work in chezmoi templates.

zb140 commented 4 years ago

The issue you're running into is that | is a pipeline operator, not an "or" operator. Piping a value into a function like this uses the value as the final argument to the function. So what's actually happening in your example is eq .chezmoi.hostname "foo" gets evaluated to a boolean (let's say true for example), then eq .chezmoi.hostname "bar" true gets evaluated. But since true can't be compared to a string with eq, it throws the error you're seeing.

Having said that, there is an easy way to achieve what you're trying to do. The eq function can actually take several arguments, not just two. The function will return true if the first argument compares equal to any of the remaining arguments. So you can just do this:

{{- if eq .chezmoi.hostname "foo" "bar"}}
Config for foo and bar
{{- end }}

For example:

$ echo '{{ if eq "foo" "foo" "bar" }}hello{{end}}' | chezmoi execute-template
hello
$ echo '{{ if eq "bar" "foo" "bar" }}hello{{end}}' | chezmoi execute-template
hello
$ echo '{{ if eq "baz" "foo" "bar" }}hello{{end}}' | chezmoi execute-template

chezmoi does use the text/template engine, so everything on the linked page should work as expected. Are you seeing any other issues that don't seem to work? In addition to that, chezmoi also bundles all of the Sprig functions described here, so you can use any of them in your templates too.

fwsmit commented 4 years ago

Thanks for you answer. This works indeed. It's weird, because I really thought that | worked with some version of chezmoi. Anyways, the documentation on templates could be improved. The golang website isn't really clear to me. Let me know if I can help with that documentation