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

struct.encode() should support YAML Fragments as values #227

Open pivotaljohn opened 3 years ago

pivotaljohn commented 3 years ago

Today:

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

#@ def labels():
foo: bar
#@ end

#@ env = struct.encode({"labels": labels()})

v: #@ env

results in ...

- (p) unknown type *yamlmeta.Map for conversion to starlark value (backtrace: goroutine 1 [running]:
    in <toplevel>
      demo.yml:7 | #@ env = struct.encode({"labels": labels()})

    reason:
     runtime/debug.Stack(0x934960, 0x8fef60, 0xc000160760)
        runtime/debug/stack.go:24 +0x9d
     github.com/k14s/ytt/pkg/template/core.ErrWrapper.func1.1(0xc00016eb78)
        github.com/k14s/ytt@/pkg/template/core/errs.go:23 +0x158
     panic(0x8fef60, 0xc000160760)
        runtime/panic.go:679 +0x1b2
     github.com/k14s/ytt/pkg/template/core.GoValue.asStarlarkValue(0x97f6a0, 0xc000178200, 0x1, 0x0, 0x99cac0, 0xc000167220, 0x8, 0x18)
...

Given that YAML Fragments are data structures, themselves (very similar to structs), struct.encode() should include the YAML Fragment.

jcfj commented 3 years ago

Oddly, this can be worked around by json.decode(json.encode(labels())), which struct knows how to deal with...

voor commented 2 years ago

For anyone finding this issue and wondering what we're talking about, here's a quick example: https://carvel.dev/ytt/#gist:https://gist.github.com/voor/234e08ff06f3e14eb2e0a1c3a8630862