I want to merge the .environments.default and .environments.dev objects together, so that dev values override any default values and default values fill in anything not defined in the dev object. If I use .environments.default * .environments.dev most of the objects are merged correctly, except for the array lists under the env and secrets objects. The entire dev object is used, but I want the array lists to be merged with unique values.
Is there anyway to get this result with jq? If it helps I could also try doing this in yq with the YAML file.
I would also really like to know if this is possible without hardcoding "env" or "secrets" anywhere in the code.
When I use .environments.default * .environments.dev on the below source...
Source:
{
"environments": {
"default": {
"config": {
"security": {
"user": 0,
"group": 0
},
"resources": {
"limits": {
"memory": "256Mi",
"cpu": "500m"
}
},
"env": [
{
"name": "DEFAULT_ENV",
"value": "DEFAULT_ENV_VALUE"
},
{
"name": "BASE_URL",
"value": "DEFAULT_BASE_URL"
}
],
"secrets": [
{
"secretID": "567",
"mountPath": "/default/dir/to/567/path"
},
{
"secretID": "123",
"mountPath": "/default/dir/to/123/path"
},
{
"secretUUID": "789",
"mountPath": "/default/dir/to/789/path"
}
]
}
},
"dev": {
"config": {
"replicas": 1,
"resources": {
"limits": {
"cpu": "5000m"
}
},
"env": [
{
"name": "BASE_URL",
"value": "DEV_BASE_URL"
},
{
"name": "DEV_ENV_1",
"value": "DEV_ENV_1"
}
],
"secrets": [
{
"secretID": "456",
"mountPath": "/dev/dir/to/456/path"
},
{
"secretID": "123",
"mountPath": "/dev/dir/to/456/path"
}
]
}
}
}
}
I get...
Current output:
{
"config": {
"security": {
"user": 0,
"group": 0
},
"resources": {
"limits": {
"memory": "256Mi",
"cpu": "5000m"
}
},
"env": [
{
"name": "BASE_URL",
"value": "DEV_BASE_URL"
},
{
"name": "DEV_ENV_1",
"value": "DEV_ENV_1"
}
],
"secrets": [
{
"secretID": "456",
"mountPath": "/dev/dir/to/456/path"
},
{
"secretID": "123",
"mountPath": "/dev/dir/to/456/path"
}
],
"replicas": 1
}
}
but I want...
Desired output:
{
"config": {
"security": {
"user": 0,
"group": 0
},
"resources": {
"limits": {
"memory": "256Mi",
"cpu": "5000m"
}
},
"env": [
{
"name": "BASE_URL",
"value": "DEV_BASE_URL"
},
{
"name": "DEV_ENV_1",
"value": "DEV_ENV_1"
},
{
"name": "DEFAULT_ENV",
"value": "DEFAULT_ENV_VALUE"
}
],
"secrets": [
{
"secretID": "456",
"mountPath": "/dev/dir/to/456/path"
},
{
"secretID": "123",
"mountPath": "/dev/dir/to/456/path"
},
{
"secretID": "567",
"mountPath": "/default/dir/to/567/path"
},
{
"secretUUID": "789",
"mountPath": "/default/dir/to/789/path"
}
],
"replicas": 1
}
}
.environments.default.config.env[0]is kept in the output array.config.env(at pos 2), while.environments.default.config.env[1]is dropped. The only reason I can imagine is, that the latter's.namevalue already occurs in the target array's items. But as its.valuevalue still differs, I cannot just check whole array items, yet I should keep it dynamic and not use field names. Then how? Same applies to.environments.default.config.secrets[1]where its.secretIDalready exists in the target, but.mountPathdoesn't.without hardcoding "env" or "secrets" anywhere in the code., so how else can I address.env.nameand.secrets.secretID? Do you expect me to use just.nameand.secretID, and query for them on any array item I can find?