diff-lcs 1.4.3 → 1.4.4
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 +83 -49
- data/History.md +41 -0
- data/Rakefile +23 -6
- data/lib/diff/lcs.rb +8 -1
- data/lib/diff/lcs/block.rb +1 -1
- data/lib/diff/lcs/hunk.rb +107 -40
- data/lib/diff/lcs/ldiff.rb +16 -20
- data/spec/fixtures/ldiff/output.diff-c +2 -2
- data/spec/fixtures/ldiff/output.diff-u +2 -2
- data/spec/hunk_spec.rb +21 -10
- data/spec/issues_spec.rb +60 -4
- data/spec/ldiff_spec.rb +33 -32
- data/spec/spec_helper.rb +19 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20a82b46de7966bb69d8293ece23c885ff05a3a6f1828d99466079026200e3bd
|
4
|
+
data.tar.gz: af785a974e010578214c66694d3e2fd232b26a452d41049a55a9127c07f4b4d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f9ef284f2af3cb47d73100700dbfc39ac16802735f6751637025ed803604b7e27272b34ed1deccc2ddc4813b6e170c7ae2b3012afb094fc5e72d446866455e4
|
7
|
+
data.tar.gz: 0b5b56817c536cd55c52e43f2e9ac5b70d76ef1edf9dcf1e7639917da16fcd65f1bf4472df7c44d8d44603c2f5caa2748ce6ddbd41bb7b0215ad3fd0c38fb49a
|
data/Contributing.md
CHANGED
@@ -1,32 +1,35 @@
|
|
1
1
|
## Contributing
|
2
2
|
|
3
|
-
I value any contribution to Diff::LCS you can provide: a bug report, a
|
4
|
-
request, or code contributions. Code contributions to Diff::LCS are
|
5
|
-
<del>welcome</del>encouraged. Because Diff::LCS is a complex
|
6
|
-
are a few guidelines:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
I value any contribution to Diff::LCS you can provide: a bug report, a
|
4
|
+
feature request, or code contributions. Code contributions to Diff::LCS are
|
5
|
+
especially <del>welcome</del>encouraged. Because Diff::LCS is a complex
|
6
|
+
codebase, there are a few guidelines:
|
7
|
+
|
8
|
+
- Code changes _will not_ be accepted without tests. The test suite is
|
9
|
+
written with [RSpec][].
|
10
|
+
- Match my coding style.
|
11
|
+
- Use a thoughtfully-named topic branch that contains your change. Rebase
|
12
|
+
your commits into logical chunks as necessary.
|
13
|
+
- Use [quality commit messages][].
|
14
|
+
- Do not change the version number; when your patch is accepted and a release
|
15
|
+
is made, the version will be updated at that point.
|
16
|
+
- Submit a GitHub pull request with your changes.
|
17
|
+
- New or changed behaviours require appropriate documentation.
|
18
18
|
|
19
19
|
### Test Dependencies
|
20
20
|
|
21
|
-
Diff::LCS uses Ryan Davis’s [Hoe][] to manage the release process, and it
|
22
|
-
a number of rake tasks. You will mostly be interested in:
|
21
|
+
Diff::LCS uses Ryan Davis’s [Hoe][] to manage the release process, and it
|
22
|
+
adds a number of rake tasks. You will mostly be interested in:
|
23
23
|
|
24
|
-
|
24
|
+
```sh
|
25
|
+
$ rake
|
26
|
+
```
|
25
27
|
|
26
28
|
which runs the tests the same way that:
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
+
```sh
|
31
|
+
$ rake spec
|
32
|
+
```
|
30
33
|
|
31
34
|
will do.
|
32
35
|
|
@@ -34,51 +37,82 @@ To assist with the installation of the development dependencies, I have
|
|
34
37
|
provided a Gemfile pointing to the (generated) `diff-lcs.gemspec` file. This
|
35
38
|
will permit you to do:
|
36
39
|
|
37
|
-
|
40
|
+
```sh
|
41
|
+
$ bundle install
|
42
|
+
```
|
38
43
|
|
39
44
|
to get the development dependencies. If you aleady have `hoe` installed, you
|
40
45
|
can accomplish the same thing with:
|
41
46
|
|
42
|
-
|
47
|
+
```sh
|
48
|
+
$ rake newb
|
49
|
+
```
|
43
50
|
|
44
51
|
This task will install any missing dependencies, run the tests/specs, and
|
45
52
|
generate the RDoc.
|
46
53
|
|
47
54
|
You can run tests with code coverage analysis by running:
|
48
55
|
|
49
|
-
|
56
|
+
```sh
|
57
|
+
$ rake spec:coverage
|
58
|
+
```
|
50
59
|
|
51
60
|
### Workflow
|
52
61
|
|
53
62
|
Here's the most direct way to get your work merged into the project:
|
54
63
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
change does and the why you think it should be merged.
|
64
|
+
- Fork the project.
|
65
|
+
- Clone down your fork (`git clone git://github.com/<username>/diff-lcs.git`).
|
66
|
+
- Create a topic branch to contain your change (`git checkout -b my_awesome_feature`).
|
67
|
+
- Hack away, add tests. Not necessarily in that order.
|
68
|
+
- Make sure everything still passes by running `rake`.
|
69
|
+
- If necessary, rebase your commits into logical chunks, without errors.
|
70
|
+
- Push the branch up (`git push origin my_awesome_feature`).
|
71
|
+
- Create a pull request against halostatue/diff-lcs and describe what your
|
72
|
+
change does and the why you think it should be merged.
|
65
73
|
|
66
74
|
### Contributors
|
67
75
|
|
68
|
-
|
69
|
-
|
70
|
-
Thanks to everyone else who has contributed to Diff::LCS:
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
76
|
+
- Austin Ziegler created Diff::LCS.
|
77
|
+
|
78
|
+
Thanks to everyone else who has contributed code or bug reports to Diff::LCS:
|
79
|
+
|
80
|
+
- @ginriki
|
81
|
+
- @joshbronson
|
82
|
+
- @kevinmook
|
83
|
+
- @mckaz
|
84
|
+
- Akinori Musha
|
85
|
+
- Artem Ignatyev
|
86
|
+
- Brandon Fish
|
87
|
+
- Camille Drapier
|
88
|
+
- Cédric Boutillier
|
89
|
+
- Gregg Kellogg
|
90
|
+
- Jagdeep Singh
|
91
|
+
- Jason Gladish
|
92
|
+
- Jon Rowe
|
93
|
+
- Josef Strzibny
|
94
|
+
- Josep (@apuratepp)
|
95
|
+
- Josh Bronson
|
96
|
+
- Jun Aruga
|
97
|
+
- Kenichi Kamiya
|
98
|
+
- Kensuke Nagae
|
99
|
+
- Kevin Ansfield
|
100
|
+
- Koichi Ito
|
101
|
+
- Mark Friedgan
|
102
|
+
- Michael Granger
|
103
|
+
- Myron Marston
|
104
|
+
- Nicolas Leger
|
105
|
+
- Oleg Orlov
|
106
|
+
- Paul Kunysch
|
107
|
+
- Pete Higgins
|
108
|
+
- Peter Wagenet
|
109
|
+
- Philippe Lafoucrière
|
110
|
+
- Ryan Lovelett
|
111
|
+
- Scott Steele
|
112
|
+
- Simon Courtois
|
113
|
+
- Tomas Jura
|
114
|
+
- Vít Ondruch
|
115
|
+
|
116
|
+
[rspec]: http://rspec.info/documentation/
|
83
117
|
[quality commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
84
|
-
[
|
118
|
+
[hoe]: https://github.com/seattlerb/hoe
|
data/History.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# History
|
2
2
|
|
3
|
+
## 1.4.4 / 2020-07-01
|
4
|
+
|
5
|
+
- Fixed an issue reported by Jun Aruga in the Diff::LCS::Ldiff binary text
|
6
|
+
detection. [#44][]
|
7
|
+
- Fixed a theoretical issue reported by Jun Aruga in Diff::LCS::Hunk to raise
|
8
|
+
a more useful exception. [#43][]
|
9
|
+
- Added documentation that should address custom object issues as reported in
|
10
|
+
[#35][].
|
11
|
+
|
12
|
+
- Fixed more diff errors, in part reported in [#65][].
|
13
|
+
|
14
|
+
- The use of `Numeric#abs` is incorrect in `Diff::LCS::Block#diff_size`.
|
15
|
+
The diff size _must_ be accurate for correct change placement.
|
16
|
+
- When selecting @max_diff_size in Diff::LCS::Hunk, choose it based on
|
17
|
+
`block.diff_size.abs`.
|
18
|
+
- Made a number of changes that will, unfortunately, increase allocations
|
19
|
+
at the cost of being safe with frozen strings.
|
20
|
+
- Add some knowledge that when `Diff::LCS::Hunk#diff` is called, that we
|
21
|
+
are processing the _last_ hunk, so some changes will be made to how the
|
22
|
+
output is generated.
|
23
|
+
|
24
|
+
- `old`, `ed`, and `reverse_ed` formats have no differences.
|
25
|
+
- `unified` format will report `` given the
|
26
|
+
correct conditions, at most once. Unified range reporting also
|
27
|
+
differs for the last hunk such that the `length` of the range is
|
28
|
+
reduced by one.
|
29
|
+
- `context` format will report `\No newline at end of file` given the
|
30
|
+
correct conditions, up to once per "file". Context range reporting also
|
31
|
+
differs for the last hunk such that the `end` part of the range is
|
32
|
+
reduced by one to a minimum of one.
|
33
|
+
|
34
|
+
- Added a bunch more tests for the cases above, and fixed `hunk_spec.rb` so
|
35
|
+
that the phrase being compared isn't nonsense French.
|
36
|
+
|
37
|
+
- Updated formatting.
|
38
|
+
- Added a Rake task to assist with manual testing on Ruby 1.8.
|
39
|
+
|
3
40
|
## 1.4.3 / 2020-06-29
|
4
41
|
|
5
42
|
- Fixed several issues with the 1.4 on Rubies older than 2.0. Some of this was
|
@@ -263,8 +300,11 @@
|
|
263
300
|
[#29]: https://github.com/halostatue/diff-lcs/pull/29
|
264
301
|
[#33]: https://github.com/halostatue/diff-lcs/issues/33
|
265
302
|
[#34]: https://github.com/halostatue/diff-lcs/pull/34
|
303
|
+
[#35]: https://github.com/halostatue/diff-lcs/issues/35
|
266
304
|
[#36]: https://github.com/halostatue/diff-lcs/pull/36
|
267
305
|
[#38]: https://github.com/halostatue/diff-lcs/issues/38
|
306
|
+
[#43]: https://github.com/halostatue/diff-lcs/issues/43
|
307
|
+
[#44]: https://github.com/halostatue/diff-lcs/issues/44
|
268
308
|
[#47]: https://github.com/halostatue/diff-lcs/pull/47
|
269
309
|
[#48]: https://github.com/halostatue/diff-lcs/issues/48
|
270
310
|
[#49]: https://github.com/halostatue/diff-lcs/pull/49
|
@@ -276,3 +316,4 @@
|
|
276
316
|
[#60]: https://github.com/halostatue/diff-lcs/issues/60
|
277
317
|
[#61]: https://github.com/halostatue/diff-lcs/pull/61
|
278
318
|
[#63]: https://github.com/halostatue/diff-lcs/issues/63
|
319
|
+
[#65]: https://github.com/halostatue/diff-lcs/issues/65
|
data/Rakefile
CHANGED
@@ -10,18 +10,19 @@ Hoe.plugin :gemspec2
|
|
10
10
|
Hoe.plugin :git
|
11
11
|
|
12
12
|
if RUBY_VERSION < '1.9'
|
13
|
-
class Array
|
13
|
+
class Array #:nodoc:
|
14
14
|
def to_h
|
15
|
-
Hash[*
|
15
|
+
Hash[*flatten(1)]
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
class Gem::Specification
|
20
|
-
def metadata=(*)
|
21
|
-
|
19
|
+
class Gem::Specification #:nodoc:
|
20
|
+
def metadata=(*); end
|
21
|
+
|
22
|
+
def default_value(*); end
|
22
23
|
end
|
23
24
|
|
24
|
-
class Object
|
25
|
+
class Object #:nodoc:
|
25
26
|
def caller_locations(*)
|
26
27
|
[]
|
27
28
|
end
|
@@ -55,3 +56,19 @@ if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
59
|
+
|
60
|
+
task :ruby18 do
|
61
|
+
puts <<-MESSAGE
|
62
|
+
You are starting a barebones Ruby 1.8 docker environment. You will need to
|
63
|
+
do the following:
|
64
|
+
|
65
|
+
- mv Gemfile.lock{,.v2}
|
66
|
+
- gem install bundler --version 1.17.2 --no-ri --no-rdoc
|
67
|
+
- ruby -S bundle
|
68
|
+
- rake
|
69
|
+
|
70
|
+
Don't forget to restore your Gemfile.lock after testing.
|
71
|
+
|
72
|
+
MESSAGE
|
73
|
+
sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l"
|
74
|
+
end
|
data/lib/diff/lcs.rb
CHANGED
@@ -49,7 +49,7 @@ module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
|
|
49
49
|
# a x b y c z p d q
|
50
50
|
# a b c a x b y c z
|
51
51
|
module Diff::LCS
|
52
|
-
VERSION = '1.4.
|
52
|
+
VERSION = '1.4.4'
|
53
53
|
end
|
54
54
|
|
55
55
|
require 'diff/lcs/callbacks'
|
@@ -60,6 +60,13 @@ module Diff::LCS # rubocop:disable Style/Documentation
|
|
60
60
|
# +self+ and +other+. See Diff::LCS#lcs.
|
61
61
|
#
|
62
62
|
# lcs = seq1.lcs(seq2)
|
63
|
+
#
|
64
|
+
# A note when using objects: Diff::LCS only works properly when each object
|
65
|
+
# can be used as a key in a Hash, which typically means that the objects must
|
66
|
+
# implement Object#eql? in a way that two identical values compare
|
67
|
+
# identically for key purposes. That is:
|
68
|
+
#
|
69
|
+
# O.new('a').eql?(O.new('a')) == true
|
63
70
|
def lcs(other, &block) #:yields self[i] if there are matched subsequences:
|
64
71
|
Diff::LCS.lcs(self, other, &block)
|
65
72
|
end
|
data/lib/diff/lcs/block.rb
CHANGED
data/lib/diff/lcs/hunk.rb
CHANGED
@@ -6,26 +6,38 @@ require 'diff/lcs/block'
|
|
6
6
|
# each block. (So if we're not using context, every hunk will contain one
|
7
7
|
# block.) Used in the diff program (bin/ldiff).
|
8
8
|
class Diff::LCS::Hunk
|
9
|
+
OLD_DIFF_OP_ACTION = { '+' => 'a', '-' => 'd', '!' => 'c' }.freeze #:nodoc:
|
10
|
+
ED_DIFF_OP_ACTION = { '+' => 'a', '-' => 'd', '!' => 'c' }.freeze #:nodoc:
|
11
|
+
|
12
|
+
private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant)
|
13
|
+
|
9
14
|
# Create a hunk using references to both the old and new data, as well as the
|
10
15
|
# piece of data.
|
11
16
|
def initialize(data_old, data_new, piece, flag_context, file_length_difference)
|
12
17
|
# At first, a hunk will have just one Block in it
|
13
18
|
@blocks = [Diff::LCS::Block.new(piece)]
|
19
|
+
|
20
|
+
if @blocks[0].remove.empty? && @blocks[0].insert.empty?
|
21
|
+
fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions"
|
22
|
+
end
|
23
|
+
|
14
24
|
if String.method_defined?(:encoding)
|
15
25
|
@preferred_data_encoding = data_old.fetch(0, data_new.fetch(0, '')).encoding
|
16
26
|
end
|
27
|
+
|
17
28
|
@data_old = data_old
|
18
29
|
@data_new = data_new
|
19
30
|
|
20
31
|
before = after = file_length_difference
|
21
32
|
after += @blocks[0].diff_size
|
22
33
|
@file_length_difference = after # The caller must get this manually
|
23
|
-
@max_diff_size = @blocks.map { |e| e.diff_size }.max
|
34
|
+
@max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
|
35
|
+
|
24
36
|
|
25
37
|
# Save the start & end of each array. If the array doesn't exist (e.g.,
|
26
|
-
# we're only adding items in this block), then figure out the line
|
27
|
-
#
|
28
|
-
#
|
38
|
+
# we're only adding items in this block), then figure out the line number
|
39
|
+
# based on the line number of the other file and the current difference in
|
40
|
+
# file lengths.
|
29
41
|
if @blocks[0].remove.empty?
|
30
42
|
a1 = a2 = nil
|
31
43
|
else
|
@@ -55,7 +67,7 @@ class Diff::LCS::Hunk
|
|
55
67
|
|
56
68
|
# Change the "start" and "end" fields to note that context should be added
|
57
69
|
# to this hunk.
|
58
|
-
attr_accessor :flag_context
|
70
|
+
attr_accessor :flag_context # rubocop:disable Layout/EmptyLinesAroundAttributeAccessor
|
59
71
|
undef :flag_context=
|
60
72
|
def flag_context=(context) #:nodoc: # rubocop:disable Lint/DuplicateMethods
|
61
73
|
return if context.nil? or context.zero?
|
@@ -101,18 +113,18 @@ class Diff::LCS::Hunk
|
|
101
113
|
end
|
102
114
|
|
103
115
|
# Returns a diff string based on a format.
|
104
|
-
def diff(format)
|
116
|
+
def diff(format, last = false)
|
105
117
|
case format
|
106
118
|
when :old
|
107
|
-
old_diff
|
119
|
+
old_diff(last)
|
108
120
|
when :unified
|
109
|
-
unified_diff
|
121
|
+
unified_diff(last)
|
110
122
|
when :context
|
111
|
-
context_diff
|
123
|
+
context_diff(last)
|
112
124
|
when :ed
|
113
125
|
self
|
114
126
|
when :reverse_ed, :ed_finish
|
115
|
-
ed_diff(format)
|
127
|
+
ed_diff(format, last)
|
116
128
|
else
|
117
129
|
fail "Unknown diff format #{format}."
|
118
130
|
end
|
@@ -120,35 +132,34 @@ class Diff::LCS::Hunk
|
|
120
132
|
|
121
133
|
# Note that an old diff can't have any context. Therefore, we know that
|
122
134
|
# there's only one block in the hunk.
|
123
|
-
def old_diff
|
135
|
+
def old_diff(_last = false)
|
124
136
|
warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
|
125
|
-
op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
|
126
137
|
|
127
138
|
block = @blocks[0]
|
128
139
|
|
129
140
|
# Calculate item number range. Old diff range is just like a context
|
130
141
|
# diff range, except the ranges are on one line with the action between
|
131
142
|
# them.
|
132
|
-
s = encode("#{context_range(:old)}#{
|
143
|
+
s = encode("#{context_range(:old, ',')}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ',')}\n")
|
133
144
|
# If removing anything, just print out all the remove lines in the hunk
|
134
145
|
# which is just all the remove lines in the block.
|
135
146
|
unless block.remove.empty?
|
136
|
-
@data_old[@start_old..@end_old].each { |e| s << encode('< ') + e + encode("\n") }
|
147
|
+
@data_old[@start_old..@end_old].each { |e| s << encode('< ') + e.chomp + encode("\n") }
|
137
148
|
end
|
138
149
|
|
139
150
|
s << encode("---\n") if block.op == '!'
|
140
151
|
|
141
152
|
unless block.insert.empty?
|
142
|
-
@data_new[@start_new..@end_new].each { |e| s << encode('> ') + e + encode("\n") }
|
153
|
+
@data_new[@start_new..@end_new].each { |e| s << encode('> ') + e.chomp + encode("\n") }
|
143
154
|
end
|
144
155
|
|
145
156
|
s
|
146
157
|
end
|
147
158
|
private :old_diff
|
148
159
|
|
149
|
-
def unified_diff
|
160
|
+
def unified_diff(last = false)
|
150
161
|
# Calculate item number range.
|
151
|
-
s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n")
|
162
|
+
s = encode("@@ -#{unified_range(:old, last)} +#{unified_range(:new, last)} @@\n")
|
152
163
|
|
153
164
|
# Outlist starts containing the hunk of the old file. Removing an item
|
154
165
|
# just means putting a '-' in front of it. Inserting an item requires
|
@@ -161,7 +172,14 @@ class Diff::LCS::Hunk
|
|
161
172
|
# file -- don't take removed items into account.
|
162
173
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
163
174
|
|
164
|
-
outlist = @data_old[lo..hi].map { |e|
|
175
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(' ')}#{e.chomp}") }
|
176
|
+
|
177
|
+
last_block = blocks[-1]
|
178
|
+
|
179
|
+
if last
|
180
|
+
old_missing_newline = missing_last_newline?(@data_old)
|
181
|
+
new_missing_newline = missing_last_newline?(@data_new)
|
182
|
+
end
|
165
183
|
|
166
184
|
@blocks.each do |block|
|
167
185
|
block.remove.each do |item|
|
@@ -170,67 +188,100 @@ class Diff::LCS::Hunk
|
|
170
188
|
outlist[offset][0, 1] = encode(op)
|
171
189
|
num_removed += 1
|
172
190
|
end
|
191
|
+
|
192
|
+
if last && block == last_block && old_missing_newline && !new_missing_newline
|
193
|
+
outlist << encode('\')
|
194
|
+
num_removed += 1
|
195
|
+
end
|
196
|
+
|
173
197
|
block.insert.each do |item|
|
174
198
|
op = item.action.to_s # +
|
175
199
|
offset = item.position - @start_new + num_removed
|
176
|
-
outlist[offset, 0] = encode(op) + @data_new[item.position]
|
200
|
+
outlist[offset, 0] = encode(op) + @data_new[item.position].chomp
|
177
201
|
num_added += 1
|
178
202
|
end
|
179
203
|
end
|
180
204
|
|
205
|
+
outlist << encode('\') if last && new_missing_newline
|
206
|
+
|
181
207
|
s << outlist.join(encode("\n"))
|
208
|
+
|
209
|
+
s
|
182
210
|
end
|
183
211
|
private :unified_diff
|
184
212
|
|
185
|
-
def context_diff
|
213
|
+
def context_diff(last = false)
|
186
214
|
s = encode("***************\n")
|
187
|
-
s << encode("*** #{context_range(:old)} ****\n")
|
188
|
-
r = context_range(:new)
|
215
|
+
s << encode("*** #{context_range(:old, ',', last)} ****\n")
|
216
|
+
r = context_range(:new, ',', last)
|
217
|
+
|
218
|
+
if last
|
219
|
+
old_missing_newline = missing_last_newline?(@data_old)
|
220
|
+
new_missing_newline = missing_last_newline?(@data_new)
|
221
|
+
end
|
189
222
|
|
190
223
|
# Print out file 1 part for each block in context diff format if there
|
191
224
|
# are any blocks that remove items
|
192
225
|
lo, hi = @start_old, @end_old
|
193
226
|
removes = @blocks.reject { |e| e.remove.empty? }
|
194
|
-
|
195
|
-
|
227
|
+
|
228
|
+
unless removes.empty?
|
229
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(' ')}#{e.chomp}") }
|
230
|
+
|
231
|
+
last_block = removes[-1]
|
196
232
|
|
197
233
|
removes.each do |block|
|
198
234
|
block.remove.each do |item|
|
199
|
-
outlist[item.position - lo]
|
235
|
+
outlist[item.position - lo][0, 1] = encode(block.op) # - or !
|
236
|
+
end
|
237
|
+
|
238
|
+
if last && block == last_block && old_missing_newline
|
239
|
+
outlist << encode('\')
|
200
240
|
end
|
201
241
|
end
|
202
|
-
|
242
|
+
|
243
|
+
s << outlist.join(encode("\n")) << encode("\n")
|
203
244
|
end
|
204
245
|
|
205
|
-
s << encode("
|
246
|
+
s << encode("--- #{r} ----\n")
|
206
247
|
lo, hi = @start_new, @end_new
|
207
248
|
inserts = @blocks.reject { |e| e.insert.empty? }
|
208
|
-
|
209
|
-
|
249
|
+
|
250
|
+
unless inserts.empty?
|
251
|
+
outlist = @data_new[lo..hi].map { |e| String.new("#{encode(' ')}#{e.chomp}") }
|
252
|
+
|
253
|
+
last_block = inserts[-1]
|
254
|
+
|
210
255
|
inserts.each do |block|
|
211
256
|
block.insert.each do |item|
|
212
|
-
outlist[item.position - lo]
|
257
|
+
outlist[item.position - lo][0, 1] = encode(block.op) # + or !
|
258
|
+
end
|
259
|
+
|
260
|
+
if last && block == last_block && new_missing_newline
|
261
|
+
outlist << encode('\')
|
213
262
|
end
|
214
263
|
end
|
215
|
-
s << outlist.join("\n")
|
264
|
+
s << outlist.join(encode("\n"))
|
216
265
|
end
|
266
|
+
|
217
267
|
s
|
218
268
|
end
|
219
269
|
private :context_diff
|
220
270
|
|
221
|
-
def ed_diff(format)
|
222
|
-
op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
|
271
|
+
def ed_diff(format, _last = false)
|
223
272
|
warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
|
224
273
|
|
225
274
|
s =
|
226
275
|
if format == :reverse_ed
|
227
|
-
encode("#{
|
276
|
+
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, ',')}\n")
|
228
277
|
else
|
229
|
-
encode("#{context_range(:old, ' ')}#{
|
278
|
+
encode("#{context_range(:old, ' ')}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
|
230
279
|
end
|
231
280
|
|
232
281
|
unless @blocks[0].insert.empty?
|
233
|
-
@data_new[@start_new..@end_new].each do |e|
|
282
|
+
@data_new[@start_new..@end_new].each do |e|
|
283
|
+
s << e.chomp + encode("\n")
|
284
|
+
end
|
234
285
|
s << encode(".\n")
|
235
286
|
end
|
236
287
|
s
|
@@ -239,7 +290,7 @@ class Diff::LCS::Hunk
|
|
239
290
|
|
240
291
|
# Generate a range of item numbers to print. Only print 1 number if the
|
241
292
|
# range has only one item in it. Otherwise, it's 'start,end'
|
242
|
-
def context_range(mode, op =
|
293
|
+
def context_range(mode, op, last = false)
|
243
294
|
case mode
|
244
295
|
when :old
|
245
296
|
s, e = (@start_old + 1), (@end_old + 1)
|
@@ -247,6 +298,9 @@ class Diff::LCS::Hunk
|
|
247
298
|
s, e = (@start_new + 1), (@end_new + 1)
|
248
299
|
end
|
249
300
|
|
301
|
+
e -= 1 if last
|
302
|
+
e = 1 if e.zero?
|
303
|
+
|
250
304
|
s < e ? "#{s}#{op}#{e}" : e.to_s
|
251
305
|
end
|
252
306
|
private :context_range
|
@@ -254,7 +308,7 @@ class Diff::LCS::Hunk
|
|
254
308
|
# Generate a range of item numbers to print for unified diff. Print number
|
255
309
|
# where block starts, followed by number of lines in the block
|
256
310
|
# (don't print number of lines if it's 1)
|
257
|
-
def unified_range(mode)
|
311
|
+
def unified_range(mode, last)
|
258
312
|
case mode
|
259
313
|
when :old
|
260
314
|
s, e = (@start_old + 1), (@end_old + 1)
|
@@ -262,12 +316,25 @@ class Diff::LCS::Hunk
|
|
262
316
|
s, e = (@start_new + 1), (@end_new + 1)
|
263
317
|
end
|
264
318
|
|
265
|
-
length = e - s + 1
|
319
|
+
length = e - s + (last ? 0 : 1)
|
320
|
+
|
266
321
|
first = length < 2 ? e : s # "strange, but correct"
|
267
|
-
length
|
322
|
+
length <= 1 ? first.to_s : "#{first},#{length}"
|
268
323
|
end
|
269
324
|
private :unified_range
|
270
325
|
|
326
|
+
def missing_last_newline?(data)
|
327
|
+
newline = encode("\n")
|
328
|
+
|
329
|
+
if data[-2]
|
330
|
+
data[-2].end_with?(newline) && !data[-1].end_with?(newline)
|
331
|
+
elsif data[-1]
|
332
|
+
!data[-1].end_with?(newline)
|
333
|
+
else
|
334
|
+
true
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
271
338
|
if String.method_defined?(:encoding)
|
272
339
|
def encode(literal, target_encoding = @preferred_data_encoding)
|
273
340
|
literal.encode target_encoding
|
data/lib/diff/lcs/ldiff.rb
CHANGED
@@ -98,24 +98,19 @@ class << Diff::LCS::Ldiff
|
|
98
98
|
# items we've read from each file will differ by FLD (could be 0).
|
99
99
|
file_length_difference = 0
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
101
|
+
data_old = IO.read(file_old)
|
102
|
+
data_new = IO.read(file_new)
|
103
|
+
|
104
|
+
# Test binary status
|
105
|
+
if @binary.nil?
|
106
|
+
old_txt = data_old[0, 4096].scan(/\0/).empty?
|
107
|
+
new_txt = data_new[0, 4096].scan(/\0/).empty?
|
108
|
+
@binary = !old_txt || !new_txt
|
109
|
+
end
|
111
110
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
else
|
117
|
-
data_old = IO.readlines(file_old).map { |e| e.chomp }
|
118
|
-
data_new = IO.readlines(file_new).map { |e| e.chomp }
|
111
|
+
unless @binary
|
112
|
+
data_old = data_old.lines.to_a
|
113
|
+
data_new = data_new.lines.to_a
|
119
114
|
end
|
120
115
|
|
121
116
|
# diff yields lots of pieces, each of which is basically a Block object
|
@@ -150,20 +145,21 @@ class << Diff::LCS::Ldiff
|
|
150
145
|
end
|
151
146
|
|
152
147
|
diffs.each do |piece|
|
153
|
-
begin
|
148
|
+
begin # rubocop:disable Style/RedundantBegin
|
154
149
|
hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines, file_length_difference)
|
155
150
|
file_length_difference = hunk.file_length_difference
|
156
151
|
|
157
152
|
next unless oldhunk
|
158
153
|
next if @lines.positive? and hunk.merge(oldhunk)
|
159
154
|
|
160
|
-
output << oldhunk.diff(@format)
|
155
|
+
output << oldhunk.diff(@format)
|
156
|
+
output << "\n" if @format == :unified
|
161
157
|
ensure
|
162
158
|
oldhunk = hunk
|
163
159
|
end
|
164
160
|
end
|
165
161
|
|
166
|
-
last = oldhunk.diff(@format)
|
162
|
+
last = oldhunk.diff(@format, true)
|
167
163
|
last << "\n" if last.respond_to?(:end_with?) && !last.end_with?("\n")
|
168
164
|
|
169
165
|
output << last
|
@@ -1,5 +1,5 @@
|
|
1
|
-
*** spec/fixtures/aX
|
2
|
-
--- spec/fixtures/bXaX
|
1
|
+
*** spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400
|
2
|
+
--- spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400
|
3
3
|
***************
|
4
4
|
*** 1 ****
|
5
5
|
! aX
|
data/spec/hunk_spec.rb
CHANGED
@@ -6,28 +6,39 @@ if String.method_defined?(:encoding)
|
|
6
6
|
require 'diff/lcs/hunk'
|
7
7
|
|
8
8
|
describe Diff::LCS::Hunk do
|
9
|
-
let(:old_data) { ['Tu
|
10
|
-
let(:new_data) { ['Tu
|
9
|
+
let(:old_data) { ['Tu a un carté avec {count} itéms'.encode('UTF-16LE')] }
|
10
|
+
let(:new_data) { ['Tu a un carte avec {count} items'.encode('UTF-16LE')] }
|
11
11
|
let(:pieces) { Diff::LCS.diff old_data, new_data }
|
12
12
|
let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) }
|
13
13
|
|
14
14
|
it 'produces a unified diff from the two pieces' do
|
15
15
|
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
16
16
|
@@ -1 +1 @@
|
17
|
-
-Tu
|
18
|
-
+Tu
|
17
|
+
-Tu a un carté avec {count} itéms
|
18
|
+
+Tu a un carte avec {count} items
|
19
19
|
EXPECTED
|
20
20
|
|
21
21
|
expect(hunk.diff(:unified)).to eq(expected)
|
22
22
|
end
|
23
23
|
|
24
|
+
it 'produces a unified diff from the two pieces (last entry)' do
|
25
|
+
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
26
|
+
@@ -1 +1 @@
|
27
|
+
-Tu a un carté avec {count} itéms
|
28
|
+
+Tu a un carte avec {count} items
|
29
|
+
\
|
30
|
+
EXPECTED
|
31
|
+
|
32
|
+
expect(hunk.diff(:unified, true)).to eq(expected)
|
33
|
+
end
|
34
|
+
|
24
35
|
it 'produces a context diff from the two pieces' do
|
25
36
|
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
26
37
|
***************
|
27
38
|
*** 1 ****
|
28
|
-
! Tu
|
39
|
+
! Tu a un carté avec {count} itéms
|
29
40
|
--- 1 ----
|
30
|
-
! Tu
|
41
|
+
! Tu a un carte avec {count} items
|
31
42
|
EXPECTED
|
32
43
|
|
33
44
|
expect(hunk.diff(:context)).to eq(expected)
|
@@ -36,9 +47,9 @@ if String.method_defined?(:encoding)
|
|
36
47
|
it 'produces an old diff from the two pieces' do
|
37
48
|
expected = <<-EXPECTED.gsub(/^ +/, '').encode('UTF-16LE').chomp
|
38
49
|
1c1
|
39
|
-
< Tu
|
50
|
+
< Tu a un carté avec {count} itéms
|
40
51
|
---
|
41
|
-
> Tu
|
52
|
+
> Tu a un carte avec {count} items
|
42
53
|
|
43
54
|
EXPECTED
|
44
55
|
|
@@ -48,7 +59,7 @@ if String.method_defined?(:encoding)
|
|
48
59
|
it 'produces a reverse ed diff from the two pieces' do
|
49
60
|
expected = <<-EXPECTED.gsub(/^ +/, '').encode('UTF-16LE').chomp
|
50
61
|
c1
|
51
|
-
Tu
|
62
|
+
Tu a un carte avec {count} items
|
52
63
|
.
|
53
64
|
|
54
65
|
EXPECTED
|
@@ -62,7 +73,7 @@ if String.method_defined?(:encoding)
|
|
62
73
|
it 'produces a unified diff' do
|
63
74
|
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
64
75
|
@@ -1 +1,2 @@
|
65
|
-
+Tu
|
76
|
+
+Tu a un carte avec {count} items
|
66
77
|
EXPECTED
|
67
78
|
|
68
79
|
expect(hunk.diff(:unified)).to eq(expected)
|
data/spec/issues_spec.rb
CHANGED
@@ -56,17 +56,17 @@ describe 'Diff::LCS Issues' do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
describe
|
59
|
+
describe 'issue #57' do
|
60
60
|
it 'should fail with a correct error' do
|
61
61
|
expect {
|
62
|
-
actual = {:category=>
|
63
|
-
expected = {:category=>
|
62
|
+
actual = { :category => 'app.rack.request' }
|
63
|
+
expected = { :category => 'rack.middleware', :title => 'Anonymous Middleware' }
|
64
64
|
expect(actual).to eq(expected)
|
65
65
|
}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
describe
|
69
|
+
describe 'issue #60' do
|
70
70
|
it 'should produce unified output with correct context' do
|
71
71
|
old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp)
|
72
72
|
{
|
@@ -95,4 +95,60 @@ describe 'Diff::LCS Issues' do
|
|
95
95
|
EXPECTED
|
96
96
|
end
|
97
97
|
end
|
98
|
+
|
99
|
+
describe 'issue #65' do
|
100
|
+
def diff_lines(old_lines, new_lines)
|
101
|
+
file_length_difference = 0
|
102
|
+
previous_hunk = nil
|
103
|
+
output = []
|
104
|
+
|
105
|
+
Diff::LCS.diff(old_lines, new_lines).each do |piece|
|
106
|
+
hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference)
|
107
|
+
file_length_difference = hunk.file_length_difference
|
108
|
+
maybe_contiguous_hunks = (previous_hunk.nil? || hunk.merge(previous_hunk))
|
109
|
+
|
110
|
+
output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks
|
111
|
+
|
112
|
+
previous_hunk = hunk
|
113
|
+
end
|
114
|
+
output << "#{previous_hunk.diff(:unified, true)}\n" unless previous_hunk.nil?
|
115
|
+
output.join
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should not misplace the new chunk' do
|
119
|
+
old_data = [
|
120
|
+
'recipe[a::default]', 'recipe[b::default]', 'recipe[c::default]',
|
121
|
+
'recipe[d::default]', 'recipe[e::default]', 'recipe[f::default]',
|
122
|
+
'recipe[g::default]', 'recipe[h::default]', 'recipe[i::default]',
|
123
|
+
'recipe[j::default]', 'recipe[k::default]', 'recipe[l::default]',
|
124
|
+
'recipe[m::default]', 'recipe[n::default]'
|
125
|
+
]
|
126
|
+
|
127
|
+
new_data = [
|
128
|
+
'recipe[a::default]', 'recipe[c::default]', 'recipe[d::default]',
|
129
|
+
'recipe[e::default]', 'recipe[f::default]', 'recipe[g::default]',
|
130
|
+
'recipe[h::default]', 'recipe[i::default]', 'recipe[j::default]',
|
131
|
+
'recipe[k::default]', 'recipe[l::default]', 'recipe[m::default]',
|
132
|
+
'recipe[n::default]', 'recipe[o::new]', 'recipe[p::new]',
|
133
|
+
'recipe[q::new]', 'recipe[r::new]'
|
134
|
+
]
|
135
|
+
|
136
|
+
expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF)
|
137
|
+
@@ -1,5 +1,4 @@
|
138
|
+
recipe[a::default]
|
139
|
+
-recipe[b::default]
|
140
|
+
recipe[c::default]
|
141
|
+
recipe[d::default]
|
142
|
+
recipe[e::default]
|
143
|
+
@@ -12,3 +11,7 @@
|
144
|
+
recipe[l::default]
|
145
|
+
recipe[m::default]
|
146
|
+
recipe[n::default]
|
147
|
+
+recipe[o::new]
|
148
|
+
+recipe[p::new]
|
149
|
+
+recipe[q::new]
|
150
|
+
+recipe[r::new]
|
151
|
+
EODIFF
|
152
|
+
end
|
153
|
+
end
|
98
154
|
end
|
data/spec/ldiff_spec.rb
CHANGED
@@ -5,40 +5,39 @@ require 'spec_helper'
|
|
5
5
|
RSpec.describe 'bin/ldiff' do
|
6
6
|
include CaptureSubprocessIO
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
fixtures = [
|
9
|
+
{ :name => 'output.diff', :left => 'aX', :right => 'bXaX' },
|
10
|
+
{ :name => 'output.diff.chef', :left => 'old-chef', :right => 'new-chef' },
|
11
|
+
{ :name => 'output.diff.chef2', :left => 'old-chef2', :right => 'new-chef2' }
|
12
|
+
].product([nil, '-e', '-f', '-c', '-u']).map { |(fixture, flag)|
|
13
|
+
fixture = fixture.dup
|
14
|
+
fixture[:flag] = flag
|
15
|
+
fixture
|
16
|
+
}
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
expect(run_ldiff('-c')).to eq(output_diff_c)
|
25
|
-
end
|
18
|
+
def self.test_ldiff(fixture)
|
19
|
+
desc = [
|
20
|
+
fixture[:flag],
|
21
|
+
"spec/fixtures/#{fixture[:left]}",
|
22
|
+
"spec/fixtures/#{fixture[:right]}",
|
23
|
+
'#',
|
24
|
+
'=>',
|
25
|
+
"spec/fixtures/ldiff/#{fixture[:name]}#{fixture[:flag]}"
|
26
|
+
].join(' ')
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
specify do
|
32
|
-
expect(run_ldiff('-f')).to eq(output_diff_f)
|
28
|
+
it desc do
|
29
|
+
expect(run_ldiff(fixture)).to eq(read_fixture(fixture))
|
30
|
+
end
|
33
31
|
end
|
34
32
|
|
35
|
-
|
36
|
-
|
33
|
+
fixtures.each do |fixture|
|
34
|
+
test_ldiff(fixture)
|
37
35
|
end
|
38
36
|
|
39
|
-
def read_fixture(
|
40
|
-
|
41
|
-
|
37
|
+
def read_fixture(options)
|
38
|
+
fixture = options.fetch(:name)
|
39
|
+
flag = options.fetch(:flag)
|
40
|
+
name = "spec/fixtures/ldiff/#{fixture}#{flag}"
|
42
41
|
data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name)
|
43
42
|
clean_data(data, flag)
|
44
43
|
end
|
@@ -68,13 +67,15 @@ RSpec.describe 'bin/ldiff' do
|
|
68
67
|
\s*
|
69
68
|
(?:[-+]\d{4}|Z)
|
70
69
|
}x,
|
71
|
-
'*** spec/fixtures/\1 0000-00-00
|
70
|
+
'*** spec/fixtures/\1 0000-00-00 :00 =>:00 =>00.000000000 -0000'
|
72
71
|
)
|
73
72
|
end
|
74
73
|
|
75
|
-
def run_ldiff(
|
76
|
-
|
77
|
-
|
74
|
+
def run_ldiff(options)
|
75
|
+
flag = options.fetch(:flag)
|
76
|
+
left = options.fetch(:left)
|
77
|
+
right = options.fetch(:right)
|
78
|
+
|
78
79
|
stdout, stderr = capture_subprocess_io do
|
79
80
|
system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}")
|
80
81
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,6 @@ require 'pathname'
|
|
5
5
|
|
6
6
|
require 'psych' if RUBY_VERSION >= '1.9'
|
7
7
|
|
8
|
-
|
9
8
|
if ENV['COVERAGE']
|
10
9
|
require 'simplecov'
|
11
10
|
|
@@ -45,30 +44,31 @@ module CaptureSubprocessIO
|
|
45
44
|
end
|
46
45
|
|
47
46
|
def capture_subprocess_io
|
48
|
-
_synchronize
|
49
|
-
|
50
|
-
|
47
|
+
_synchronize { _capture_subprocess_io { yield } }
|
48
|
+
end
|
49
|
+
|
50
|
+
def _capture_subprocess_io
|
51
|
+
require 'tempfile'
|
51
52
|
|
52
|
-
|
53
|
+
captured_stdout, captured_stderr = Tempfile.new('out'), Tempfile.new('err')
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
|
56
|
+
$stdout.reopen captured_stdout
|
57
|
+
$stderr.reopen captured_stderr
|
57
58
|
|
58
|
-
|
59
|
+
yield
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
$stdout.rewind
|
62
|
+
$stderr.rewind
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
64
|
+
[captured_stdout.read, captured_stderr.read]
|
65
|
+
ensure
|
66
|
+
captured_stdout.unlink
|
67
|
+
captured_stderr.unlink
|
68
|
+
$stdout.reopen orig_stdout
|
69
|
+
$stderr.reopen orig_stderr
|
71
70
|
end
|
71
|
+
private :_capture_subprocess_io
|
72
72
|
end
|
73
73
|
|
74
74
|
require 'diff-lcs'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diff-lcs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Austin Ziegler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hoe-doofus
|