yq
yq copied to clipboard
Assignment for nested keys is broken for keys following referenced parent key
Describe the bug
=
assignment is broken for nested keys following referenced one-level up property related to them.
Version of yq: 4.34.2 Operating system: Linux 22.04 Ubuntu Installed via: sudo apt install yq
Input Yaml Concise yaml document(s) (as simple as possible to show the bug, please keep it to 10 lines or less) data1.yml:
{
"first": {
"type": "string"
},
"second": {
"type": "string"
},
"referenced": {
"type": "string"
},
"third": {
"type": "string"
},
"fourth": {
"type": "string"
}
}
Command The command you ran:
yq -P -o json '.[].type = .referenced'
Actual behavior
{
"first": {
"type": {
"type": "string"
}
},
"second": {
"type": {
"type": "string"
}
},
"referenced": {
"type": {
"type": "string"
}
},
"third": {
"type": {
"type": {
"type": "string"
}
}
},
"fourth": {
"type": {
"type": {
"type": "string"
}
}
}
}
Expected behavior
{
"first": {
"type": {
"type": "string"
}
},
"second": {
"type": {
"type": "string"
}
},
"referenced": {
"type": {
"type": "string"
}
},
"third": {
"type": {
"type": "string"
}
},
"fourth": {
"type": {
"type": "string"
}
}
}
type
keys after referenced
key are assigned incorrectly. I've compared output with jq
and it works as expected.
This is because yq works a little differently than jq - for better or worse.
You can get the right result by using a variable to force it to first make a copy of .referenced
yq '.referenced as $i | .[].type = $i' file.yaml
Is it documented somewhere? Can u explain in details why it's the case? From the developer perspective.
Not documented anywhere atm. Basically what yq
is doing under the hood is looping through each LHS, evaluating the RHS (.referenced) and assigning the result.
The issue is, after .referenced is updated itself, it becomes {type: {type: string}} - from then on that's the value that's used when updating "third" and "fourth" (which is why they get an extra type.
By using the variable, we can evaluate the RHS first and cache it for use in the assignments.
It wouldn't be hard to change the way assignments work - but that could have all sorts of bad side effects for everyone already using yq and relying on the existing behavior.