Home > OS >  How do I prevent "yq" from replacing my texet wiht a "!!merge" statement?
How do I prevent "yq" from replacing my texet wiht a "!!merge" statement?

Time:04-23

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?

CodePudding user response:

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.

  • Related