1

Let's assume I have a config/secrets.yml file that contains:

development:
  app_name: MyApp
  secret: <%= ENV['SECRET_VALUE'] %>

If I set SECRET_VALUE with a newline, it will break. E.g:

export SECRET_VALUE=$(printf "hello\nworld")

Then when I start my rail application I get this error:

/usr/local/lib/ruby/3.0.0/psych.rb:457:in 'parse': (<unknown>): could not find expected ':' while scanning a simple key at line 4 column 1 (Psych::SyntaxError)

While debugging the issue, I realized that the literal value of ENV['SECRET_VALUE'] is added to the yaml file before parsing it. That means if I wanted to achieve what I'm trying to do, I would have to do something like:

export SECRET_VALUE=$(printf "|\n hello\n world")

This works but this is very ugly and I can't be the only one who think this behaviour is absurd?? Is there a better way to do this?

EDIT:

I tried adding quotes around the value:

development:
  app_name: MyApp
  secret: "<%= ENV['SECRET_VALUE'] %>"

It "works" but the newline gets removed from the string...

root@4e4431bae32e:/app# rails console
Loading development environment (Rails 7.0.3)
irb(main):001:0> puts ENV['SECRET_VALUE']
hello
world
=> nil
irb(main):002:0> puts Rails.application.secrets[:secret]
hello world
=> nil

It's important that the newline remains for my use case.

MyUsername112358
  • 1,320
  • 14
  • 39
  • See https://stackoverflow.com/a/21699210. This really doesn't have that much to do with Rails and is rather just down to how YAML works. – max Jul 15 '22 at 18:52
  • I understand how yaml works, I even gave example of how I could make it works. It's the fact that the parser (psych) literally adds the value to the yaml file before parsing it that is the issue. This is completely absurd for a parser to do that. – MyUsername112358 Jul 17 '22 at 14:19
  • You have it completely backwards. The file is sent through ERB which is a templating engine and the result after interpolation is sent to psych. Psych is really just a completely standard YAML parser. So as suggested the issue is really just printing the string in Ruby in a format that is interpreted correctly in YAML. – max Jul 26 '22 at 20:56
  • https://github.com/rails/rails/blob/f2d9316ba965e150ad04596085ee10eea4f58d3e/activesupport/lib/active_support/configuration_file.rb#L3 – max Jul 26 '22 at 21:07

1 Answers1

1

You can use an escaped quoted string. YAML's string format is similar enough to a superset of Ruby's for String#dump to work:

development:
  app_name: MyApp
  secret: <%= ENV['SECRET_VALUE'].dump %>
Pierre Carrier
  • 396
  • 2
  • 9