Skip to content

Instantly share code, notes, and snippets.

@nanki
Created February 22, 2012 09:31
Show Gist options
  • Save nanki/1883594 to your computer and use it in GitHub Desktop.
Save nanki/1883594 to your computer and use it in GitHub Desktop.
Calculate & display the differences among multiple files.
#!/usr/bin/env ruby
# Requirements:
# Ruby1.9
# gem 'ansi'
# gem 'text_layout'
# diff
# diffstat
require 'shellwords'
require 'ansi'
require 'text_layout'
class String
alias display_width_without_ansi display_width
def display_width
method(:display_width_without_ansi).unbind.bind(ANSI.unansi self).call
end
end
Filename = Struct.new :name, :index
class Diff < Struct.new(:inserted, :deleted, :modified)
def display_text(flag=true)
r = []
r << ANSI.color(inserted.to_s, flag ? :green : :red) unless inserted.zero?
r << ANSI.color(deleted.to_s, flag ? :red : :green) unless deleted.zero?
r.reverse! unless flag
r << modified.to_s unless modified.zero?
r.join("/")
end
end
files = ARGF.enum_for.map.with_index{|line, i| Filename.new line.strip, i}
r = Array.new(files.size){[]}
files.combination(2).each do |f1, f2|
diff = Diff.new(*`diff --strip-trailing-cr -du #{Shellwords.shellescape f1.name} #{Shellwords.shellescape f2.name} | diffstat -mt`.lines.to_a.last.split(",").map{|v|Integer(v) rescue 0}[0,3])
r[f1.index][f2.index] = diff.display_text(true)
r[f2.index][f1.index] = diff.display_text(false)
end
files.each do |file|
r[file.index][files.size] = {value:file.name, align: :left}
end
puts TextLayout::Table.new(r).layout
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment