carvel-dev / ytt

YAML templating tool that works on YAML structure instead of text
https://carvel.dev/ytt
Apache License 2.0
1.63k stars 137 forks source link

`or` does not test possibly-undefined data values #836

Open CJKay opened 1 year ago

CJKay commented 1 year ago

What steps did you take:

I wrote this snippet into a new file xyz.yaml:

#@ load("@ytt:data", "data")

#@ foo = data.values.foo or "bar"

What happened:

When running ytt -f xyz.yaml, the following error is generated:

ytt: Error: 
- struct has no .foo field or method
    in <toplevel>
      template.yaml:3 | #@ foo = data.values.foo or "bar"

What did you expect:

I expected templating to complete successfully and generate an empty YAML file, per the FAQ:

How do I provide a default for a data value when it may not be defined?

When a value may be null, you can use or to specify a default.

#@ data.values.foo or "bar"

~ https://carvel.dev/ytt/docs/v0.38.0/faq/#how-do-i-provide-a-default-for-a-data-value-when-it-may-not-be-defined

Environment:


Vote on this request

This is an invitation to the community to vote on issues, to help us prioritize our backlog. Use the "smiley face" up to the right of this comment to vote.

👍 "I would like to see this addressed as soon as possible" 👎 "There are other more important things to focus on right now"

We are also happy to receive and review Pull Requests if you want to help working on this issue.

vmunishwar commented 1 year ago

@CJKay Thanks for reaching out.

This seems to be working as expected. When the data values file has 'foo' as empty or null, the foo gets value as bar in the output template. Please check few examples run on the ytt playground.. Could you please elaborate your use case if that does not fit with the use of 'or' as shown in the examples? Thanks

image image image
CJKay commented 1 year ago

Hi @vmunishwar, here is an example in the playground: https://carvel.dev/ytt/#gist:https://gist.github.com/CJKay/3a5944330d82c1e04a86d1afa5a4282c

In this example no foo data value has been provided. I therefore expected the value of the foo variable to evaluate to bar, but it instead triggers an error as the data value is not defined. It's not clear from the documentation that it is necessary to provide a definition for foo (if that is indeed the expectation), as the title for the relevant FAQ entry is:

How do I provide a default for a data value when it may not be defined?

Either there is a bug in the implementation (or must test that the left value is defined), or there is a bug in the documentation:

How do I provide a default for a data value when it may not be defined may be null?

vmunishwar commented 1 year ago

Hi @CJKay Looks like this is a documentation issue. Thanks for pointing it out. We will take your inputs and try to change the docs.

For now, just to be clear, when we load a data module using #@ load("@ytt:data","data"), the data values file is used to refer to the data values and data.values is a struct supplied by the @ytt:data module. Though, we do not explicitly throw error if it is not present. So, the answer in FAQ docs `#@ data.values.foo or "bar"' refers to the use of 'or' keyword (assuming the data values file has foo as a key but not set with any default value). For complete examples please also refer to the ytt playground

Meanwhile, if you still need help kindly share your use case to use the default value for undefined data values. Thanks again for reaching out.