Skip to content

Instantly share code, notes, and snippets.

@branch14
Created June 6, 2011 14:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save branch14/1010381 to your computer and use it in GitHub Desktop.
Save branch14/1010381 to your computer and use it in GitHub Desktop.
Interactively merge several YAML files into one
#!/usr/bin/env ruby
#
# synopsis
#
# ruby merge_locales.rb config/locales translations.yml
require 'yaml'
require 'rubygems'
require 'highline/import'
::Hash.class_eval do
class MergeConflict < StandardError; end
def deep_merge(other, &bloc)
other.keys.inject(dup) do |result, key|
begin
case result[key]
when Hash
if other[key].is_a?(Hash)
result[key] = result[key].deep_merge(other[key], &bloc)
result
else
raise MergeConflict
end
when nil then result.merge key => other[key]
else
raise MergeConflict
end
rescue MergeConflict
if bloc.nil?
result[key] = other[key]
else
result[key] = bloc.call(result, other, key)
end
result
end
end
end
end
result = ARGV.inject({}) do |result, path|
files = [path] if File.file?(path) && path.match(/\.yml$/)
files ||= Dir.glob( File.join(path, '**', '*.yml')).to_a
files.inject(result) do |inner_result, file|
warn "loading #{file}"
yaml = File.open(file) { |yf| YAML::load(yf) }
inner_result.deep_merge(yaml) do |res, other, key|
if res[key] == other[key]
res[key]
else
warn "Conflict on key: '#{key}'"
warn " 1. #{res[key].inspect}"
warn " 2. #{other[key].inspect}"
select = ask('')
case select
when '1' then res[key]
when '2' then other[key]
end
end
end
end
end
YAML.dump(result, STDOUT)
@munen
Copy link

munen commented Jun 7, 2011

Forked your Gist and pushed my changes to it. But I don't think that I can issue a pull request on your Gist.

@ozbillwang
Copy link

ozbillwang commented Oct 18, 2016

Compare with the yaml files before and after merged. Should be double or single quota?

<       - FromPort: '-1'
<         IpProtocol: '-1'

---
>       - FromPort: "-1"
>         IpProtocol: "-1"

Regarding yaml syntax (http://www.yaml.org/start.html), without quota is fine. But I prefer single quota.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment