Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/env ruby
- require "fileutils"
- require "getopts"
- ENV['LANG']="C"
- USAGE = <<USAGE
- usage: #$0 [options] dir1 dir2\n
- options:
- -f Force diffing. If not given, try to use cache under ~/.diffrb.
- -b Ignore changes in amount of white space.
- -B Ignore changes that just insert or delete blank lines.
- -N treat only file as present but empty in the other directory.
- -p Print diff(1) and exit.
- --change | --add | --delete
- Reports only change/add/delete. No two of these can't be given.
- --diff
- Reports as diff command to leads "| sh". Implies --change.
- --noprefix
- Do not print one-letter prefix A, C, nor D.
- USAGE
- opterr = getopts("fpbNB0", "change", "add", "delete", "help", "noprefix", "diff")
- if $OPT_diff
- $OPT_change = true
- $OPT_add, $OPT_delete = nil
- end
- if $OPT_change && $OPT_add or
- $OPT_change && $OPT_delete or
- $OPT_delete && $OPT_add
- abort USAGE
- end
- if ARGV.size != 2 or $OPT_help or !opterr
- abort USAGE
- end
- non_directory = ARGV.find_all{|d| !File.directory?(d)}
- if !non_directory.empty?
- non_directory.each{|d|
- STDERR.puts "#$0: #{d}: not a directory"
- }
- abort USAGE
- end
- $OPT_all = !$OPT_add && !$OPT_change && !$OPT_delete
- dir1, dir2 = ARGV.map{|i| i.dup}
- dir1.sub!(%r#/+$#, '')
- dir2.sub!(%r#/+$#, '')
- opts = "-q"
- opts << "b" if $OPT_b
- opts << "B" if $OPT_B
- opts << "N" if $OPT_N
- uopts = "-u"
- uopts << "b" if $OPT_b
- uopts << "B" if $OPT_B
- uopts << "N" if $OPT_N
- uopts << "0" if $OPT_0
- rcdir = ENV["HOME"]+"/.diffrb"
- fn = ARGV.map{|d| File.expand_path(d).gsub("/", "___")}.join("---")
- difffile = File.join(rcdir, fn+".txt")
- if !File.exist?(difffile) or $OPT_f
- FileUtils.mkdir_p(rcdir)
- STDERR.puts("# #$0: executing diff -qr #{dir1} #{dir2}")
- system("diff -qr #{dir1} #{dir2} > #{difffile}")
- end
- diff = File.read(difffile)
- if $OPT_p
- print diff
- exit
- end
- change = diff.scan(/Files #{Regexp::quote(dir1)}\/(.*?) and #{Regexp.quote(dir2)}\/\1 differ/u).flatten.sort
- deleted = diff.scan(/Only in #{Regexp.quote(dir1)}\/(\S+): (.+)$/u).map{|i| i.join("/")}.sort
- added = diff.scan(/Only in #{Regexp.quote(dir2)}\/(\S+): (.+)$/u).map{|i| i.join("/")}.sort
- if !$OPT_add and !$OPT_delete
- if $OPT_diff
- change.each{|i| puts %<diff #{uopts} "#{dir1}/#{i}" "#{dir2}/#{i}">}
- else
- change.each{|i| puts $OPT_noprefix ? i : "C #{i}"}
- end
- end
- if !$OPT_change and !$OPT_delete
- added.each{|i| puts $OPT_noprefix ? i : "A #{i}"}
- end
- if !$OPT_add and !$OPT_change
- deleted.each{|i| puts $OPT_noprefix ? i : "D #{i}"}
- end
Add Comment
Please, Sign In to add comment