What's the easiest way to edit a YAML file in-place while preserving whitespace and comments? For example, if my YAML file looks like this:
foo:
# comment 1
bar:
- "str"
- "string_before" # comment 2
I want to do the equivalent of #(assoc-in % ["foo" "bar" 1] "string_after") while preserving comments, with the result being:
foo:
# comment 1
bar:
- "str"
- "string_after" # comment 2
clj-yaml doesn't seem to have a way to parse YAML and get back comments and preserve stuff like indentation-levels.
:mark true doesn't result in comments either, so I'm wondering whether this is possible with clj-yaml without dropping down to snake-yaml (or something else).Hiya @jaihindhreddy, yeah, clj-yaml parsing is actually more like loading, maybe. I think @ingy tried to teach us the correct YAML terminology at one point, but unfortunately, my wee brain did not retain it. FYI: there is an open issue regarding comments https://github.com/clj-commons/clj-yaml/issues/108
@jaihindhreddy have a look at the yq CLI utility for this kind of thing. Specifically yq -i ...
It can make updates to YAML files while preserving comments and scalar style.
It's not always perfect but pretty good.
If you need to do this from clojure code, https://yamlscript.org/ will have this capability at some point (clojure lib for YS https://clojars.org/org.yamlscript/clj-yamlscript) but not terribly soon...
Here's your example:
$ cat file.yaml
foo:
# comment 1
bar:
- "str"
- "string_before" # comment 2
$ yq -i '.foo.bar.1 = "string_after"' file.yaml
$ cat file.yaml
foo:
# comment 1
bar:
- "str"
- "string_after" # comment 2
You'll notice the sequence indent changed. That's noted in the yq docs. Apparently it's an inherited property from the upstream Go library it is built over.