Imported Upstream version 3.1.0
Abhijith PA
6 years ago
0 | == 3.1.0 == | |
1 | Side by side diffs. Thanks Runar Skaare Tveiten! | |
2 | ||
0 | 3 | == 3.0.5 == |
1 | 4 | Improve performance when generating html output (with inline highlighting) on |
2 | 5 | long lines. Thanks Jason Barnabe! |
0 | Diffy - Easy Diffing With Ruby [![Build Status](https://secure.travis-ci.org/samg/diffy.png)](http://travis-ci.org/samg/diffy) | |
0 | Diffy - Easy Diffing With Ruby [![Build Status](https://travis-ci.org/samg/diffy.svg?branch=master)](https://travis-ci.org/samg/diffy) | |
1 | 1 | ============================ |
2 | 2 | |
3 | 3 | Need diffs in your ruby app? Diffy has you covered. It provides a convenient |
29 | 29 | |
30 | 30 | ###on Windows: |
31 | 31 | |
32 | 1. ensure that you have a working `which` and `diff` on your machine and on | |
33 | your search path. | |
34 | ||
35 | There are two options: | |
36 | ||
37 | 1. install unxutils <http://sourceforge.net/projects/unxutils> | |
32 | 1. Ensure that you have a working `diff` on your machine and in your search path. | |
33 | ||
34 | There are several options: | |
35 | ||
36 | 1. Install [Diff::LCS](https://github.com/halostatue/diff-lcs), which includes `ldiff`. [RSpec](https://www.relishapp.com/rspec/docs/gettingstarted) | |
37 | depends on Diff::LCS so you may already have it installed. | |
38 | ||
39 | 1. If you're using [RubyInstaller](http://rubyinstaller.org), install the [devkit](http://rubyinstaller.org/add-ons/devkit). | |
40 | ||
41 | 1. Install unxutils <http://sourceforge.net/projects/unxutils> | |
38 | 42 | |
39 | 43 | note that these tools contain diff 2.7 which has a different handling |
40 | 44 | of whitespace in the diff results. This makes Diffy spec tests |
41 | 45 | yielding one fail on Windows. |
42 | 46 | |
43 | 2. install these two individually from the gnuwin32 project | |
47 | 1. Install these two individually from the gnuwin32 project | |
44 | 48 | <http://gnuwin32.sourceforge.net/> |
45 | 49 | |
46 | 50 | note that this delivers diff 2.8 which makes Diffy spec pass |
47 | 51 | even on Windows. |
48 | 52 | |
49 | 53 | |
50 | 2. install the gem by | |
54 | 2. Install the gem by | |
51 | 55 | |
52 | 56 | gem install diffy |
53 | 57 | |
121 | 125 | .diff li.diff-comment { display: none; } |
122 | 126 | .diff li.diff-block-info { background: none repeat scroll 0 0 gray; } |
123 | 127 | |
128 | ||
129 | There's also a colorblind-safe version of the pallete provided in `Diffy::CSS_COLORBLIND_1`. | |
130 | ||
131 | ||
132 | Side-by-side comparisons | |
133 | ------------------------ | |
134 | ||
135 | Side-by-side comparisons, or split views as called by some, are supported by | |
136 | using the `Diffy::SplitDiff` class. This class takes a diff returned from | |
137 | `Diffy::Diff` and splits it in two parts (or two sides): left and right. The | |
138 | left side represents deletions while the right side represents insertions. | |
139 | ||
140 | The class is used as follows: | |
141 | ||
142 | ``` | |
143 | Diffy::SplitDiff.new(string1, string2, options = {}) | |
144 | ``` | |
145 | ||
146 | The optional options hash is passed along to the main `Diff::Diff` class, so | |
147 | all default options such as full diff output are supported. The output format | |
148 | may be changed by passing the format with the options hash (see below), and all | |
149 | default formats are supported. | |
150 | ||
151 | Unlinke `Diffy::Diff`, `Diffy::SplitDiff` does not use `#to_s` to output | |
152 | the resulting diff. Instead, two self-explanatory methods are used to output | |
153 | the diff; `#left` and `#right`. Using the earlier example, this is what they | |
154 | look like in action: | |
155 | ||
156 | ``` | |
157 | >> puts Diffy::SplitDiff.new(string1, string2).left | |
158 | -Hello how are you | |
159 | I'm fine | |
160 | -That's great | |
161 | ``` | |
162 | ||
163 | ``` | |
164 | >> puts Diffy::SplitDiff.new(string1, string2).right | |
165 | +Hello how are you? | |
166 | I'm fine | |
167 | +That's swell | |
168 | ``` | |
169 | ||
170 | ### Changing the split view output format | |
171 | ||
172 | The output format may be changed by passing the format with the options hash: | |
173 | ||
174 | ``` | |
175 | Diffy::SplitDiff.new(string1, string2, :format => :html) | |
176 | ``` | |
177 | ||
178 | This will result in the following: | |
179 | ||
180 | ``` | |
181 | >> puts Diffy::SplitDiff.new(string1, string2, :format => :html).left | |
182 | <div class="diff"> | |
183 | <ul> | |
184 | <li class="del"><del>Hello how are you</del></li> | |
185 | <li class="unchanged"><span>I'm fine</span></li> | |
186 | <li class="del"><del>That's <strong>great</strong></del></li> | |
187 | </ul> | |
188 | </div> | |
189 | ``` | |
190 | ||
191 | ``` | |
192 | >> puts Diffy::SplitDiff.new(string1, string2, :format => :html).right | |
193 | <div class="diff"> | |
194 | <ul> | |
195 | <li class="ins"><ins>Hello how are you<strong>?</strong></ins></li> | |
196 | <li class="unchanged"><span>I'm fine</span></li> | |
197 | <li class="ins"><ins>That's <strong>swell</strong></ins></li> | |
198 | </ul> | |
199 | </div> | |
200 | ``` | |
201 | ||
202 | ||
124 | 203 | Other Diff Options |
125 | 204 | ------------------ |
126 | 205 |
13 | 13 | .diff li.diff-comment { display: none; } |
14 | 14 | .diff li.diff-block-info { background: none repeat scroll 0 0 gray; } |
15 | 15 | STYLE |
16 | ||
17 | CSS_COLORBLIND_1 = <<-STYLE | |
18 | .diff{overflow:auto;} | |
19 | .diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0;display:table;width:100%;} | |
20 | .diff del, .diff ins{display:block;text-decoration:none;} | |
21 | .diff li{padding:0; display:table-row;margin: 0;height:1em;} | |
22 | .diff li.ins{background:#ddf; color:#008} | |
23 | .diff li.del{background:#fee; color:#b00} | |
24 | .diff li:hover{background:#ffc} | |
25 | /* try 'whitespace:pre;' if you don't want lines to wrap */ | |
26 | .diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;} | |
27 | .diff del strong{font-weight:normal;background:#fcc;} | |
28 | .diff ins strong{font-weight:normal;background:#99f;} | |
29 | .diff li.diff-comment { display: none; } | |
30 | .diff li.diff-block-info { background: none repeat scroll 0 0 gray; } | |
31 | STYLE | |
32 | ||
16 | 33 | end |
50 | 50 | |
51 | 51 | if WINDOWS |
52 | 52 | # don't use open3 on windows |
53 | cmd = "\"#{diff_bin}\" #{diff_options.join(' ')} #{paths.map{|s| "\"#{s}\""}.join(' ')}" | |
53 | cmd = sprintf '"%s" %s %s', diff_bin, diff_options.join(' '), paths.map { |s| %("#{s}") }.join(' ') | |
54 | 54 | diff = `#{cmd}` |
55 | 55 | else |
56 | 56 | diff = Open3.popen3(diff_bin, *(diff_options + paths)) { |i, o, e| o.read } |
141 | 141 | def diff_bin |
142 | 142 | return @@bin if @@bin |
143 | 143 | |
144 | @@bin ||= "" | |
145 | if WINDOWS | |
146 | @@bin = `which diff.exe`.chomp if @@bin.empty? | |
144 | if @@bin = ENV['DIFFY_DIFF'] | |
145 | # system() trick from Minitest | |
146 | raise "Can't execute diff program '#@@bin'" unless system(@@bin, __FILE__, __FILE__) | |
147 | return @@bin | |
147 | 148 | end |
148 | @@bin = `which diff`.chomp if @@bin.empty? | |
149 | 149 | |
150 | if @@bin.empty? | |
150 | diffs = ['diff', 'ldiff'] | |
151 | diffs.first << '.exe' if WINDOWS # ldiff does not have exe extension | |
152 | @@bin = diffs.find { |name| system(name, __FILE__, __FILE__) } | |
153 | ||
154 | if @@bin.nil? | |
151 | 155 | raise "Can't find a diff executable in PATH #{ENV['PATH']}" |
152 | 156 | end |
157 | ||
153 | 158 | @@bin |
154 | 159 | end |
155 | 160 |
0 | module Diffy | |
1 | class SplitDiff | |
2 | def initialize(left, right, options = {}) | |
3 | @format = options[:format] || Diffy::Diff.default_format | |
4 | ||
5 | formats = Format.instance_methods(false).map { |x| x.to_s } | |
6 | unless formats.include?(@format.to_s) | |
7 | fail ArgumentError, "Format #{format.inspect} is not a valid format" | |
8 | end | |
9 | ||
10 | @diff = Diffy::Diff.new(left, right, options).to_s(@format) | |
11 | @left_diff, @right_diff = split | |
12 | end | |
13 | ||
14 | %w(left right).each do |direction| | |
15 | define_method direction do | |
16 | instance_variable_get("@#{direction}_diff") | |
17 | end | |
18 | end | |
19 | ||
20 | private | |
21 | ||
22 | def split | |
23 | [split_left, split_right] | |
24 | end | |
25 | ||
26 | def split_left | |
27 | case @format | |
28 | when :color | |
29 | @diff.gsub(/\033\[32m\+(.*)\033\[0m\n/, '') | |
30 | when :html, :html_simple | |
31 | @diff.gsub(%r{\s+<li class="ins"><ins>(.*)</ins></li>}, '') | |
32 | when :text | |
33 | @diff.gsub(/^\+(.*)\n/, '') | |
34 | end | |
35 | end | |
36 | ||
37 | def split_right | |
38 | case @format | |
39 | when :color | |
40 | @diff.gsub(/\033\[31m\-(.*)\033\[0m\n/, '') | |
41 | when :html, :html_simple | |
42 | @diff.gsub(%r{\s+<li class="del"><del>(.*)</del></li>}, '') | |
43 | when :text | |
44 | @diff.gsub(/^-(.*)\n/, '') | |
45 | end | |
46 | end | |
47 | end | |
48 | end |
8 | 8 | require File.join(File.dirname(__FILE__), 'diffy', 'format') |
9 | 9 | require File.join(File.dirname(__FILE__), 'diffy', 'html_formatter') |
10 | 10 | require File.join(File.dirname(__FILE__), 'diffy', 'diff') |
11 | require File.join(File.dirname(__FILE__), 'diffy', 'split_diff') | |
11 | 12 | require File.join(File.dirname(__FILE__), 'diffy', 'css') |
0 | 0 | --- !ruby/object:Gem::Specification |
1 | 1 | name: diffy |
2 | 2 | version: !ruby/object:Gem::Version |
3 | version: 3.0.6 | |
3 | version: 3.1.0 | |
4 | 4 | platform: ruby |
5 | 5 | authors: |
6 | 6 | - Sam Goldstein |
7 | 7 | autorequire: |
8 | 8 | bindir: bin |
9 | 9 | cert_chain: [] |
10 | date: 2014-07-25 00:00:00.000000000 Z | |
10 | date: 2015-12-17 00:00:00.000000000 Z | |
11 | 11 | dependencies: |
12 | 12 | - !ruby/object:Gem::Dependency |
13 | 13 | name: rake |
59 | 59 | - lib/diffy/diff.rb |
60 | 60 | - lib/diffy/format.rb |
61 | 61 | - lib/diffy/html_formatter.rb |
62 | - lib/diffy/split_diff.rb | |
62 | 63 | - lib/diffy/version.rb |
63 | 64 | - spec/demo_app.rb |
64 | 65 | - spec/diffy_spec.rb |
82 | 83 | version: '0' |
83 | 84 | requirements: [] |
84 | 85 | rubyforge_project: |
85 | rubygems_version: 2.2.2 | |
86 | rubygems_version: 2.4.5.1 | |
86 | 87 | signing_key: |
87 | 88 | specification_version: 4 |
88 | 89 | summary: A convenient way to diff string in ruby |
587 | 587 | end |
588 | 588 | end |
589 | 589 | |
590 | describe Diffy::SplitDiff do | |
591 | before do | |
592 | ::Diffy::Diff.default_options.merge!(:diff => '-U 10000') | |
593 | end | |
594 | ||
595 | it "should fail with invalid format" do | |
596 | expected_fail = expect do | |
597 | Diffy::SplitDiff.new("lorem\n", "ipsum\n", :format => :fail) | |
598 | end | |
599 | expected_fail.to raise_error(ArgumentError) | |
600 | end | |
601 | ||
602 | describe "#left" do | |
603 | it "should only highlight deletions" do | |
604 | string1 = "lorem\nipsum\ndolor\nsit amet\n" | |
605 | string2 = "lorem\nipsumdolor\nsit amet\n" | |
606 | expect(Diffy::SplitDiff.new(string1, string2).left).to eq <<-TEXT | |
607 | lorem | |
608 | -ipsum | |
609 | -dolor | |
610 | sit amet | |
611 | TEXT | |
612 | end | |
613 | ||
614 | it "should also format left diff as html" do | |
615 | string1 = "lorem\nipsum\ndolor\nsit amet\n" | |
616 | string2 = "lorem\nipsumdolor\nsit amet\n" | |
617 | expect(Diffy::SplitDiff.new(string1, string2, :format => :html).left).to eq <<-HTML | |
618 | <div class="diff"> | |
619 | <ul> | |
620 | <li class="unchanged"><span>lorem</span></li> | |
621 | <li class="del"><del>ipsum<strong></strong></del></li> | |
622 | <li class="del"><del><strong></strong>dolor</del></li> | |
623 | <li class="unchanged"><span>sit amet</span></li> | |
624 | </ul> | |
625 | </div> | |
626 | HTML | |
627 | end | |
628 | end | |
629 | ||
630 | describe "#right" do | |
631 | it "should only highlight insertions" do | |
632 | string1 = "lorem\nipsum\ndolor\nsit amet\n" | |
633 | string2 = "lorem\nipsumdolor\nsit amet\n" | |
634 | expect(Diffy::SplitDiff.new(string1, string2).right).to eq <<-TEXT | |
635 | lorem | |
636 | +ipsumdolor | |
637 | sit amet | |
638 | TEXT | |
639 | end | |
640 | ||
641 | it "should also format right diff as html" do | |
642 | string1 = "lorem\nipsum\ndolor\nsit amet\n" | |
643 | string2 = "lorem\nipsumdolor\nsit amet\n" | |
644 | expect(Diffy::SplitDiff.new(string1, string2, :format => :html).right).to eq <<-HTML | |
645 | <div class="diff"> | |
646 | <ul> | |
647 | <li class="unchanged"><span>lorem</span></li> | |
648 | <li class="ins"><ins>ipsumdolor</ins></li> | |
649 | <li class="unchanged"><span>sit amet</span></li> | |
650 | </ul> | |
651 | </div> | |
652 | HTML | |
653 | end | |
654 | end | |
655 | end | |
656 | ||
590 | 657 | describe 'Diffy::CSS' do |
591 | 658 | it "should be some css" do |
592 | 659 | expect(Diffy::CSS).to include 'diff{overflow:auto;}' |