Reputation: 13012
I have a yml file that I am using to store a list of stories I have added between releases.
I am using a rake task to dynamically update the version number based off what stories I have added to this file.
It is introducing a new process, so I created the following comment block this will help anyone commenting here to add stories in the right format:
# Version control file.
# Versions should be incremented as follows
#
# [X - major change] . [V - new feature] . [I - Bug fix / Small change]
#
# Update the undefined block with a one line readable description of what your story was about. example:
#
# undefined:
# stories:
# - "I - fixed spelling mistake"
# - "V - added import functionality"
# - "X - rebuilt the main dashboard"
#
The issue is after my rake task is done the job the file loses the comment block.
I pretty much load the YAML versions = YAML.load_file( 'doc/release.yml' )
and then once the logic is finished I File.open("doc/release.yml", 'w') { |f| YAML.dump(versions, f) }
Where versions
is the new updated hash. However, this removes the comment block to the file.
Other solutions I have found just modify existing lines.
Is there a way to open the file and adding the above without messing up the YAML beneath. Any help will be much appreciated.
Upvotes: 3
Views: 2379
Reputation: 178
I came up with this method of adding comments to my Hash before dumping out to yaml. I use this to initialize configuration files with embedded comments to document the configuration options. It's a limited solution. No in-Array comments, for example. But it'll work for simple cases.
cfg = {
c: 'This is a comment',
'foo' => 'bar',
'level2' => {
'level3' => {
'foo' => 'bar',
c1: 'This is a comment (line 1)',
c2: 'This is a comment (line 2)',
'foo2' => 'bar2',
},
},
}
YAML.dump(cfg).each_line do |l|
if l.match(/:c(\d+)?:/)
l.sub!(/:c(\d+)?:/, '#')
l.sub!(/(^\s*# )["']/, '\1')
l.sub!(/["']\s*$/, '')
end
puts l
end
Produces:
---
# This is a comment
foo: bar
level2:
level3:
foo: bar
# This is a comment (line 1)
# This is a comment (line 2)
foo2: bar2
Upvotes: 1
Reputation: 54253
Here's a possible solution.
require 'yaml'
versions_yaml = File.read('release.yml')
versions = YAML.load(versions_yaml)
comments = versions_yaml.scan(/^#.*?$/)
File.open("release2.yml", 'w') { |f|
f.puts comments
YAML.dump(versions, f)
}
puts File.read("release2.yml")
With release.yml :
# I'm a comment on first line
---
- 1
- 2
- 3
# I'm a comment somewhere in the middle
- - 4
- 5
it outputs :
# I'm a comment on first line
# I'm a comment somewhere in the middle
---
- 1
- 2
- 3
- - 4
- 5
Upvotes: 1
Reputation: 42207
That the comments are lost with a dump is unfortunatly normal. You have two options:
{ :a => 'b'}.to_yaml
, add the comments and with File.write
do the dump yourself, you could overwrite the normal
.dump method in YAML this wayUpvotes: 1