mikefarah / yq

yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor
https://mikefarah.gitbook.io/yq/
MIT License
12.02k stars 590 forks source link

yq is confused by the indentation of a comment, considers it belonging to a wrong node. #2054

Open OndraZizka opened 4 months ago

OndraZizka commented 4 months ago

yq messes with the comments when just reading and then writing (edit: due to a bug in the underlying go/yaml).

Version of yq: 4.40.05 Operating system: linux, Ubuntu 23.10

Input Yaml

Original:

images:
  ### Some comment
  - name: mounting-app
    ### Other comment
    newName: "foo bar"
    ###  Other comment
    newTag: "foo bar" # Line comment
  ### }

  - name: "Some name"

After any processing by yq:

images:
  ### Some comment
  - name: mounting-app
    ### Other comment
    newName: "foo bar"
    ###  Other comment
    newTag: "foo bar" # Line comment

  - name: "Some name"
  ### }

Notice the difference: The ### } is moved down 2 lines.

My guess is that based on the position, yq determines correctly it is a foot_comment.

But because of indentation, yq determines it as belonging to the node at the same level - the nest array element, starting at - name.

And then mixes it together, and puts it to that node (let's call it .images[1].name) as a foot_comment.

Correct behavior would be, despite it's indentation, assign that as belonging to .images[0].newTag, even if with a misfitting indentation.

Command More less any command that retains the affected nodes.

Thanks for reviewing.

mikefarah commented 3 months ago

This is a problem with the underlying yaml parser yq uses (go/yaml), which makes a best effort approach in round-tripping comments. There have been several issues raised against that project; but none have been addressed :(

hamadodene commented 3 months ago

I also have a similar problem when trying to update a tag inside a values.yaml.gompl where there was something like this:

privateRegistry: {{ requiredEnv "PRIVATE_REGISTRY" }} After running the yq command, it returns: privateRegistry: {? {requiredEnv "PRIVATE_REGISTRY": ''}: ''} Is there a workaround for this?

OndraZizka commented 3 months ago

I applied a workaround, the idea is:

1) Process with yq . to get another file, only with these confused details 2) Store the diff of the two 3) Do the actual change you want to do with yq 4) Revert the changes from the previously stored diff.

If your actual change does not collide with any of the intended changes, you'll get what you need.

OndraZizka commented 3 weeks ago

@mikefarah Is there a ticket for go/yaml I could vote for? This is quite limiting for processing human-edited YAMLs... If you could please link one, thanks