github_diff_parser 0.1.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +24 -17
- data/lib/github_diff_parser/diff.rb +86 -3
- data/lib/github_diff_parser/parser.rb +16 -1
- data/lib/github_diff_parser/regexes.rb +22 -2
- data/lib/github_diff_parser/version.rb +1 -1
- data/lib/github_diff_parser.rb +1 -0
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d048ece303a1deffcfd8c90f1f9ff01ae8ecd3e4cd933227b4e6fe37b895e82
|
4
|
+
data.tar.gz: 81f8202228089acd92296c2504ec8689598a59ff01fdac8df3c089e9d1bb7658
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9edb9abb99bf74763577a06801429e2accb3af1b806a434d83f1ea518a694411fd528c080e5fefeed9ab603ac405861d631e416cbc5236f77b6f6e4ac52fb36
|
7
|
+
data.tar.gz: ca25e44f9e0cc56fdc3044ea85b09e4f59e9a2cca5f172f44b50d5570dda436228b1b1c8b905b890a7bdcc7d1097e1c1876d75927291bfe34d3f4619cd7b35b7
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## Unreleased
|
8
|
+
|
9
|
+
## [1.1.0] - 2024-2-21
|
10
|
+
### Added
|
11
|
+
- Github Diff Parser parses the permissions bits and you now have have access to various method
|
12
|
+
such as:
|
13
|
+
- `GithubDiffParser::Diff#normal_file?` when the bits are 100644
|
14
|
+
- `GithubDiffParser::Diff#executable?` when the bits are 107555
|
15
|
+
- `GithubDiffParser::Diff#symlink?` when the bits are 120000
|
16
|
+
- Introduce `GithubDiffParser::Diff#symlink_source`. When the diff applies to a symbolic link, `symlink_source` will
|
17
|
+
return the path to where the symbolic link points to.
|
18
|
+
- Introduce `GithubDiffParser::Diff#apply`, a simple implementation of `git apply`.
|
19
|
+
- Introduce `GithubDiffParser::Diff#revert`, a simple implementation of `git apply -R`.
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
- `GithubDiffParser::Line#content` didn't include `\n` (if the line had one).
|
data/Gemfile.lock
CHANGED
@@ -1,39 +1,46 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
github_diff_parser (
|
4
|
+
github_diff_parser (1.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
ast (2.4.2)
|
10
10
|
byebug (11.1.3)
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
json (2.6.3)
|
12
|
+
language_server-protocol (3.17.0.3)
|
13
|
+
minitest (5.18.1)
|
14
|
+
parallel (1.23.0)
|
15
|
+
parser (3.2.2.3)
|
14
16
|
ast (~> 2.4.1)
|
17
|
+
racc
|
18
|
+
racc (1.7.1)
|
15
19
|
rainbow (3.1.1)
|
16
20
|
rake (13.0.6)
|
17
|
-
regexp_parser (2.
|
21
|
+
regexp_parser (2.8.1)
|
18
22
|
rexml (3.2.5)
|
19
|
-
rubocop (1.
|
23
|
+
rubocop (1.53.1)
|
24
|
+
json (~> 2.3)
|
25
|
+
language_server-protocol (>= 3.17.0)
|
20
26
|
parallel (~> 1.10)
|
21
|
-
parser (>= 3.
|
27
|
+
parser (>= 3.2.2.3)
|
22
28
|
rainbow (>= 2.2.2, < 4.0)
|
23
29
|
regexp_parser (>= 1.8, < 3.0)
|
24
|
-
rexml
|
25
|
-
rubocop-ast (>= 1.
|
30
|
+
rexml (>= 3.2.5, < 4.0)
|
31
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
26
32
|
ruby-progressbar (~> 1.7)
|
27
|
-
unicode-display_width (>=
|
28
|
-
rubocop-ast (1.
|
29
|
-
parser (>= 3.
|
30
|
-
rubocop-shopify (2.
|
31
|
-
rubocop (~> 1.
|
32
|
-
ruby-progressbar (1.
|
33
|
-
unicode-display_width (2.
|
33
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
34
|
+
rubocop-ast (1.29.0)
|
35
|
+
parser (>= 3.2.1.0)
|
36
|
+
rubocop-shopify (2.14.0)
|
37
|
+
rubocop (~> 1.51)
|
38
|
+
ruby-progressbar (1.13.0)
|
39
|
+
unicode-display_width (2.4.2)
|
34
40
|
|
35
41
|
PLATFORMS
|
36
42
|
x86_64-darwin-20
|
43
|
+
x86_64-darwin-22
|
37
44
|
x86_64-linux
|
38
45
|
|
39
46
|
DEPENDENCIES
|
@@ -44,4 +51,4 @@ DEPENDENCIES
|
|
44
51
|
rubocop-shopify
|
45
52
|
|
46
53
|
BUNDLED WITH
|
47
|
-
2.
|
54
|
+
2.4.14
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module GithubDiffParser
|
4
4
|
class Diff
|
5
|
+
Mode = Struct.new(:operation, :bits)
|
6
|
+
|
5
7
|
# @return [String] (see #initialize)
|
6
8
|
attr_reader :previous_filename
|
7
9
|
|
@@ -11,8 +13,19 @@ module GithubDiffParser
|
|
11
13
|
# @return [Array<GithubDiffParser::Hunk>] the hunks belonging to this diff
|
12
14
|
attr_reader :hunks
|
13
15
|
|
16
|
+
# @return [String] the hash of the previous file. This is indicate in the diff
|
17
|
+
# by the line `index abc..def`. The +abc+ part is the previous_index.
|
18
|
+
attr_reader :previous_index
|
19
|
+
|
20
|
+
# @return [String] the hash of the new file. This is indicate in the diff
|
21
|
+
# by the line `index abc..def`. The +def+ part is the previous_index.
|
22
|
+
attr_reader :new_index
|
23
|
+
|
14
24
|
# @private
|
15
|
-
attr_writer :
|
25
|
+
attr_writer :previous_index, :new_index
|
26
|
+
|
27
|
+
# @private
|
28
|
+
attr_accessor :mode
|
16
29
|
|
17
30
|
# @param previous_filename [String] the original filename. Represented by "diff --git /a filename"
|
18
31
|
# @param new_filename [String] the new filename. Represented by "diff --git /b filename"
|
@@ -22,6 +35,11 @@ module GithubDiffParser
|
|
22
35
|
@hunks = []
|
23
36
|
end
|
24
37
|
|
38
|
+
# Get all the lines in this diff. Shortcut for `diff.hunks.each { |h| h.lines }`
|
39
|
+
def lines
|
40
|
+
hunks.flat_map(&:lines)
|
41
|
+
end
|
42
|
+
|
25
43
|
# Add a Git Hunk to the diff.
|
26
44
|
#
|
27
45
|
# @param previous_lino_start [String] the starting line number of the hunk for the original file
|
@@ -60,7 +78,7 @@ module GithubDiffParser
|
|
60
78
|
#
|
61
79
|
# @return [Boolean]
|
62
80
|
def deleted_mode?
|
63
|
-
@
|
81
|
+
@mode.operation == "deleted"
|
64
82
|
end
|
65
83
|
|
66
84
|
# Check if this Diff is set to new mode.
|
@@ -76,7 +94,7 @@ module GithubDiffParser
|
|
76
94
|
#
|
77
95
|
# @return [Boolean]
|
78
96
|
def new_mode?
|
79
|
-
@
|
97
|
+
@mode.operation == "new"
|
80
98
|
end
|
81
99
|
|
82
100
|
# Check if this Diff is set to rename mode.
|
@@ -92,6 +110,29 @@ module GithubDiffParser
|
|
92
110
|
previous_filename != new_filename
|
93
111
|
end
|
94
112
|
|
113
|
+
# @return [Boolean] True if this diff applies to a regular file.
|
114
|
+
def normal_file?
|
115
|
+
@mode.bits == "100644"
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [Boolean] True if this diff applies to an executable.
|
119
|
+
def executable?
|
120
|
+
@mode.bits == "100755"
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return [Boolean] True if this diff applies to a symlink.
|
124
|
+
def symlink?
|
125
|
+
@mode.bits == "120000"
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [String] The source of the symlink
|
129
|
+
# @raise If this diff doesn't apply to a symlink
|
130
|
+
def symlink_source
|
131
|
+
raise(Error, "This diff doen't apply to a symbolic link") unless symlink?
|
132
|
+
|
133
|
+
lines.first.content
|
134
|
+
end
|
135
|
+
|
95
136
|
# A utility method that returns the current number of a line who might not be present in the diff.
|
96
137
|
# This is useful if you need to keep track of the updated line numbers in a file for every changes.
|
97
138
|
#
|
@@ -111,6 +152,48 @@ module GithubDiffParser
|
|
111
152
|
end
|
112
153
|
end
|
113
154
|
|
155
|
+
# A naive implementation of `$ git apply`.
|
156
|
+
#
|
157
|
+
# @param previous_content [String] The previous content related to this diff.
|
158
|
+
# @return [String] The content after applying this diff to the `previous_content`.
|
159
|
+
def apply(previous_content)
|
160
|
+
lines = previous_content.lines
|
161
|
+
offset = 0
|
162
|
+
|
163
|
+
self.lines.each do |line|
|
164
|
+
if line.addition?
|
165
|
+
lines.insert(line.current_number - 1, line.content)
|
166
|
+
offset += 1
|
167
|
+
elsif line.deletion?
|
168
|
+
lines.delete_at(line.previous_number - 1 + offset)
|
169
|
+
offset -= 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
lines.join
|
174
|
+
end
|
175
|
+
|
176
|
+
# A naive implementation of `$ git apply -R`.
|
177
|
+
#
|
178
|
+
# @param current_content [String] The current content related to this diff.
|
179
|
+
# @return [String] The content after reverting this diff to the `current_content`.
|
180
|
+
def revert(current_content)
|
181
|
+
lines = current_content.lines
|
182
|
+
offset = 0
|
183
|
+
|
184
|
+
self.lines.each do |line|
|
185
|
+
if line.addition?
|
186
|
+
lines.delete_at(line.current_number - 1 + offset)
|
187
|
+
offset -= 1
|
188
|
+
elsif line.deletion?
|
189
|
+
lines.insert(line.previous_number - 1, line.content)
|
190
|
+
offset += 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
lines.join
|
195
|
+
end
|
196
|
+
|
114
197
|
private
|
115
198
|
|
116
199
|
# Check if a line was shifted. A line is considered shifted if its number is superior to the first hunk's start
|
@@ -18,6 +18,8 @@ module GithubDiffParser
|
|
18
18
|
case line
|
19
19
|
when Regexes::DIFF_HEADER
|
20
20
|
process_new_diff(Regexp.last_match)
|
21
|
+
when Regexes::INDEX_HEADER
|
22
|
+
process_index(Regexp.last_match)
|
21
23
|
when Regexes::MODE_HEADER
|
22
24
|
process_diff_file_mode(Regexp.last_match)
|
23
25
|
when Regexes::ORIGINAL_FILE_HEADER, Regexes::NEW_FILE_HEADER
|
@@ -26,6 +28,8 @@ module GithubDiffParser
|
|
26
28
|
add_hunk_to_diff(Regexp.last_match)
|
27
29
|
when Regexes::LINE_DIFF
|
28
30
|
add_line_to_hunk(Regexp.last_match)
|
31
|
+
when Regexes::NO_NEWLINE_AT_EOF
|
32
|
+
@current_diff.lines.last.content.sub!(/\n$/, "")
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
@@ -47,6 +51,17 @@ module GithubDiffParser
|
|
47
51
|
@current_diff = Diff.new(match_data[:previous_filename], match_data[:new_filename])
|
48
52
|
end
|
49
53
|
|
54
|
+
# Called when encountering a `index abc..def` in the Git Diff output.
|
55
|
+
#
|
56
|
+
# @param match_data [MatchData]
|
57
|
+
def process_index(match_data)
|
58
|
+
validate_diff
|
59
|
+
|
60
|
+
@current_diff.previous_index = match_data[:previous_index]
|
61
|
+
@current_diff.new_index = match_data[:new_index]
|
62
|
+
@current_diff.mode ||= Diff::Mode.new("modified", match_data[:bits])
|
63
|
+
end
|
64
|
+
|
50
65
|
# Called when encountering a `new file mode 100644` or `delete file mode 100644` in the Git Diff output.
|
51
66
|
#
|
52
67
|
# @param match_data [MatchData]
|
@@ -55,7 +70,7 @@ module GithubDiffParser
|
|
55
70
|
def process_diff_file_mode(match_data)
|
56
71
|
validate_diff
|
57
72
|
|
58
|
-
@current_diff.
|
73
|
+
@current_diff.mode = Diff::Mode.new(match_data[:file_mode], match_data[:bits])
|
59
74
|
end
|
60
75
|
|
61
76
|
# Called when encountering a `@@ -0,0 +1,10 @@` in the Git Diff output.
|
@@ -19,6 +19,24 @@ module GithubDiffParser
|
|
19
19
|
\Z # End of line
|
20
20
|
}x
|
21
21
|
|
22
|
+
# This Regexp is used to match the sha of the previous and the file
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
#
|
26
|
+
# diff --git a/app/my_file.rb b/app/my_file.rb
|
27
|
+
# index d3dfbe4..ac0e8b3 100644 <-- Match this line -->
|
28
|
+
# --- a/app/my_file.rb
|
29
|
+
# +++ b/app/my_file.rb
|
30
|
+
# @@ -5,6 +5,6 @@ def test1
|
31
|
+
INDEX_HEADER = %r{
|
32
|
+
\A # Start of line
|
33
|
+
index\s # Match 'index '
|
34
|
+
(?<previous_index>[a-z0-9]+) # Match and capture alphanumerical chars
|
35
|
+
.. # Match '..' literally
|
36
|
+
(?<new_index>[a-z0-9]+)\s # Match and capture alphanumerical chars
|
37
|
+
(?<bits>\d+)? # Optionaly capture the mode bits
|
38
|
+
}x
|
39
|
+
|
22
40
|
# This Regexp is used to match the header containing the original filename.
|
23
41
|
#
|
24
42
|
# @example Possible header on a diff.
|
@@ -71,7 +89,7 @@ module GithubDiffParser
|
|
71
89
|
MODE_HEADER = %r{
|
72
90
|
\A # Start of line
|
73
91
|
(?<file_mode>new|deleted) # Match 'new' or 'deleted' and capture the group
|
74
|
-
\sfile\smode\s
|
92
|
+
\sfile\smode\s(?<bits>\d+) # Match ' file mode 100655' and capture the "100655" part
|
75
93
|
\Z # End of line
|
76
94
|
}x
|
77
95
|
|
@@ -153,8 +171,10 @@ module GithubDiffParser
|
|
153
171
|
| # OR
|
154
172
|
\s # Match empty space ' ' (Considered as a contextual line)
|
155
173
|
) # End of named group
|
156
|
-
(?<line
|
174
|
+
(?<line>.*\n?) # Match the content of the line itself
|
157
175
|
\Z # End of line
|
158
176
|
}x
|
177
|
+
|
178
|
+
NO_NEWLINE_AT_EOF = /\/
|
159
179
|
end
|
160
180
|
end
|
data/lib/github_diff_parser.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_diff_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edouard CHIN
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -46,6 +46,7 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- ".rubocop.yml"
|
49
|
+
- CHANGELOG.md
|
49
50
|
- CODE_OF_CONDUCT.md
|
50
51
|
- Gemfile
|
51
52
|
- Gemfile.lock
|
@@ -61,13 +62,13 @@ files:
|
|
61
62
|
- lib/github_diff_parser/parser.rb
|
62
63
|
- lib/github_diff_parser/regexes.rb
|
63
64
|
- lib/github_diff_parser/version.rb
|
64
|
-
homepage: https://github.com/
|
65
|
+
homepage: https://github.com/CatanaCorp/github_diff_parser
|
65
66
|
licenses:
|
66
67
|
- MIT
|
67
68
|
metadata:
|
68
69
|
allowed_push_host: https://rubygems.org
|
69
|
-
homepage_uri: https://github.com/
|
70
|
-
source_code_uri: https://github.com/
|
70
|
+
homepage_uri: https://github.com/CatanaCorp/github_diff_parser
|
71
|
+
source_code_uri: https://github.com/CatanaCorp/github_diff_parser
|
71
72
|
rubygems_mfa_required: 'true'
|
72
73
|
post_install_message:
|
73
74
|
rdoc_options: []
|
@@ -77,14 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
78
|
requirements:
|
78
79
|
- - ">="
|
79
80
|
- !ruby/object:Gem::Version
|
80
|
-
version:
|
81
|
+
version: 3.0.0
|
81
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
83
|
requirements:
|
83
84
|
- - ">="
|
84
85
|
- !ruby/object:Gem::Version
|
85
86
|
version: '0'
|
86
87
|
requirements: []
|
87
|
-
rubygems_version: 3.
|
88
|
+
rubygems_version: 3.5.4
|
88
89
|
signing_key:
|
89
90
|
specification_version: 4
|
90
91
|
summary: A Ruby Gem to parse unified git diff output.
|