smart_diff 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # SmartDiff
2
+
3
+ This is a port to Ruby of part of @yinwang0's [psydiff](https://github.com/yinwang0/psydiff). Specifically, I've ported the htmlizer part of his app, which converts a semantic diff into an html page which can be viewed in a webbrowser to make visual the information contained in the diff. @yinwang0
4
+ has written extensively about semantic diffing [on his blog](http://yinwang0.wordpress.com/2012/01/03/ydiff/) and also about [psydiff](http://yinwang0.wordpress.com/2013/07/06/psydiff/).
5
+
6
+ I created this port to demonstrate the use of the NodeDiff classes
7
+ I recently added to [JRubyParser](https://github.com/jruby/jruby-parser) and
8
+ to serve as an example of using it. I should make clear that JRubyParser and
9
+ said NodeDiff classes are entirely unrelated to psydiff, except that they do
10
+ something quite similar (create a diff of source code based on the AST rather than comparing the text directly).
11
+
12
+ This application should especially serve as an example of using the subdiff's
13
+ produced by NodeDiff to improve the quality of the output. See `bin/smart_diff`
14
+ .
15
+
16
+ ## Install
17
+
18
+ ```
19
+ $ jruby -S gem install smart_diff
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ Run `smart_diff` along with the paths to two versions of a ruby source file.
25
+
26
+ smart_diff example/bar.rb example/foo.rb
27
+
28
+ This will output an html file you can open in your browser. Check out `foo.rb-bar.rb.html` for a sample of the output.
29
+
30
+ LICENSE
31
+
32
+ Copyright (C) 2011-2013 Yin Wang
33
+
34
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
35
+
36
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
37
+
38
+ You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "rspec/core/rake_task"
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ desc "Run specs"
6
+ RSpec::Core::RakeTask.new do |r|
7
+ r.ruby_opts = "-J-ea -Ilib"
8
+ end
9
+
10
+ desc "Build gem"
11
+ task :build_gem => [:spec, :build] do
12
+ puts "Building gem with Bundler"
13
+ end
data/bin/smart_diff ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/smart_diff"
4
+ require_relative "../lib/smart_diff/htmlize"
5
+
6
+ file_path1 = ARGV[0]
7
+ file_path2 = ARGV[1]
8
+
9
+ puts "Creating Diff from #{file_path1} and #{file_path2}"
10
+
11
+ rd = SmartDiff.new(file_path1, file_path2)
12
+
13
+ nd = rd.node_diff.to_a
14
+
15
+ # Subdiffs use levenschtein distances to match up nodes. This won't work on
16
+ # the full diff, because it has too many chances to create false positives.
17
+ # However, within a subdiff, it can be pretty accurate because its less
18
+ # likely to have many highly similar nodes. Here's an example of using those
19
+ # subdiffs to improve the diffing results.
20
+
21
+ puts "Examining subdiffs to improve results."
22
+
23
+ # Gather up subdiffs
24
+
25
+ subs = []
26
+
27
+ nd.each do |d|
28
+ if d.subdiff
29
+ d.subdiff.each do |s|
30
+ subs << s
31
+ end
32
+ end
33
+ end
34
+
35
+ # Go through our diff, removing any diff which matches a subdiff
36
+ # We create a few nils in the process, so we strip those out at the end
37
+
38
+ complete = nd.map do |dd|
39
+ subs.each do |c|
40
+ if dd.old_node && c.old_node and !dd.new_node && c.new_node
41
+ if dd.old_node.isSame(c.old_node)
42
+ dd.old_node = nil
43
+ end
44
+ elsif dd.new_node && c.new_node and !dd.old_node && c.old_node
45
+ if dd.new_node.isSame(c.new_node)
46
+ dd.new_node = nil
47
+ end
48
+ end
49
+ end
50
+ dd unless dd.new_node == nil && dd.old_node == nil
51
+ end
52
+
53
+ complete.compact!
54
+
55
+ # Add all the subdiffs onto the end of our list of diffs
56
+ # We need them at the end so later we can make sure we are
57
+ # not creating nested anchor tags.
58
+
59
+ subs.each do |c|
60
+ complete << c
61
+ end
62
+
63
+
64
+ puts "Creating html output."
65
+
66
+ html = Htmlize.new
67
+ output = html.create_html(complete, file_path2, file_path1, rd.code_two, rd.code_one)
68
+
69
+ puts "Output complete. Try opening #{output} in your browser."