Skip to content

Bad ordering during merge key sequence evaluation? #840

@Madoxen

Description

@Madoxen

Describe the bug
Not sure if this is a actual bug or me misinterpreting the merge key draft spec (there is no official spec aside from this one): https://yaml.org/type/merge.html

The spec outlines the override ordering:
If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier in the sequence override keys specified in later mapping nodes.

goccy/go-yaml does this in reverse order, where latter keys override the former ones, while the spec says otherwise. The old gopkg.in/yaml behaves correctly when unmarshaling merge keys to map, but does entirely different thing when doing so to struct, more on it later.

To Reproduce

Example behaviour goccy-go/yaml: https://go.dev/play/p/8UxGfgYCs8j
Example behaviour gopkg.in/yaml.v2: https://go.dev/play/p/8jkv3N954K9

Expected behavior
I would expect this yaml:

a: &a
  entry:
    env:
      A: "a"
      B: "c"
      D: "d"

b: &b
  entry:
    env:
      B: "b"
      A: "c"
      E: "e"

images:
  hello:
    <<: [*a, *b]

to be marshalled into:

images:
  hello:
    entry:
      env:
        A: "a"
        B: "c"
        D: "d"

not into

images:
  hello:
    entry:
      env:
        A: "c"
        B: "b"
        E: "e"

due to *a being earlier than *b in merge sequence as per spec.

Version Variables

  • go-yaml's Version: 1.19.2

Additional context
Note, that I've only mentioned unmarshalling into maps, unmarshaling into structs is broken due to #776 and also needs AllowDuplicateMapKey option turned on for the decoder. The behaviour with structs is totally different for gopkg.in/yaml.v2 where it will try to recursively merge maps which is completely out of spec.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions