Skip to content

Instantly share code, notes, and snippets.

@tomoasleep
Last active August 8, 2022 06:20
Show Gist options
  • Save tomoasleep/3f141d3d6ee9130353be92c46ee06357 to your computer and use it in GitHub Desktop.
Save tomoasleep/3f141d3d6ee9130353be92c46ee06357 to your computer and use it in GitHub Desktop.
YAML の差分を JSON Patch (https://jsonpatch.com/) として生成してくれるスクリプト

Usage

ruby ./yaml_to_json_patch.rb OLD_YAML_FILE_PATH NEW_YAML_FILE_PATH
require 'yaml'
require 'json'
require 'set'
OLD_FILE = ARGV[0]
NEW_FILE = ARGV[1]
old_yaml = YAML.load_file(OLD_FILE)
new_yaml = YAML.load_file(NEW_FILE)
def flatten(hash_or_array)
new_hash = Hash.new
dict = hash_or_array.is_a?(Array) ? hash_or_array.map.with_index { |v, k| [k.to_s, v] }.to_h : hash_or_array
dict.each do |(key, value)|
if value.is_a?(Hash) || value.is_a?(Array)
flatten(value).each do |(k, v)|
new_hash["/#{key}#{k}"] = v
end
else
new_hash["/#{key}"] = value
end
end
new_hash
end
old_flatten_yaml = flatten(old_yaml)
new_flatten_yaml = flatten(new_yaml)
keys = Set.new(old_flatten_yaml.keys + new_flatten_yaml.keys)
patch = []
keys.each do |key|
if old_flatten_yaml[key].nil? && !new_flatten_yaml[key].nil?
patch << { 'op' => 'add', 'path' => key, 'value' => new_flatten_yaml[key] }
end
if !old_flatten_yaml[key].nil? && new_flatten_yaml[key].nil?
patch << { 'op' => 'remove', 'path' => key }
end
if old_flatten_yaml[key] != new_flatten_yaml[key]
patch << { 'op' => 'replace', 'path' => key, 'value' => new_flatten_yaml[key] }
end
end
puts patch.to_json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment