3 def self.diff_files(old_filename, new_filename)
5 ScratchDir.new do |old_dir|
6 ScratchDir.new do |new_dir|
7 old_buffer = File.new(old_filename).read
8 old_polyglot = Ohcount::Detector.detect(SimpleFileContext.new(old_filename))
9 Ohcount::Parser.parse_to_dir(:dir => old_dir,
10 :buffer => old_buffer,
11 :polyglot => old_polyglot)
12 new_buffer = File.new(new_filename).read
13 new_polyglot = Ohcount::Detector.detect(SimpleFileContext.new(new_filename))
14 Ohcount::Parser.parse_to_dir(:dir => new_dir,
15 :buffer => new_buffer,
16 :polyglot => new_polyglot)
17 langs = diff_sloc_dirs(old_dir, new_dir)
23 def self.blank_diffs(new_file, old_file)
24 # blanks are stored as a simple string
25 old_blanks = new_blanks = 0
26 if old_file != "/dev/null" && FileTest.file?(old_file)
27 File.open(old_file) do |io|
28 old_blanks = io.read.to_i
31 if new_file != "/dev/null" && FileTest.file?(new_file)
32 File.open(new_file) do |io|
33 new_blanks = io.read.to_i
36 blanks_changed = new_blanks - old_blanks
37 blanks_added = blanks_changed > 0 ? blanks_changed : 0
38 blanks_removed = blanks_changed < 0 ? -blanks_changed : 0
39 [blanks_added, blanks_removed]
43 def self.get_langs(dir)
46 Dir.foreach(dir) do |l|
47 next if [".", ".."].include?(l)
49 Dir.foreach(dir + "/" + l) do |s|
50 next if [".", ".."].include?(s)
57 def self.diff_sloc_dirs(old_dir, new_dir)
58 # figure out the superset of all languages and semantics we're dealing with (on old and new)
60 langs.merge!(get_langs(old_dir))
61 langs.merge!(get_langs(new_dir))
63 # now go through each and tally up the added/removed
65 langs.each do |lang, semantics|
66 next if lang == "_file" # this is a special case...
67 sloc_info = SlocInfo.new(lang)
69 semantics.each_key do |s|
70 old_file = old_dir ? File.join(old_dir, lang, s) : '/dev/null'
71 new_file = new_dir ? File.join(new_dir, lang, s) : '/dev/null'
73 sloc_info.blanks_added, sloc_info.blanks_removed = blank_diffs(new_file, old_file)
75 added_removed = diff_file(old_file, new_file)
78 sloc_info.code_added, sloc_info.code_removed = added_removed
80 sloc_info.comments_added, sloc_info.comments_removed = added_removed
82 raise RuntimeError.new("unknown semantic: #{ s }")
86 sloc_infos << sloc_info unless sloc_info.empty?
89 # sort them -- nice thing to do
90 sloc_infos.sort do |a,b|
91 a.language <=> b.language
95 def self.diff_file(old, new)
98 if FileTest.file?(old) == false
99 # original file doesn't exist -> return all new lines as added
100 added = `cat '#{ new }' | wc -l`.strip.to_i
101 elsif FileTest.file?(new) == false
102 # new file doesn't exist -> return all old lines as deleted
103 removed = `cat '#{ old }' | wc -l`.strip.to_i
105 cmd = "diff -d --normal --suppress-common-lines --new-file '#{old}' '#{new}' | grep '^>' | wc -l"
106 added = `#{cmd}`.to_i
107 cmd = "diff -d --normal --suppress-common-lines --new-file '#{old}' '#{new}' | grep '^<' | wc -l"
108 removed = `#{cmd}`.to_i