CertainLach/jrsonnet

Yaml multiline string pretty-printing in manifestification

psalaberria002 opened this issue · 6 comments

Since 0.9 the string formatting defaults to pretty formatting. See dtolnay/serde-yaml#226.

It would be great to get that updated.

serde-yaml here is only used for parsing, manifestification is implemented manually, the same way as it implemented in official jsonnet: https://github.com/CertainLach/jrsonnet/blob/master/crates/jrsonnet-stdlib/src/manifest/yaml.rs#L110

It should be possible to implement different string manifestification strategy, but this should be also proposed/implemented on https://github.com/google/jsonnet side.

We get a much better manifestation from kubecfg, which is a go program sitting on top of the go jsonnet and doing https://github.com/kubecfg/kubecfg/blob/main/pkg/kubecfg/show.go#L159-L171 - I think we'd be happy to do a similar shim on top of jrsonnet if we need to, but since producing config files at scale is a key use case, and since readability when doing code review matters - on the output - it would be great if you can suggest some way forward that involves somewhat less redundancy :)

I'll think about this, I might add this feature under the feature-flag, because I agree such multiline string output is much better.

I want jrsonnet to be mostly output-compatible with go-jsonnet. I won't make it worse in the sake of compatibility (Such as in #108), but I don't want defaults to be different.

It might be a good idea to leave std.manifestYamlEx as-is, but then add new output format --format=pretty-yaml.
There already exist --format=json (Which is default), --format=yaml (Which is default when using -y flag), --format=string (This is an alternative syntax for -S) and --format=toml

I think we've found a workaround for now - we just do

   thing: std.manifestYamlDoc(obj_to_stringify) + "\n"

which triggers your codepath here:

} else if let Some(s) = s.strip_suffix('\n') {

Oh, it already exists in jsonnet:
https://github.com/google/jsonnet/blob/master/stdlib/std.jsonnet#L1219-L1223

        else if v[len - 1] == '\n' then
          local split = std.split(v, '\n');
          std.join('\n' + cindent + '  ', ['|'] + split[0:std.length(split) - 1])
        else
          std.escapeStringJson(v)

Even better, then it can be implemented by default for jrsonnet, and then it is possible to update original jsonnet to include this shorthand as well:

        else if v[len - 1] == '\n' then
          local split = std.split(v, '\n');
          std.join('\n' + cindent + '  ', ['|'] + split[0:std.length(split) - 1])
        else if std.member(v, '\n') then
          local split = std.split(v, '\n');
          std.join('\n' + cindent + '  ', ['|-'] + split[0:std.length(split) - 1])
        else
          std.escapeStringJson(v)