carvel-dev / ytt

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

When dict is accessed using attribute notation, hint using bracket notation #121

Open pivotaljohn opened 4 years ago

pivotaljohn commented 4 years ago

Sometimes, a user may not realize they are dealing with a Starlark dictionary and attempt to access it using attribute notation (as if it were a struct). When this happens, let's give them a helping hint.

For example:

stable_config.json

{
  "vpc_id": "pete",
  "pks_subnet_ids": [ 1, 2, 3 ]
}

cluster-template-paving.yaml

 1: #@ load("@ytt:data", "data")
 2: #@ load("@ytt:json", "json")
 3:
 4: #@ stable_config = json.decode(data.values.stable_config)
 5: first_subnet_id: #@ stable_config.pks_subnet_ids[0]

yields...

$ ytt --data-value-file stable_config=stable_config.json -f cluster-template-paving.yaml -f values.yml

ytt: Error: 
- dict has no .pks_subnet_ids field or method
    in <toplevel>
      cluster-template-paving.yaml:5 |       first_subnet_id: #@ stable_config.pks_subnet_ids[0]

Let's drop them a hint:

$ ytt --data-value-file stable_config=stable_config.json -f cluster-template-paving.yaml -f values.yml

ytt: Error: 
- dict has no .pks_subnet_ids field or method (hint: use bracket notation to get dictionary values. Example: ["pks_subnet_ids"])
    in <toplevel>
      cluster-template-paving.yaml:5 |       first_subnet_id: #@ stable_config.pks_subnet_ids[0]
pivotaljohn commented 4 years ago

To the uninitiated, this may be the first time the user learns that there are such things as dictionaries in ytt (via Starlark) — in contrast to structs (which are similar in nature, being key-value pairs). Users are introduced to structs immediately, but often discover ytt's dictionaries through use or study.

Thoughts on an evergreen hyperlink to documentation specifically clarifying the the presence and purpose of structs and dictionaries in ytt?

cppforlife commented 4 years ago

i think this is a bit better:

ytt: Error:

  • dict has no .pks_subnet_ids field or method (hint: use bracket notation to access fields in dictionaries e.g. x.pks_subnet_ids should be x["pks_subnet_ids"])