1

I have a YAML file that I use in my Rails 4 application,

default: &default
  key: <%= JSON.parse(ENV[‘data’])[‘key'] %> 
  secret: <%= JSON.parse(ENV[‘data’])[‘secret’] %> 

development:
  key: 1234
  Secret: 1234

test:
  key: 1234
  Secret: 1234

qa:
  <<: *default

production:
  <<: *default

I would like to run a script to duplicate the block “qa” so that there is an identical “qa2” block beneath it. Ideally the end result would be

default: &default
  key: <%= JSON.parse(ENV[‘data’])[‘key'] %> 
  secret: <%= JSON.parse(ENV[‘data’])[‘secret’] %> 

development:
  key: 1234
  secret: 1234

test:
  key: 1234
  secret: 1234

qa:
  <<: *default

qa2:
  <<: *default

production:
  <<: *default

And was given this command

yq e '.production as $p | del(.production) | .qa2 = .qa | .production = $p' config/myfile.yml

But this produces

default: &default
  key: <%= JSON.parse(ENV['data'])['key'] %>
  secret: <%= JSON.parse(ENV['data'])['secret'] %>
development:
  key: 1234
  secret: 1234
test:
  key: 1234
  secret: 1234
qa:
  !!merge <<: *default
qa2:
  !!merge <<: *default
production:
  !!merge <<: 

Is there a way I can rewrite things so that I don’t have that annoying “!!merge” keyword inserted?

Dave
  • 15,639
  • 133
  • 442
  • 830
  • See [here](https://github.com/mikefarah/yq/issues/1083) and [here](https://mikefarah.gitbook.io/yq/usage/tips-and-tricks#yq-adds-a-merge-tag-automatically): it looks like that's the way it is. – Benjamin W. Apr 15 '22 at 22:12
  • From the [manual](https://mikefarah.gitbook.io/yq/operators/anchor-and-alias-operators): `yq` supports merge aliases (like `<<: *blah`) however this is no longer in the standard yaml spec (1.2) and so `yq` will automatically add the `!!merge` tag to these nodes as it is effectively a custom tag. – pmf Apr 16 '22 at 06:55
  • I'm open to using a solution other than yq if what I've presented is not standard yaml. – Dave Apr 18 '22 at 15:07
  • @Dave The merge keys are likely to be removed in the future YAML specifications (see https://stackoverflow.com/a/47203224/5291015) – Inian Apr 18 '22 at 15:18

1 Answers1

1

From the manual:

yq supports merge aliases (like <<: *blah) however this is no longer in the standard yaml spec (1.2) and so yq will automatically add the !!merge tag to these nodes as it is effectively a custom tag.

To remove this custom tag, perform your operations, then use (... | select(tag == "!!merge")) tag = "" as the final operation. It will untag any item that is tagged with !!merge.

yq e '
  .production as $p | del(.production) | .qa2 = .qa | .production = $p
  | (... | select(tag == "!!merge")) tag = ""
' config/myfile.yml
default: &default
  key: <%= JSON.parse(ENV[‘data’])[‘key'] %>
  secret: <%= JSON.parse(ENV[‘data’])[‘secret’] %>
development:
  key: 1234
  Secret: 1234
test:
  key: 1234
  Secret: 1234
qa:
  <<: *default
qa2:
  <<: *default
production:
  <<: *default

Alternatively, you can also directly untag .qa, .qa2 and .production only:

yq e '
  .production as $p | del(.production) | .qa2 = .qa | .production = $p
  | ((.qa, .qa2, .production) | ...) tag = ""
' config/myfile.yml

Tested with mikefarah/yq 4.14.1 and 4.20.2.

pmf
  • 24,478
  • 2
  • 22
  • 31