diff-lcs 1.6.2 → 2.0.0

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.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -4
  3. data/CODE_OF_CONDUCT.md +152 -114
  4. data/CONTRIBUTING.md +91 -35
  5. data/CONTRIBUTORS.md +19 -9
  6. data/LICENCE.md +39 -11
  7. data/Manifest.txt +91 -83
  8. data/README.md +30 -17
  9. data/Rakefile +99 -73
  10. data/SECURITY.md +22 -27
  11. data/integration/compare/array_diff_spec.rb +10 -0
  12. data/integration/compare/hash_diff_spec.rb +25 -0
  13. data/integration/compare/string_diff_spec.rb +10 -0
  14. data/integration/rspec_differ_spec.rb +26 -0
  15. data/integration/rspec_expectations_spec.rb +32 -0
  16. data/integration/runner +20 -0
  17. data/lib/diff/lcs/block.rb +29 -24
  18. data/lib/diff/lcs/callbacks.rb +240 -242
  19. data/lib/diff/lcs/change.rb +102 -104
  20. data/lib/diff/lcs/hunk.rb +92 -155
  21. data/lib/diff/lcs/internals.rb +92 -96
  22. data/lib/diff/lcs/ldiff.rb +30 -38
  23. data/lib/diff/lcs/version.rb +1 -1
  24. data/lib/diff/lcs.rb +439 -466
  25. data/licenses/dco.txt +34 -0
  26. data/spec/hunk_spec.rb +32 -45
  27. data/spec/lcs_spec.rb +6 -6
  28. data/spec/ldiff_spec.rb +8 -8
  29. data/spec/spec_helper.rb +17 -27
  30. data/test/fixtures/ldiff/output.diff-c +7 -0
  31. data/test/fixtures/ldiff/output.diff-u +5 -0
  32. data/test/fixtures/ldiff/output.diff.bin2 +1 -0
  33. data/test/fixtures/ldiff/output.diff.bin2-c +1 -0
  34. data/test/fixtures/ldiff/output.diff.bin2-e +1 -0
  35. data/test/fixtures/ldiff/output.diff.bin2-f +1 -0
  36. data/test/fixtures/ldiff/output.diff.bin2-u +1 -0
  37. data/{spec → test}/fixtures/ldiff/output.diff.chef-c +2 -2
  38. data/test/fixtures/ldiff/output.diff.chef-u +9 -0
  39. data/{spec → test}/fixtures/ldiff/output.diff.chef2-c +2 -2
  40. data/{spec → test}/fixtures/ldiff/output.diff.chef2-u +2 -2
  41. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
  42. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
  43. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
  44. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
  45. data/test/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
  46. data/test/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
  47. data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-c +2 -2
  48. data/test/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
  49. data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-c +2 -2
  50. data/test/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
  51. data/test/test_block.rb +34 -0
  52. data/test/test_change.rb +234 -0
  53. data/test/test_diff.rb +53 -0
  54. data/test/test_helper.rb +225 -0
  55. data/test/test_hunk.rb +72 -0
  56. data/test/test_issues.rb +168 -0
  57. data/test/test_lcs.rb +47 -0
  58. data/test/test_ldiff.rb +89 -0
  59. data/test/test_patch.rb +362 -0
  60. data/test/test_sdiff.rb +167 -0
  61. data/test/test_traverse_balanced.rb +322 -0
  62. data/test/test_traverse_sequences.rb +187 -0
  63. metadata +205 -119
  64. data/.rspec +0 -1
  65. data/bin/htmldiff +0 -35
  66. data/lib/diff/lcs/backports.rb +0 -13
  67. data/lib/diff/lcs/htmldiff.rb +0 -160
  68. data/mise.toml +0 -5
  69. data/spec/fixtures/ldiff/output.diff-c +0 -7
  70. data/spec/fixtures/ldiff/output.diff-e +0 -3
  71. data/spec/fixtures/ldiff/output.diff-f +0 -3
  72. data/spec/fixtures/ldiff/output.diff-u +0 -5
  73. data/spec/fixtures/ldiff/output.diff.bin2 +0 -1
  74. data/spec/fixtures/ldiff/output.diff.bin2-c +0 -1
  75. data/spec/fixtures/ldiff/output.diff.bin2-e +0 -1
  76. data/spec/fixtures/ldiff/output.diff.bin2-f +0 -1
  77. data/spec/fixtures/ldiff/output.diff.bin2-u +0 -1
  78. data/spec/fixtures/ldiff/output.diff.chef-e +0 -3
  79. data/spec/fixtures/ldiff/output.diff.chef-f +0 -3
  80. data/spec/fixtures/ldiff/output.diff.chef-u +0 -9
  81. data/spec/fixtures/ldiff/output.diff.chef2-e +0 -7
  82. data/spec/fixtures/ldiff/output.diff.chef2-f +0 -7
  83. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +0 -9
  84. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +0 -7
  85. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +0 -9
  86. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +0 -7
  87. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +0 -9
  88. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +0 -6
  89. data/spec/fixtures/ldiff/output.diff.missing_new_line1-u +0 -9
  90. data/spec/fixtures/ldiff/output.diff.missing_new_line2-u +0 -9
  91. /data/{docs → licenses}/COPYING.txt +0 -0
  92. /data/{docs → licenses}/artistic.txt +0 -0
  93. /data/{spec → test}/fixtures/123_x +0 -0
  94. /data/{spec → test}/fixtures/456_x +0 -0
  95. /data/{spec → test}/fixtures/aX +0 -0
  96. /data/{spec → test}/fixtures/bXaX +0 -0
  97. /data/{spec → test}/fixtures/ds1.csv +0 -0
  98. /data/{spec → test}/fixtures/ds2.csv +0 -0
  99. /data/{spec → test}/fixtures/empty +0 -0
  100. /data/{spec → test}/fixtures/file1.bin +0 -0
  101. /data/{spec → test}/fixtures/file2.bin +0 -0
  102. /data/{spec → test}/fixtures/four_lines +0 -0
  103. /data/{spec → test}/fixtures/four_lines_with_missing_new_line +0 -0
  104. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line1-e +0 -0
  105. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line1-f +0 -0
  106. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line2-e +0 -0
  107. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line2-f +0 -0
  108. /data/{spec → test}/fixtures/ldiff/error.diff.chef-e +0 -0
  109. /data/{spec → test}/fixtures/ldiff/error.diff.chef-f +0 -0
  110. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line1-e +0 -0
  111. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line1-f +0 -0
  112. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line2-e +0 -0
  113. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line2-f +0 -0
  114. /data/{spec → test}/fixtures/ldiff/output.diff +0 -0
  115. /data/{spec → test}/fixtures/ldiff/output.diff.bin1 +0 -0
  116. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-c +0 -0
  117. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-e +0 -0
  118. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-f +0 -0
  119. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-u +0 -0
  120. /data/{spec → test}/fixtures/ldiff/output.diff.chef +0 -0
  121. /data/{spec → test}/fixtures/ldiff/output.diff.chef2 +0 -0
  122. /data/{spec → test}/fixtures/ldiff/output.diff.chef2-d +0 -0
  123. /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines +0 -0
  124. /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines-e +0 -0
  125. /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines-f +0 -0
  126. /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty +0 -0
  127. /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty-e +0 -0
  128. /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty-f +0 -0
  129. /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context +0 -0
  130. /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context-e +0 -0
  131. /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context-f +0 -0
  132. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1 +0 -0
  133. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
  134. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
  135. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2 +0 -0
  136. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
  137. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
  138. /data/{spec → test}/fixtures/new-chef +0 -0
  139. /data/{spec → test}/fixtures/new-chef2 +0 -0
  140. /data/{spec → test}/fixtures/old-chef +0 -0
  141. /data/{spec → test}/fixtures/old-chef2 +0 -0
