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 +38 -0
- data/Rakefile +13 -0
- data/bin/smart_diff +69 -0
- data/doc/Htmlize.html +1209 -0
- data/doc/SmartDiff.html +790 -0
- data/doc/Tag.html +484 -0
- data/doc/Utils.html +370 -0
- data/doc/_index.html +149 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +338 -0
- data/doc/file.README.html +127 -0
- data/doc/file_list.html +55 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +127 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +178 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +250 -0
- data/doc/top-level-namespace.html +114 -0
- data/example/bar.rb +52 -0
- data/example/foo.rb +51 -0
- data/foo.rb-bar.rb.html +498 -0
- data/lib/smart_diff/htmlize.rb +181 -0
- data/lib/smart_diff/utils.rb +29 -0
- data/lib/smart_diff.rb +49 -0
- data/spec/smart_diff/htmlize_spec.rb +33 -0
- data/spec/smart_diff/utils_spec.rb +34 -0
- data/spec/smart_diff_spec.rb +31 -0
- data/web/diff.css +96 -0
- data/web/nav.js +275 -0
- metadata +133 -0
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."
|