Skip to content

Instantly share code, notes, and snippets.

@tagomoris
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tagomoris/8f1bd08a7e9c363b9752 to your computer and use it in GitHub Desktop.
Save tagomoris/8f1bd08a7e9c363b9752 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rexml/document'
require 'set'
Property = Struct.new(:name, :value, :description, :final)
$PROP_NAMES = SortedSet.new
def read_document(path)
props = REXML::XPath.match(REXML::Document.new(File.open(path){|f| f.read}), "/configuration/property").map {|prop|
Property.new(
prop.elements["name"].text,
prop.elements["value"].text,
prop.elements["description"] ? prop.elements["description"].text : nil,
prop.elements["final"] ? prop.elements["final"].text : nil
)
}
props_map = {}
props.each do |p|
$PROP_NAMES << p.name
props_map[p.name] = p
end
props_map
end
def printlines(prefix, str)
str.each_line do |line|
puts "#{prefix}#{line.chomp}"
end
end
def element(p, element_sym)
if p.send(element_sym).nil?
(" " * 4) + "<#{element_sym}/>"
else
(" " * 4) + "<#{element_sym}>#{p.send(element_sym)}</#{element_sym}>"
end
end
def write_property(p)
str = ""
str << " <property>\n"
str << element(p, :name) + "\n"
str << element(p, :value) + "\n"
str << element(p, :description) + "\n" unless p.description.nil?
str << element(p, :final) + "\n" unless p.final.nil?
str << " </property>\n\n"
str
end
def description_equal(desc1, desc2)
if desc1.nil? || desc2.nil?
return desc1 == desc2
end
desc1 == desc2 || desc1.lines.map(&:strip).join('') == desc2.lines.map(&:strip).join('')
end
def write_property_diff(p1, p2)
printlines(" ", " <property>")
printlines(" ", element(p1, :name))
if p1.value == p2.value
printlines(" ", element(p1, :value))
else
printlines("-", element(p1, :value))
printlines("+", element(p2, :value))
end
if p1.final != p2.final
printlines("-", element(p1, :final))
printlines("+", element(p2, :final))
end
unless description_equal(p1.description, p2.description)
printlines("-", element(p1, :description))
printlines("+", element(p2, :description))
end
printlines(" ", " </property>")
puts " "
end
def diff(p1, p2)
if p1.nil? && p2.nil?
raise "BUG: both are nil"
elsif p1.nil?
printlines("+", write_property(p2))
elsif p2.nil?
printlines("-", write_property(p1))
elsif p1.name == p2.name && p1.value == p2.value && description_equal(p1.description, p2.description) && p1.final == p2.final
return
else
raise "BUG: property name mismatch, #{p1.name}, #{p2.name}" unless p1.name == p2.name
write_property_diff(p1, p2)
end
end
doc1 = read_document(ARGV[0])
doc2 = read_document(ARGV[1])
puts "--- #{File.basename(ARGV[0])}"
puts "+++ #{File.basename(ARGV[1])}"
puts "<configuration>"
puts ""
$PROP_NAMES.each do |name|
diff doc1[name], doc2[name]
end
puts "</configuration>"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment