diff-lcs 1.4.4 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Contributing.md +3 -0
- data/History.md +219 -107
- data/License.md +6 -4
- data/Manifest.txt +15 -1
- data/Rakefile +81 -25
- data/bin/htmldiff +4 -4
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +2 -2
- data/lib/diff/lcs/block.rb +4 -4
- data/lib/diff/lcs/callbacks.rb +9 -7
- data/lib/diff/lcs/change.rb +19 -19
- data/lib/diff/lcs/htmldiff.rb +24 -16
- data/lib/diff/lcs/hunk.rb +35 -30
- data/lib/diff/lcs/internals.rb +24 -20
- data/lib/diff/lcs/ldiff.rb +37 -35
- data/lib/diff/lcs.rb +77 -75
- data/lib/diff-lcs.rb +1 -1
- data/spec/change_spec.rb +50 -50
- data/spec/diff_spec.rb +14 -14
- data/spec/fixtures/ldiff/output.diff.chef +4 -0
- data/spec/fixtures/ldiff/output.diff.chef-c +15 -0
- data/spec/fixtures/ldiff/output.diff.chef-e +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-f +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-u +9 -0
- data/spec/fixtures/ldiff/output.diff.chef2 +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-c +20 -0
- data/spec/fixtures/ldiff/output.diff.chef2-d +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-e +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-f +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-u +16 -0
- data/spec/fixtures/new-chef +4 -0
- data/spec/fixtures/new-chef2 +17 -0
- data/spec/fixtures/old-chef +4 -0
- data/spec/fixtures/old-chef2 +14 -0
- data/spec/hunk_spec.rb +19 -19
- data/spec/issues_spec.rb +48 -42
- data/spec/lcs_spec.rb +11 -11
- data/spec/ldiff_spec.rb +13 -11
- data/spec/patch_spec.rb +84 -84
- data/spec/sdiff_spec.rb +111 -109
- data/spec/spec_helper.rb +77 -76
- data/spec/traverse_balanced_spec.rb +191 -189
- data/spec/traverse_sequences_spec.rb +31 -33
- metadata +50 -23
- data/autotest/discover.rb +0 -3
data/Rakefile
CHANGED
@@ -1,63 +1,118 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "rubygems"
|
4
|
+
require "rspec"
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
require "hoe"
|
7
|
+
|
8
|
+
# This is required until https://github.com/seattlerb/hoe/issues/112 is fixed
|
9
|
+
class Hoe
|
10
|
+
def with_config
|
11
|
+
config = Hoe::DEFAULT_CONFIG
|
12
|
+
|
13
|
+
rc = File.expand_path("~/.hoerc")
|
14
|
+
homeconfig = load_config(rc)
|
15
|
+
config = config.merge(homeconfig)
|
16
|
+
|
17
|
+
localconfig = load_config(File.expand_path(File.join(Dir.pwd, ".hoerc")))
|
18
|
+
config = config.merge(localconfig)
|
19
|
+
|
20
|
+
yield config, rc
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_config(name)
|
24
|
+
File.exist?(name) ? safe_load_yaml(name) : {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def safe_load_yaml(name)
|
28
|
+
return safe_load_yaml_file(name) if YAML.respond_to?(:safe_load_file)
|
29
|
+
|
30
|
+
data = IO.binread(name)
|
31
|
+
YAML.safe_load(data, permitted_classes: [Regexp])
|
32
|
+
rescue
|
33
|
+
YAML.safe_load(data, [Regexp])
|
34
|
+
end
|
35
|
+
|
36
|
+
def safe_load_yaml_file(name)
|
37
|
+
YAML.safe_load_file(name, permitted_classes: [Regexp])
|
38
|
+
rescue
|
39
|
+
YAML.safe_load_file(name, [Regexp])
|
40
|
+
end
|
41
|
+
end
|
6
42
|
|
7
43
|
Hoe.plugin :bundler
|
8
44
|
Hoe.plugin :doofus
|
9
45
|
Hoe.plugin :gemspec2
|
10
46
|
Hoe.plugin :git
|
11
47
|
|
12
|
-
if RUBY_VERSION <
|
13
|
-
class Array
|
48
|
+
if RUBY_VERSION < "1.9"
|
49
|
+
class Array # :nodoc:
|
14
50
|
def to_h
|
15
51
|
Hash[*flatten(1)]
|
16
52
|
end
|
17
53
|
end
|
18
54
|
|
19
|
-
class Gem::Specification
|
20
|
-
def metadata=(*)
|
55
|
+
class Gem::Specification # :nodoc:
|
56
|
+
def metadata=(*)
|
57
|
+
end
|
21
58
|
|
22
|
-
def default_value(*)
|
59
|
+
def default_value(*)
|
60
|
+
end
|
23
61
|
end
|
24
62
|
|
25
|
-
class Object
|
63
|
+
class Object # :nodoc:
|
26
64
|
def caller_locations(*)
|
27
65
|
[]
|
28
66
|
end
|
29
67
|
end
|
30
68
|
end
|
31
69
|
|
32
|
-
_spec = Hoe.spec
|
33
|
-
developer(
|
70
|
+
_spec = Hoe.spec "diff-lcs" do
|
71
|
+
developer("Austin Ziegler", "halostatue@gmail.com")
|
34
72
|
|
35
|
-
require_ruby_version
|
73
|
+
require_ruby_version ">= 1.8"
|
36
74
|
|
37
|
-
self.history_file =
|
38
|
-
self.readme_file =
|
39
|
-
self.licenses = [
|
75
|
+
self.history_file = "History.md"
|
76
|
+
self.readme_file = "README.rdoc"
|
77
|
+
self.licenses = ["MIT", "Artistic-2.0", "GPL-2.0-or-later"]
|
40
78
|
|
41
|
-
|
42
|
-
|
43
|
-
extra_dev_deps << [
|
44
|
-
extra_dev_deps << [
|
45
|
-
extra_dev_deps << [
|
46
|
-
extra_dev_deps << [
|
47
|
-
extra_dev_deps << [
|
79
|
+
spec_extras[:metadata] = ->(val) { val["rubygems_mfa_required"] = "true" }
|
80
|
+
|
81
|
+
extra_dev_deps << ["hoe", ">= 3.0", "< 5"]
|
82
|
+
extra_dev_deps << ["hoe-doofus", "~> 1.0"]
|
83
|
+
extra_dev_deps << ["hoe-gemspec2", "~> 1.1"]
|
84
|
+
extra_dev_deps << ["hoe-git2", "~> 1.7"]
|
85
|
+
extra_dev_deps << ["hoe-rubygems", "~> 1.0"]
|
86
|
+
extra_dev_deps << ["rspec", ">= 2.0", "< 4"]
|
87
|
+
extra_dev_deps << ["rake", ">= 10.0", "< 14"]
|
88
|
+
extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"]
|
89
|
+
end
|
90
|
+
|
91
|
+
desc "Run all specifications"
|
92
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
93
|
+
rspec_dirs = %w[spec lib].join(":")
|
94
|
+
t.rspec_opts = ["-I#{rspec_dirs}"]
|
48
95
|
end
|
49
96
|
|
50
|
-
|
97
|
+
Rake::Task["spec"].actions.uniq! { |a| a.source_location }
|
98
|
+
|
99
|
+
# standard:disable Style/HashSyntax
|
100
|
+
task :default => :spec unless Rake::Task["default"].prereqs.include?("spec")
|
101
|
+
task :test => :spec unless Rake::Task["test"].prereqs.include?("spec")
|
102
|
+
# standard:enable Style/HashSyntax
|
103
|
+
|
104
|
+
if RUBY_VERSION >= "2.0" && RUBY_ENGINE == "ruby"
|
51
105
|
namespace :spec do
|
52
106
|
desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
|
53
107
|
task :coverage do
|
54
|
-
ENV[
|
55
|
-
Rake::Task[
|
108
|
+
ENV["COVERAGE"] = "yes"
|
109
|
+
Rake::Task["spec"].execute
|
56
110
|
end
|
57
111
|
end
|
58
112
|
end
|
59
113
|
|
60
114
|
task :ruby18 do
|
115
|
+
# standard:disable Layout/HeredocIndentation
|
61
116
|
puts <<-MESSAGE
|
62
117
|
You are starting a barebones Ruby 1.8 docker environment. You will need to
|
63
118
|
do the following:
|
@@ -70,5 +125,6 @@ do the following:
|
|
70
125
|
Don't forget to restore your Gemfile.lock after testing.
|
71
126
|
|
72
127
|
MESSAGE
|
128
|
+
# standard:enable Layout/HeredocIndentation
|
73
129
|
sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l"
|
74
130
|
end
|
data/bin/htmldiff
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#! /usr/bin/env ruby -w
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "diff/lcs"
|
5
|
+
require "diff/lcs/htmldiff"
|
6
6
|
|
7
7
|
begin
|
8
|
-
require
|
8
|
+
require "text/format"
|
9
9
|
rescue LoadError
|
10
10
|
Diff::LCS::HTMLDiff.can_expand_tabs = false
|
11
11
|
end
|
@@ -24,7 +24,7 @@ options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" }
|
|
24
24
|
htmldiff = Diff::LCS::HTMLDiff.new(left, right, options)
|
25
25
|
|
26
26
|
if ARGV[2]
|
27
|
-
File.open(ARGV[2],
|
27
|
+
File.open(ARGV[2], "w") do |f|
|
28
28
|
htmldiff.options[:output] = f
|
29
29
|
htmldiff.run
|
30
30
|
end
|
data/lib/diff/lcs/array.rb
CHANGED
data/lib/diff/lcs/backports.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
unless 0.respond_to?(:positive?)
|
4
|
-
class Fixnum #
|
4
|
+
class Fixnum # standard:disable Lint/UnifiedInteger
|
5
5
|
def positive?
|
6
|
-
self > 0
|
6
|
+
self > 0
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/diff/lcs/block.rb
CHANGED
@@ -25,13 +25,13 @@ class Diff::LCS::Block
|
|
25
25
|
def op
|
26
26
|
case [@remove.empty?, @insert.empty?]
|
27
27
|
when [false, false]
|
28
|
-
|
28
|
+
"!"
|
29
29
|
when [false, true]
|
30
|
-
|
30
|
+
"-"
|
31
31
|
when [true, false]
|
32
|
-
|
32
|
+
"+"
|
33
33
|
else # [true, true]
|
34
|
-
|
34
|
+
"^"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/diff/lcs/callbacks.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "diff/lcs/change"
|
4
4
|
|
5
|
-
module Diff::LCS
|
5
|
+
module Diff::LCS
|
6
6
|
# This callback object implements the default set of callback events,
|
7
7
|
# which only returns the event itself. Note that #finished_a and
|
8
8
|
# #finished_b are not implemented -- I haven't yet figured out where they
|
@@ -50,7 +50,9 @@ module Diff::LCS # rubocop:disable Style/Documentation
|
|
50
50
|
BalancedCallbacks = DefaultCallbacks
|
51
51
|
|
52
52
|
def self.callbacks_for(callbacks)
|
53
|
-
callbacks.new
|
53
|
+
callbacks.new
|
54
|
+
rescue
|
55
|
+
callbacks
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
@@ -107,7 +109,7 @@ class Diff::LCS::DiffCallbacks
|
|
107
109
|
# Returns the difference set collected during the diff process.
|
108
110
|
attr_reader :diffs
|
109
111
|
|
110
|
-
def initialize # :yields self
|
112
|
+
def initialize # :yields: self
|
111
113
|
@hunk = []
|
112
114
|
@diffs = []
|
113
115
|
|
@@ -131,11 +133,11 @@ class Diff::LCS::DiffCallbacks
|
|
131
133
|
end
|
132
134
|
|
133
135
|
def discard_a(event)
|
134
|
-
@hunk << Diff::LCS::Change.new(
|
136
|
+
@hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element)
|
135
137
|
end
|
136
138
|
|
137
139
|
def discard_b(event)
|
138
|
-
@hunk << Diff::LCS::Change.new(
|
140
|
+
@hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element)
|
139
141
|
end
|
140
142
|
|
141
143
|
def finish_hunk
|
@@ -302,7 +304,7 @@ class Diff::LCS::SDiffCallbacks
|
|
302
304
|
# Returns the difference set collected during the diff process.
|
303
305
|
attr_reader :diffs
|
304
306
|
|
305
|
-
def initialize
|
307
|
+
def initialize # :yields: self
|
306
308
|
@diffs = []
|
307
309
|
yield self if block_given?
|
308
310
|
end
|
data/lib/diff/lcs/change.rb
CHANGED
@@ -10,7 +10,7 @@ class Diff::LCS::Change
|
|
10
10
|
# (no change), '!' (changed), '<' (tail changes from first sequence), or
|
11
11
|
# '>' (tail changes from second sequence). The last two ('<>') are only
|
12
12
|
# found with Diff::LCS::diff and Diff::LCS::sdiff.
|
13
|
-
VALID_ACTIONS = %w
|
13
|
+
VALID_ACTIONS = %w[+ - = ! > <].freeze
|
14
14
|
|
15
15
|
def self.valid_action?(action)
|
16
16
|
VALID_ACTIONS.include? action
|
@@ -28,7 +28,7 @@ class Diff::LCS::Change
|
|
28
28
|
@action, @position, @element = *args
|
29
29
|
|
30
30
|
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
31
|
-
fail
|
31
|
+
fail "Invalid Position Type" unless @position.is_a? IntClass
|
32
32
|
end
|
33
33
|
|
34
34
|
def inspect(*_args)
|
@@ -39,7 +39,7 @@ class Diff::LCS::Change
|
|
39
39
|
[@action, @position, @element]
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
alias_method :to_ary, :to_a
|
43
43
|
|
44
44
|
def self.from_a(arr)
|
45
45
|
arr = arr.flatten(1)
|
@@ -49,7 +49,7 @@ class Diff::LCS::Change
|
|
49
49
|
when 3
|
50
50
|
Diff::LCS::Change.new(*(arr[0...3]))
|
51
51
|
else
|
52
|
-
fail
|
52
|
+
fail "Invalid change array format provided."
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -70,27 +70,27 @@ class Diff::LCS::Change
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def adding?
|
73
|
-
@action ==
|
73
|
+
@action == "+"
|
74
74
|
end
|
75
75
|
|
76
76
|
def deleting?
|
77
|
-
@action ==
|
77
|
+
@action == "-"
|
78
78
|
end
|
79
79
|
|
80
80
|
def unchanged?
|
81
|
-
@action ==
|
81
|
+
@action == "="
|
82
82
|
end
|
83
83
|
|
84
84
|
def changed?
|
85
|
-
@action ==
|
85
|
+
@action == "!"
|
86
86
|
end
|
87
87
|
|
88
88
|
def finished_a?
|
89
|
-
@action ==
|
89
|
+
@action == ">"
|
90
90
|
end
|
91
91
|
|
92
92
|
def finished_b?
|
93
|
-
@action ==
|
93
|
+
@action == "<"
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
@@ -115,8 +115,8 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
115
115
|
@action, @old_position, @old_element, @new_position, @new_element = *args
|
116
116
|
|
117
117
|
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
118
|
-
fail
|
119
|
-
fail
|
118
|
+
fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass)
|
119
|
+
fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass)
|
120
120
|
end
|
121
121
|
|
122
122
|
def to_a
|
@@ -127,7 +127,7 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
127
127
|
]
|
128
128
|
end
|
129
129
|
|
130
|
-
|
130
|
+
alias_method :to_ary, :to_a
|
131
131
|
|
132
132
|
def self.from_a(arr)
|
133
133
|
Diff::LCS::Change.from_a(arr)
|
@@ -139,15 +139,15 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
139
139
|
ea = event.to_a
|
140
140
|
|
141
141
|
case ea[0]
|
142
|
-
when
|
142
|
+
when "-"
|
143
143
|
ea[2][1] = nil
|
144
|
-
when
|
145
|
-
ea[0] =
|
144
|
+
when "<"
|
145
|
+
ea[0] = "-"
|
146
146
|
ea[2][1] = nil
|
147
|
-
when
|
147
|
+
when "+"
|
148
148
|
ea[1][1] = nil
|
149
|
-
when
|
150
|
-
ea[0] =
|
149
|
+
when ">"
|
150
|
+
ea[0] = "+"
|
151
151
|
ea[1][1] = nil
|
152
152
|
end
|
153
153
|
|
data/lib/diff/lcs/htmldiff.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cgi"
|
4
4
|
|
5
5
|
# Produce a simple HTML diff view.
|
6
6
|
class Diff::LCS::HTMLDiff
|
7
7
|
class << self
|
8
|
-
attr_accessor :can_expand_tabs
|
8
|
+
attr_accessor :can_expand_tabs # :nodoc:
|
9
9
|
end
|
10
10
|
self.can_expand_tabs = true
|
11
11
|
|
12
|
-
class Callbacks
|
12
|
+
class Callbacks # :nodoc:
|
13
13
|
attr_accessor :output
|
14
14
|
attr_accessor :match_class
|
15
15
|
attr_accessor :only_a_class
|
@@ -19,14 +19,14 @@ class Diff::LCS::HTMLDiff
|
|
19
19
|
@output = output
|
20
20
|
options ||= {}
|
21
21
|
|
22
|
-
@match_class = options[:match_class] ||
|
23
|
-
@only_a_class = options[:only_a_class] ||
|
24
|
-
@only_b_class = options[:only_b_class] ||
|
22
|
+
@match_class = options[:match_class] || "match"
|
23
|
+
@only_a_class = options[:only_a_class] || "only_a"
|
24
|
+
@only_b_class = options[:only_b_class] || "only_b"
|
25
25
|
end
|
26
26
|
|
27
27
|
def htmlize(element, css_class)
|
28
|
-
element =
|
29
|
-
%
|
28
|
+
element = " " if element.empty?
|
29
|
+
%(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
|
30
30
|
end
|
31
31
|
private :htmlize
|
32
32
|
|
@@ -46,13 +46,16 @@ class Diff::LCS::HTMLDiff
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
# standard:disable Style/HashSyntax
|
49
50
|
DEFAULT_OPTIONS = {
|
50
51
|
:expand_tabs => nil,
|
51
52
|
:output => nil,
|
52
53
|
:css => nil,
|
53
54
|
:title => nil
|
54
55
|
}.freeze
|
56
|
+
# standard:enable Style/HashSyntax
|
55
57
|
|
58
|
+
# standard:disable Layout/HeredocIndentation
|
56
59
|
DEFAULT_CSS = <<-CSS
|
57
60
|
body { margin: 0; }
|
58
61
|
.diff
|
@@ -86,11 +89,12 @@ pre
|
|
86
89
|
}
|
87
90
|
h1 { margin-left: 2em; }
|
88
91
|
CSS
|
92
|
+
# standard:enable Layout/HeredocIndentation
|
89
93
|
|
90
94
|
def initialize(left, right, options = nil)
|
91
|
-
@left
|
92
|
-
@right
|
93
|
-
@options
|
95
|
+
@left = left
|
96
|
+
@right = right
|
97
|
+
@options = options
|
94
98
|
|
95
99
|
@options = DEFAULT_OPTIONS.dup if @options.nil?
|
96
100
|
end
|
@@ -103,7 +107,7 @@ h1 { margin-left: 2em; }
|
|
103
107
|
|
104
108
|
@options[:css] ||= DEFAULT_CSS.dup
|
105
109
|
|
106
|
-
@options[:title] ||=
|
110
|
+
@options[:title] ||= "diff"
|
107
111
|
end
|
108
112
|
private :verify_options
|
109
113
|
|
@@ -116,13 +120,14 @@ h1 { margin-left: 2em; }
|
|
116
120
|
formatter = Text::Format.new
|
117
121
|
formatter.tabstop = @options[:expand_tabs]
|
118
122
|
|
119
|
-
@left.map!
|
120
|
-
@right.map!
|
123
|
+
@left.map! { |line| formatter.expand(line.chomp) }
|
124
|
+
@right.map! { |line| formatter.expand(line.chomp) }
|
121
125
|
end
|
122
126
|
|
123
|
-
@left.map!
|
124
|
-
@right.map!
|
127
|
+
@left.map! { |line| CGI.escapeHTML(line.chomp) }
|
128
|
+
@right.map! { |line| CGI.escapeHTML(line.chomp) }
|
125
129
|
|
130
|
+
# standard:disable Layout/HeredocIndentation
|
126
131
|
@options[:output] << <<-OUTPUT
|
127
132
|
<html>
|
128
133
|
<head>
|
@@ -137,14 +142,17 @@ h1 { margin-left: 2em; }
|
|
137
142
|
<span class="only_b">Only in New</span></p>
|
138
143
|
<div class="diff">
|
139
144
|
OUTPUT
|
145
|
+
# standard:enable Layout/HeredocIndentation
|
140
146
|
|
141
147
|
callbacks = Callbacks.new(@options[:output])
|
142
148
|
Diff::LCS.traverse_sequences(@left, @right, callbacks)
|
143
149
|
|
150
|
+
# standard:disable Layout/HeredocIndentation
|
144
151
|
@options[:output] << <<-OUTPUT
|
145
152
|
</div>
|
146
153
|
</body>
|
147
154
|
</html>
|
148
155
|
OUTPUT
|
156
|
+
# standard:enable Layout/HeredocIndentation
|
149
157
|
end
|
150
158
|
end
|