data/LICENCE.md CHANGED
@@ -1,14 +1,17 @@
1
1
  # Licence
2
2
 
3
- This software is available under three licenses: the GNU GPL version 2 (or at
4
- your option, a later version), the Perl Artistic license, or the MIT license.
5
- Note that my preference for licensing is the MIT license, but Algorithm::Diff
6
- was dually originally licensed with the Perl Artistic and the GNU GPL ("the same
7
- terms as Perl itself") and given that the Ruby implementation originally hewed
8
- pretty closely to the Perl version, I must maintain the additional licensing
9
- terms.
10
-
11
- - Copyright 2004–2025 Austin Ziegler and contributors.
3
+ - SPDX-License-Identifier: [MIT][mit] OR [GPL-2.0-or-later][gpl2-or-later] OR
4
+ [Artistic-1.0-Perl][artistic-perl]
5
+
6
+ This software is available under three disjunctive licences: the GNU GPL version
7
+ 2 (or at your option, a later version), the Perl Artistic license, or the MIT
8
+ license. Note that my preference for licensing is the MIT license, but
9
+ Algorithm::Diff was dually originally licensed with the Perl Artistic and the
10
+ GNU GPL ("the same terms as Perl itself") and given that the Ruby implementation
11
+ originally hewed pretty closely to the Perl version, I must maintain the
12
+ additional licensing terms.
13
+
14
+ - Copyright 2004-2026 Austin Ziegler and contributors.
12
15
  - Adapted from Algorithm::Diff (Perl) by Ned Konz and a Smalltalk version by
13
16
  Mario I. Wolczko.
14
17
 
@@ -33,8 +36,33 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
36
 
34
37
  ## Perl Artistic License
35
38
 
36
- See the file docs/artistic.txt in the main distribution.
39
+ See [licences/artistic.txt](licences/artistic.txt) in the main distribution.
37
40
 
38
41
  ## GNU GPL version 2
39
42
 
40
- See the file docs/COPYING.txt in the main distribution.
43
+ See the file [licences/COPYING.txt](licences/COPYING.txt) in the main
44
+ distribution.
45
+
46
+ ## Developer Certificate of Origin
47
+
48
+ All contributors **must** certify they are willing and able to provide their
49
+ contributions under the terms of _all_ of this project's licences with the
50
+ certification of the [Developer Certificate of Origin (Version 1.1)][dco].
51
+
52
+ Such certification is provided by ensuring that a `Signed-off-by`
53
+ [commit trailer][trailer] is present on every commit:
54
+
55
+ Signed-off-by: FirstName LastName <email@example.org>
56
+
57
+ The `Signed-off-by` trailer can be automatically added by git with the `-s` or
58
+ `--signoff` option on `git commit`:
59
+
60
+ ```sh
61
+ git commit --signoff
62
+ ```
63
+
64
+ [artistic-perl]: https://spdx.org/licenses/Artistic-1.0-Perl.html
65
+ [gpl2-or-later]: https://spdx.org/licenses/GPL-2.0-or-later.html
66
+ [mit]: https://spdx.org/licenses/MIT.html
67
+ [trailer]: https://git-scm.com/docs/git-interpret-trailers
68
+ [dco]: licences/dco.txt
data/Manifest.txt CHANGED
@@ -1,4 +1,3 @@
1
- .rspec
2
1
  CHANGELOG.md
3
2
  CODE_OF_CONDUCT.md
4
3
  CONTRIBUTING.md
@@ -8,102 +7,29 @@ Manifest.txt
8
7
  README.md
9
8
  Rakefile
10
9
  SECURITY.md
11
- bin/htmldiff
12
10
  bin/ldiff
13
- docs/COPYING.txt
14
- docs/artistic.txt
11
+ integration/compare/array_diff_spec.rb
12
+ integration/compare/hash_diff_spec.rb
13
+ integration/compare/string_diff_spec.rb
14
+ integration/rspec_differ_spec.rb
15
+ integration/rspec_expectations_spec.rb
16
+ integration/runner
15
17
  lib/diff-lcs.rb
16
18
  lib/diff/lcs.rb
17
19
  lib/diff/lcs/array.rb
18
- lib/diff/lcs/backports.rb
19
20
  lib/diff/lcs/block.rb
20
21
  lib/diff/lcs/callbacks.rb
21
22
  lib/diff/lcs/change.rb
22
- lib/diff/lcs/htmldiff.rb
23
23
  lib/diff/lcs/hunk.rb
24
24
  lib/diff/lcs/internals.rb
25
25
  lib/diff/lcs/ldiff.rb
26
26
  lib/diff/lcs/string.rb
27
27
  lib/diff/lcs/version.rb
28
- mise.toml
28
+ licenses/COPYING.txt
29
+ licenses/artistic.txt
30
+ licenses/dco.txt
29
31
  spec/change_spec.rb
30
32
  spec/diff_spec.rb
31
- spec/fixtures/123_x
32
- spec/fixtures/456_x
33
- spec/fixtures/aX
34
- spec/fixtures/bXaX
35
- spec/fixtures/ds1.csv
36
- spec/fixtures/ds2.csv
37
- spec/fixtures/empty
38
- spec/fixtures/file1.bin
39
- spec/fixtures/file2.bin
40
- spec/fixtures/four_lines
41
- spec/fixtures/four_lines_with_missing_new_line
42
- spec/fixtures/ldiff/diff.missing_new_line1-e
43
- spec/fixtures/ldiff/diff.missing_new_line1-f
44
- spec/fixtures/ldiff/diff.missing_new_line2-e
45
- spec/fixtures/ldiff/diff.missing_new_line2-f
46
- spec/fixtures/ldiff/error.diff.chef-e
47
- spec/fixtures/ldiff/error.diff.chef-f
48
- spec/fixtures/ldiff/error.diff.missing_new_line1-e
49
- spec/fixtures/ldiff/error.diff.missing_new_line1-f
50
- spec/fixtures/ldiff/error.diff.missing_new_line2-e
51
- spec/fixtures/ldiff/error.diff.missing_new_line2-f
52
- spec/fixtures/ldiff/output.diff
53
- spec/fixtures/ldiff/output.diff-c
54
- spec/fixtures/ldiff/output.diff-e
55
- spec/fixtures/ldiff/output.diff-f
56
- spec/fixtures/ldiff/output.diff-u
57
- spec/fixtures/ldiff/output.diff.bin1
58
- spec/fixtures/ldiff/output.diff.bin1-c
59
- spec/fixtures/ldiff/output.diff.bin1-e
60
- spec/fixtures/ldiff/output.diff.bin1-f
61
- spec/fixtures/ldiff/output.diff.bin1-u
62
- spec/fixtures/ldiff/output.diff.bin2
63
- spec/fixtures/ldiff/output.diff.bin2-c
64
- spec/fixtures/ldiff/output.diff.bin2-e
65
- spec/fixtures/ldiff/output.diff.bin2-f
66
- spec/fixtures/ldiff/output.diff.bin2-u
67
- spec/fixtures/ldiff/output.diff.chef
68
- spec/fixtures/ldiff/output.diff.chef-c
69
- spec/fixtures/ldiff/output.diff.chef-e
70
- spec/fixtures/ldiff/output.diff.chef-f
71
- spec/fixtures/ldiff/output.diff.chef-u
72
- spec/fixtures/ldiff/output.diff.chef2
73
- spec/fixtures/ldiff/output.diff.chef2-c
74
- spec/fixtures/ldiff/output.diff.chef2-d
75
- spec/fixtures/ldiff/output.diff.chef2-e
76
- spec/fixtures/ldiff/output.diff.chef2-f
77
- spec/fixtures/ldiff/output.diff.chef2-u
78
- spec/fixtures/ldiff/output.diff.empty.vs.four_lines
79
- spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c
80
- spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e
81
- spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f
82
- spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u
83
- spec/fixtures/ldiff/output.diff.four_lines.vs.empty
84
- spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c
85
- spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e
86
- spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f
87
- spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u
88
- spec/fixtures/ldiff/output.diff.issue95_trailing_context
89
- spec/fixtures/ldiff/output.diff.issue95_trailing_context-c
90
- spec/fixtures/ldiff/output.diff.issue95_trailing_context-e
91
- spec/fixtures/ldiff/output.diff.issue95_trailing_context-f
92
- spec/fixtures/ldiff/output.diff.issue95_trailing_context-u
93
- spec/fixtures/ldiff/output.diff.missing_new_line1
94
- spec/fixtures/ldiff/output.diff.missing_new_line1-c
95
- spec/fixtures/ldiff/output.diff.missing_new_line1-e
96
- spec/fixtures/ldiff/output.diff.missing_new_line1-f
97
- spec/fixtures/ldiff/output.diff.missing_new_line1-u
98
- spec/fixtures/ldiff/output.diff.missing_new_line2
99
- spec/fixtures/ldiff/output.diff.missing_new_line2-c
100
- spec/fixtures/ldiff/output.diff.missing_new_line2-e
101
- spec/fixtures/ldiff/output.diff.missing_new_line2-f
102
- spec/fixtures/ldiff/output.diff.missing_new_line2-u
103
- spec/fixtures/new-chef
104
- spec/fixtures/new-chef2
105
- spec/fixtures/old-chef
106
- spec/fixtures/old-chef2
107
33
  spec/hunk_spec.rb
108
34
  spec/issues_spec.rb
109
35
  spec/lcs_spec.rb
@@ -113,3 +39,85 @@ spec/sdiff_spec.rb
113
39
  spec/spec_helper.rb
114
40
  spec/traverse_balanced_spec.rb
115
41
  spec/traverse_sequences_spec.rb
42
+ test/fixtures/123_x
43
+ test/fixtures/456_x
44
+ test/fixtures/aX
45
+ test/fixtures/bXaX
46
+ test/fixtures/ds1.csv
47
+ test/fixtures/ds2.csv
48
+ test/fixtures/empty
49
+ test/fixtures/file1.bin
50
+ test/fixtures/file2.bin
51
+ test/fixtures/four_lines
52
+ test/fixtures/four_lines_with_missing_new_line
53
+ test/fixtures/ldiff/diff.missing_new_line1-e
54
+ test/fixtures/ldiff/diff.missing_new_line1-f
55
+ test/fixtures/ldiff/diff.missing_new_line2-e
56
+ test/fixtures/ldiff/diff.missing_new_line2-f
57
+ test/fixtures/ldiff/error.diff.chef-e
58
+ test/fixtures/ldiff/error.diff.chef-f
59
+ test/fixtures/ldiff/error.diff.missing_new_line1-e
60
+ test/fixtures/ldiff/error.diff.missing_new_line1-f
61
+ test/fixtures/ldiff/error.diff.missing_new_line2-e
62
+ test/fixtures/ldiff/error.diff.missing_new_line2-f
63
+ test/fixtures/ldiff/output.diff
64
+ test/fixtures/ldiff/output.diff-c
65
+ test/fixtures/ldiff/output.diff-u
66
+ test/fixtures/ldiff/output.diff.bin1
67
+ test/fixtures/ldiff/output.diff.bin1-c
68
+ test/fixtures/ldiff/output.diff.bin1-e
69
+ test/fixtures/ldiff/output.diff.bin1-f
70
+ test/fixtures/ldiff/output.diff.bin1-u
71
+ test/fixtures/ldiff/output.diff.bin2
72
+ test/fixtures/ldiff/output.diff.bin2-c
73
+ test/fixtures/ldiff/output.diff.bin2-e
74
+ test/fixtures/ldiff/output.diff.bin2-f
75
+ test/fixtures/ldiff/output.diff.bin2-u
76
+ test/fixtures/ldiff/output.diff.chef
77
+ test/fixtures/ldiff/output.diff.chef-c
78
+ test/fixtures/ldiff/output.diff.chef-u
79
+ test/fixtures/ldiff/output.diff.chef2
80
+ test/fixtures/ldiff/output.diff.chef2-c
81
+ test/fixtures/ldiff/output.diff.chef2-d
82
+ test/fixtures/ldiff/output.diff.chef2-u
83
+ test/fixtures/ldiff/output.diff.empty.vs.four_lines
84
+ test/fixtures/ldiff/output.diff.empty.vs.four_lines-c
85
+ test/fixtures/ldiff/output.diff.empty.vs.four_lines-e
86
+ test/fixtures/ldiff/output.diff.empty.vs.four_lines-f
87
+ test/fixtures/ldiff/output.diff.empty.vs.four_lines-u
88
+ test/fixtures/ldiff/output.diff.four_lines.vs.empty
89
+ test/fixtures/ldiff/output.diff.four_lines.vs.empty-c
90
+ test/fixtures/ldiff/output.diff.four_lines.vs.empty-e
91
+ test/fixtures/ldiff/output.diff.four_lines.vs.empty-f
92
+ test/fixtures/ldiff/output.diff.four_lines.vs.empty-u
93
+ test/fixtures/ldiff/output.diff.issue95_trailing_context
94
+ test/fixtures/ldiff/output.diff.issue95_trailing_context-c
95
+ test/fixtures/ldiff/output.diff.issue95_trailing_context-e
96
+ test/fixtures/ldiff/output.diff.issue95_trailing_context-f
97
+ test/fixtures/ldiff/output.diff.issue95_trailing_context-u
98
+ test/fixtures/ldiff/output.diff.missing_new_line1
99
+ test/fixtures/ldiff/output.diff.missing_new_line1-c
100
+ test/fixtures/ldiff/output.diff.missing_new_line1-e
101
+ test/fixtures/ldiff/output.diff.missing_new_line1-f
102
+ test/fixtures/ldiff/output.diff.missing_new_line1-u
103
+ test/fixtures/ldiff/output.diff.missing_new_line2
104
+ test/fixtures/ldiff/output.diff.missing_new_line2-c
105
+ test/fixtures/ldiff/output.diff.missing_new_line2-e
106
+ test/fixtures/ldiff/output.diff.missing_new_line2-f
107
+ test/fixtures/ldiff/output.diff.missing_new_line2-u
108
+ test/fixtures/new-chef
109
+ test/fixtures/new-chef2
110
+ test/fixtures/old-chef
111
+ test/fixtures/old-chef2
112
+ test/test_block.rb
113
+ test/test_change.rb
114
+ test/test_diff.rb
115
+ test/test_helper.rb
116
+ test/test_hunk.rb
117
+ test/test_issues.rb
118
+ test/test_lcs.rb
119
+ test/test_ldiff.rb
120
+ test/test_patch.rb
121
+ test/test_sdiff.rb
122
+ test/test_traverse_balanced.rb
123
+ test/test_traverse_sequences.rb
data/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # Diff::LCS
2
2
 
3
- - home :: https://github.com/halostatue/diff-lcs
4
- - changelog :: https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md
5
- - code :: https://github.com/halostatue/diff-lcs
6
- - bugs :: https://github.com/halostatue/diff-lcs/issues
7
- - rdoc :: http://rubydoc.info/github/halostatue/diff-lcs
3
+ [![RubyGems Version][shield-gems]][rubygems] ![Coveralls][shield-coveralls]
4
+ [![Build Status][shield-ci]][ci-workflow]
8
5
 
9
- <a href="https://github.com/halostatue/diff-lcs/actions">
10
- <img src="https://github.com/halostatue/diff-lcs/workflows/CI/badge.svg" />
11
- </a>
6
+ - code :: <https://github.com/halostatue/diff-lcs>
7
+ - issues :: <https://github.com/halostatue/diff-lcs/issues>
8
+ - docs :: <https://halostatue.github.io/diff-lcs/>
9
+ - changelog :: <https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md>
12
10
 
13
11
  ## Description
14
12
 
@@ -16,15 +14,23 @@ Diff::LCS computes the difference between two Enumerable sequences using the
16
14
  McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities
17
15
  to create a simple HTML diff output format and a standard diff-like tool.
18
16
 
19
- This is release 1.6.1, providing a simple extension that allows for
20
- Diff::LCS::Change objects to be treated implicitly as arrays and fixes a number
21
- of formatting issues.
17
+ This is release 2.0, which has significant breaking changes (removal of
18
+ deprecations and workarounds) and requires at least Ruby 3.2 or higher. See full
19
+ details in the `CHANGELOG`, but users of diff-lcs should not notice any
20
+ significant changes to the APIs.
22
21
 
23
- Ruby versions below 2.5 are soft-deprecated, which means that older versions are
24
- no longer part of the CI test suite. If any changes have been introduced that
25
- break those versions, bug reports and patches will be accepted, but it will be
26
- up to the reporter to verify any fixes prior to release. The next major release
27
- will completely break compatibility.
22
+ ### Performance and Compatibility
23
+
24
+ I have not run any benchmarks, but the use of immutable Data classes and the
25
+ removal of a number of inner loop conditionals related to encoding and String
26
+ handling (which have been unnecessary since at least Ruby 2.1 but kept for
27
+ strict compatibility) should allow better optimization by modern Ruby
28
+ implementations.
29
+
30
+ If you are using RSpec for your test suite, you are unlikely to be able to use
31
+ Diff::LCS 2.0 because of the minimum Ruby version unless the developers of RSpec
32
+ loosen their version constraints. I cannot control this and have raised
33
+ [rspec/rspec#290][rspec-issue-290].
28
34
 
29
35
  ## Synopsis
30
36
 
@@ -88,5 +94,12 @@ Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor
88
94
  improvements to improve the speed. A simplified description of the algorithm,
89
95
  originally written for the Perl version, was written by Mark-Jason Dominus.
90
96
 
97
+ [ci-workflow]: https://github.com/halostatue/diff-lcs/actions/workflows/ci.yml
98
+ [coveralls]: https://coveralls.io/github/halostatue/diff-lcs?branch=main
99
+ [perl]: https://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
100
+ [rspec-issue-290]: https://github.com/rspec/rspec/issues/290
101
+ [rubygems]: https://rubygems.org/gems/diff-lcs
102
+ [shield-ci]: https://img.shields.io/github/actions/workflow/status/halostatue/diff-lcs/ci.yml?style=for-the-badge "Build Status"
103
+ [shield-coveralls]: https://img.shields.io/coverallsCoverage/github/halostatue/diff-lcs?style=for-the-badge
104
+ [shield-gems]: https://img.shields.io/gem/v/diff-lcs?style=for-the-badge "Version"
91
105
  [smalltalk]: ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
92
- [perl]: http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
data/Rakefile CHANGED
@@ -1,52 +1,24 @@
1
1
  require "rubygems"
2
- require "rspec"
3
- require "rspec/core/rake_task"
4
2
  require "hoe"
5
3
  require "rake/clean"
6
-
7
- MAINTENANCE = ENV["MAINTENANCE"] == "true"
8
- BUILD_DOCS = MAINTENANCE || ENV["DOCS"] == "true"
9
- TRUSTED_RELEASE = ENV["rubygems_release_gem"] == "true"
4
+ require "rdoc/task"
5
+ require "minitest/test_task"
10
6
 
11
7
  Hoe.plugin :halostatue
12
- Hoe.plugin :rubygems
13
8
 
14
9
  Hoe.plugins.delete :debug
15
10
  Hoe.plugins.delete :newb
11
+ Hoe.plugins.delete :publish
16
12
  Hoe.plugins.delete :signing
17
- Hoe.plugins.delete :publish unless BUILD_DOCS
18
-
19
- if RUBY_VERSION < "1.9"
20
- class Array # :nodoc:
21
- def to_h
22
- Hash[*flatten(1)]
23
- end
24
- end
13
+ Hoe.plugins.delete :test
25
14
 
26
- class Gem::Specification # :nodoc:
27
- def metadata=(*)
28
- end
29
-
30
- def default_value(*)
31
- end
32
- end
33
-
34
- class Object # :nodoc:
35
- def caller_locations(*)
36
- []
37
- end
38
- end
39
- end
40
-
41
- _spec = Hoe.spec "diff-lcs" do
15
+ hoe = Hoe.spec "diff-lcs" do
42
16
  developer("Austin Ziegler", "halostatue@gmail.com")
43
17
 
44
- self.trusted_release = TRUSTED_RELEASE
18
+ self.trusted_release = ENV["rubygems_release_gem"] == "true"
45
19
 
46
- require_ruby_version ">= 1.8"
20
+ require_ruby_version ">= 3.2.0", "< 5"
47
21
 
48
- self.history_file = "CHANGELOG.md"
49
- self.readme_file = "README.md"
50
22
  self.licenses = ["MIT", "Artistic-1.0-Perl", "GPL-2.0-or-later"]
51
23
 
52
24
  spec_extras[:metadata] = ->(val) {
@@ -54,62 +26,116 @@ _spec = Hoe.spec "diff-lcs" do
54
26
  }
55
27
 
56
28
  extra_dev_deps << ["hoe", "~> 4.0"]
57
- extra_dev_deps << ["hoe-halostatue", "~> 2.0"]
58
- extra_dev_deps << ["hoe-rubygems", "~> 1.0"]
59
- extra_dev_deps << ["rspec", ">= 2.0", "< 4"]
29
+ extra_dev_deps << ["hoe-halostatue", "~> 3.0"]
30
+ extra_dev_deps << ["minitest", "~> 6.0"]
31
+ extra_dev_deps << ["minitest-autotest", "~> 1.0"]
32
+ extra_dev_deps << ["minitest-focus", "~> 1.1"]
60
33
  extra_dev_deps << ["rake", ">= 10.0", "< 14"]
61
- extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"]
34
+ extra_dev_deps << ["rdoc", ">= 6.0", "< 8"]
35
+ extra_dev_deps << ["simplecov", "~> 0.9"]
36
+ extra_dev_deps << ["simplecov-lcov", "~> 0.9"]
37
+ extra_dev_deps << ["standard", "~> 1.50"]
38
+ extra_dev_deps << ["standard-thread_safety", "~> 1.0"]
39
+ extra_dev_deps << ["fasterer", "~> 0.11"]
62
40
  end
63
41
 
64
- if BUILD_DOCS
65
- rake_tasks = Rake.application.instance_variable_get(:@tasks)
66
- tasks = ["publish_docs", "publish_on_announce", "debug_email", "post_blog", "announce"]
67
- tasks.each do |task|
68
- rake_tasks.delete(task)
42
+ Minitest::TestTask.create :test
43
+ Minitest::TestTask.create :coverage do |t|
44
+ formatters = <<-RUBY.split($/).join(" ")
45
+ SimpleCov::Formatter::MultiFormatter.new([
46
+ SimpleCov::Formatter::HTMLFormatter,
47
+ SimpleCov::Formatter::LcovFormatter,
48
+ SimpleCov::Formatter::SimpleFormatter
49
+ ])
50
+ RUBY
51
+ t.test_prelude = <<-RUBY.split($/).join("; ")
52
+ require "simplecov"
53
+ require "simplecov-lcov"
54
+
55
+ SimpleCov::Formatter::LcovFormatter.config do |config|
56
+ config.report_with_single_file = true
57
+ config.lcov_file_name = "lcov.info"
69
58
  end
70
- end
71
59
 
72
- desc "Run all specifications"
73
- RSpec::Core::RakeTask.new(:spec) do |t|
74
- rspec_dirs = %w[spec lib].join(":")
75
- t.rspec_opts = ["-I#{rspec_dirs}"]
60
+ SimpleCov.start "test_frameworks" do
61
+ enable_coverage :branch
62
+ primary_coverage :branch
63
+ formatter #{formatters}
64
+ end
65
+ RUBY
76
66
  end
77
67
 
68
+ task default: :test
69
+
78
70
  task :version do
79
71
  require "diff/lcs/version"
80
72
  puts Diff::LCS::VERSION
81
73
  end
82
74
 
83
- Rake::Task["spec"].actions.uniq! { |a| a.source_location }
75
+ RDoc::Task.new do |config|
76
+ config.title = "diff-lcs"
77
+ config.main = "README.md"
78
+ config.rdoc_dir = "doc"
79
+ config.rdoc_files = hoe.spec.require_paths + hoe.spec.extra_rdoc_files -
80
+ FileList["integration/golden/*.txt", "Manifest.txt"].to_a
81
+ config.markup = "markdown"
82
+ end
83
+ task docs: :rerdoc
84
84
 
85
- # standard:disable Style/HashSyntax
86
- task :default => :spec unless Rake::Task["default"].prereqs.include?("spec")
87
- task :test => :spec unless Rake::Task["test"].prereqs.include?("spec")
88
- # standard:enable Style/HashSyntax
85
+ def rspec_to_golden(file)
86
+ File.join("integration/golden", File.basename(file, "_spec.rb")) + ".txt"
87
+ end
89
88
 
90
- if RUBY_VERSION >= "3.0" && RUBY_ENGINE == "ruby"
91
- namespace :spec do
92
- desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
93
- task :coverage do
94
- ENV["COVERAGE"] = "true"
95
- Rake::Task["spec"].execute
96
- end
89
+ def normalize_rspec_output(data)
90
+ data
91
+ .gsub(/Randomized with seed \d+/, "Randomized with seed XXXXX")
92
+ .gsub(/Finished in [\d.]+ seconds/, "Finished in X.XXXXX seconds")
93
+ .gsub(/files took [\d.]+ seconds to load/, "files took X.XXXXX seconds to load")
94
+ end
95
+
96
+ def unbundled(&block)
97
+ if defined?(Bundler)
98
+ Bundler.with_unbundled_env(&block)
99
+ else
100
+ block.call
97
101
  end
98
102
  end
99
103
 
100
- if MAINTENANCE
101
- task ruby18: :package do
102
- require "diff/lcs/version"
103
- # standard:disable Layout/HeredocIndentation
104
- puts <<-MESSAGE
105
- You are starting a barebones Ruby 1.8 docker environment for testing.
106
- A snapshot package has been built, so install it with:
104
+ rspecs = FileList["integration/compare/*_spec.rb"]
105
+
106
+ namespace :integration do
107
+ desc "Compare RSpec output with and without diff-lcs 2"
108
+ task :compare do
109
+ require "tempfile"
110
+ base = Tempfile.create("baseline") { _1.path }
111
+ work = Tempfile.create("working") { _1.path }
112
+
113
+ unbundled { sh "gem install rspec" }
107
114
 
108
- cd diff-lcs
109
- gem install pkg/diff-lcs-#{Diff::LCS::VERSION}
115
+ rspecs.to_a.each do |rspec_file|
116
+ basename = File.basename(rspec_file, "_spec.rb")
110
117
 
111
- MESSAGE
112
- # standard:enable Layout/HeredocIndentation
113
- sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l"
118
+ base_contents = unbundled { `integration/runner rspec #{rspec_file} 2>&1` }
119
+ base_contents = normalize_rspec_output(base_contents)
120
+
121
+ work_contents = unbundled { `integration/runner rspec -Ilib -rdiff/lcs #{rspec_file} 2>&1` }
122
+ work_contents = normalize_rspec_output(work_contents)
123
+
124
+ if base_contents == work_contents
125
+ puts "#{basename}: OK"
126
+ else
127
+ puts "#{basename}: FAIL"
128
+
129
+ File.write(base, base_contents)
130
+ File.write(work, work_contents)
131
+
132
+ unbundled { sh "integration/runner -Ilib bin/ldiff -U #{base} #{work}" }
133
+ end
134
+ end
114
135
  end
115
136
  end
137
+
138
+ desc "Run RSpec integration tests with diff-lcs 2.0"
139
+ task integration: ["integration:compare"] do
140
+ sh "rspec -Ilib -r diff/lcs integration/*_spec.rb"
141
+ end
data/SECURITY.md CHANGED
@@ -1,41 +1,36 @@
1
1
  # diff-lcs Security
2
2
 
3
+ ## LLM-Generated Security Report Policy
4
+
5
+ Absolutely no security reports will be accepted that have been generated by LLM
6
+ agents.
7
+
3
8
  ## Supported Versions
4
9
 
5
- Security reports are accepted for the most recent major release and the previous
6
- version for a limited time after the initial major release version. After a
7
- major release, the previous version will receive full support for six months and
8
- security support for an additional six months (for a total of twelve months).
10
+ Security reports are accepted for the most recent major release, with a limited
11
+ window of support after the initial major release.
9
12
 
10
- Because diff-lcs 1.x supports a wide range of Ruby versions, security reports
11
- will only be accepted when they can be demonstrated on Ruby 3.1 or higher.
13
+ - Bug reports will be accepted up to three months after release.
14
+ - Security reports will be accepted up to six months after release.
12
15
 
13
- > [!information]
14
- >
15
- > There will be a diff-lcs 2.0 released in 2025 which narrows support to modern
16
- > versions of Ruby only.
16
+ All issues raised must be demonstrated on the minimum supported Ruby version.
17
+
18
+ > [!important]
17
19
  >
18
- > | Release Date | Support Ends | Security Support Ends |
19
- > | ------------ | ------------ | --------------------- |
20
- > | 2025 | +6 months | +12 months |
20
+ > Because diff-lcs 1 has been the only version for over twenty years, security
21
+ > reports will be accepted for one year after the release of diff-lcs 2.
21
22
  >
22
- > If the 2.0.0 release happens on 2025-07-01, regular support for diff-lcs 1.x
23
- > will end on 2026-12-31 and security support for diff-lcs 1.x will end on
24
- > 2026-06-30.
23
+ > | Version | Release Date | Support Ends | Security Support Ends |
24
+ > | ------- | ------------ | ------------ | --------------------- |
25
+ > | 1.x | 2010 | 2026-05-01 | 2027-02-01 |
26
+ > | 2.x | 2026-02-01 | - | - |
25
27
 
26
28
  ## Reporting a Vulnerability
27
29
 
28
- By preference, use the [Tidelift security contact][tidelift]. Tidelift will
29
- coordinate the fix and disclosure.
30
-
31
- Alternatively, Send an email to [diff-lcs@halostatue.ca][email] with the text
32
- `Diff::LCS` in the subject. Emails sent to this address should be encrypted
33
- using [age][age] with the following public key:
30
+ Report vulnerabilities via the [Tidelift security contact][tidelift]. Tidelift
31
+ will coordinate the fix and disclosure.
34
32
 
35
- ```
36
- age1fc6ngxmn02m62fej5cl30lrvwmxn4k3q2atqu53aatekmnqfwumqj4g93w
37
- ```
33
+ Alternatively, create a [private vulnerability report][advisory] with GitHub.
38
34
 
35
+ [advisory]: https://github.com/halostatue/diff-lcs/security/advisories/new
39
36
  [tidelift]: https://tidelift.com/security
40
- [email]: mailto:diff-lcs@halostatue.ca
41
- [age]: https://github.com/FiloSottile/age
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "Array diff failure" do
4
+ it "shows diff for array with different elements" do
5
+ expected = ["apple", "banana", "cherry", "date", "elderberry"]
6
+ actual = ["apple", "blueberry", "cherry", "date", "elderberry"]
7
+
8
+ expect(actual).to eq(expected)
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "Hash diff failure" do
4
+ it "shows diff for nested hash mismatch" do
5
+ expected = {
6
+ name: "John",
7
+ age: 30,
8
+ address: {
9
+ city: "New York",
10
+ zip: "10001"
11
+ }
12
+ }
13
+
14
+ actual = {
15
+ name: "John",
16
+ age: 35,
17
+ address: {
18
+ city: "Boston",
19
+ zip: "10001"
20
+ }
21
+ }
22
+
23
+ expect(actual).to eq(expected)
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "String diff failure" do
4
+ it "shows diff for multiline string mismatch" do
5
+ expected = "line1\nline2\nline3\nline4\nline5\n"
6
+ actual = "line1\nchanged\nline3\nline4\nline5\n"
7
+
8
+ expect(actual).to eq(expected)
9
+ end
10
+ end