github_diff_parser 1.0.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 +1 -1
- data/lib/github_diff_parser/diff.rb +73 -3
- data/lib/github_diff_parser/parser.rb +4 -1
- data/lib/github_diff_parser/regexes.rb +6 -3
- data/lib/github_diff_parser/version.rb +1 -1
- data/lib/github_diff_parser.rb +1 -0
- metadata +4 -3
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
@@ -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
|
|
@@ -20,7 +22,10 @@ module GithubDiffParser
|
|
20
22
|
attr_reader :new_index
|
21
23
|
|
22
24
|
# @private
|
23
|
-
attr_writer :
|
25
|
+
attr_writer :previous_index, :new_index
|
26
|
+
|
27
|
+
# @private
|
28
|
+
attr_accessor :mode
|
24
29
|
|
25
30
|
# @param previous_filename [String] the original filename. Represented by "diff --git /a filename"
|
26
31
|
# @param new_filename [String] the new filename. Represented by "diff --git /b filename"
|
@@ -73,7 +78,7 @@ module GithubDiffParser
|
|
73
78
|
#
|
74
79
|
# @return [Boolean]
|
75
80
|
def deleted_mode?
|
76
|
-
@
|
81
|
+
@mode.operation == "deleted"
|
77
82
|
end
|
78
83
|
|
79
84
|
# Check if this Diff is set to new mode.
|
@@ -89,7 +94,7 @@ module GithubDiffParser
|
|
89
94
|
#
|
90
95
|
# @return [Boolean]
|
91
96
|
def new_mode?
|
92
|
-
@
|
97
|
+
@mode.operation == "new"
|
93
98
|
end
|
94
99
|
|
95
100
|
# Check if this Diff is set to rename mode.
|
@@ -105,6 +110,29 @@ module GithubDiffParser
|
|
105
110
|
previous_filename != new_filename
|
106
111
|
end
|
107
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
|
+
|
108
136
|
# A utility method that returns the current number of a line who might not be present in the diff.
|
109
137
|
# This is useful if you need to keep track of the updated line numbers in a file for every changes.
|
110
138
|
#
|
@@ -124,6 +152,48 @@ module GithubDiffParser
|
|
124
152
|
end
|
125
153
|
end
|
126
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
|
+
|
127
197
|
private
|
128
198
|
|
129
199
|
# Check if a line was shifted. A line is considered shifted if its number is superior to the first hunk's start
|
@@ -28,6 +28,8 @@ module GithubDiffParser
|
|
28
28
|
add_hunk_to_diff(Regexp.last_match)
|
29
29
|
when Regexes::LINE_DIFF
|
30
30
|
add_line_to_hunk(Regexp.last_match)
|
31
|
+
when Regexes::NO_NEWLINE_AT_EOF
|
32
|
+
@current_diff.lines.last.content.sub!(/\n$/, "")
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
@@ -57,6 +59,7 @@ module GithubDiffParser
|
|
57
59
|
|
58
60
|
@current_diff.previous_index = match_data[:previous_index]
|
59
61
|
@current_diff.new_index = match_data[:new_index]
|
62
|
+
@current_diff.mode ||= Diff::Mode.new("modified", match_data[:bits])
|
60
63
|
end
|
61
64
|
|
62
65
|
# Called when encountering a `new file mode 100644` or `delete file mode 100644` in the Git Diff output.
|
@@ -67,7 +70,7 @@ module GithubDiffParser
|
|
67
70
|
def process_diff_file_mode(match_data)
|
68
71
|
validate_diff
|
69
72
|
|
70
|
-
@current_diff.
|
73
|
+
@current_diff.mode = Diff::Mode.new(match_data[:file_mode], match_data[:bits])
|
71
74
|
end
|
72
75
|
|
73
76
|
# Called when encountering a `@@ -0,0 +1,10 @@` in the Git Diff output.
|
@@ -33,7 +33,8 @@ module GithubDiffParser
|
|
33
33
|
index\s # Match 'index '
|
34
34
|
(?<previous_index>[a-z0-9]+) # Match and capture alphanumerical chars
|
35
35
|
.. # Match '..' literally
|
36
|
-
(?<new_index>[a-z0-9]+)
|
36
|
+
(?<new_index>[a-z0-9]+)\s # Match and capture alphanumerical chars
|
37
|
+
(?<bits>\d+)? # Optionaly capture the mode bits
|
37
38
|
}x
|
38
39
|
|
39
40
|
# This Regexp is used to match the header containing the original filename.
|
@@ -88,7 +89,7 @@ module GithubDiffParser
|
|
88
89
|
MODE_HEADER = %r{
|
89
90
|
\A # Start of line
|
90
91
|
(?<file_mode>new|deleted) # Match 'new' or 'deleted' and capture the group
|
91
|
-
\sfile\smode\s
|
92
|
+
\sfile\smode\s(?<bits>\d+) # Match ' file mode 100655' and capture the "100655" part
|
92
93
|
\Z # End of line
|
93
94
|
}x
|
94
95
|
|
@@ -170,8 +171,10 @@ module GithubDiffParser
|
|
170
171
|
| # OR
|
171
172
|
\s # Match empty space ' ' (Considered as a contextual line)
|
172
173
|
) # End of named group
|
173
|
-
(?<line
|
174
|
+
(?<line>.*\n?) # Match the content of the line itself
|
174
175
|
\Z # End of line
|
175
176
|
}x
|
177
|
+
|
178
|
+
NO_NEWLINE_AT_EOF = /\/
|
176
179
|
end
|
177
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: 1.
|
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
|
@@ -84,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
85
|
- !ruby/object:Gem::Version
|
85
86
|
version: '0'
|
86
87
|
requirements: []
|
87
|
-
rubygems_version: 3.4
|
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.
|