git-lint 4.6.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.adoc +235 -30
  4. data/git-lint.gemspec +9 -8
  5. data/lib/git/lint/analyzer.rb +14 -3
  6. data/lib/git/lint/analyzers/abstract.rb +8 -5
  7. data/lib/git/lint/analyzers/commit_author_capitalization.rb +2 -9
  8. data/lib/git/lint/analyzers/commit_author_email.rb +2 -9
  9. data/lib/git/lint/analyzers/commit_author_name.rb +2 -7
  10. data/lib/git/lint/analyzers/commit_body_leading_line.rb +3 -3
  11. data/lib/git/lint/analyzers/commit_body_paragraph_capitalization.rb +9 -6
  12. data/lib/git/lint/analyzers/commit_signature.rb +22 -0
  13. data/lib/git/lint/analyzers/commit_trailer_collaborator_capitalization.rb +9 -17
  14. data/lib/git/lint/analyzers/commit_trailer_collaborator_email.rb +9 -13
  15. data/lib/git/lint/analyzers/commit_trailer_collaborator_key.rb +5 -15
  16. data/lib/git/lint/analyzers/commit_trailer_collaborator_name.rb +9 -15
  17. data/lib/git/lint/analyzers/commit_trailer_duplicate.rb +25 -0
  18. data/lib/git/lint/analyzers/commit_trailer_format_key.rb +33 -0
  19. data/lib/git/lint/analyzers/commit_trailer_format_value.rb +33 -0
  20. data/lib/git/lint/analyzers/commit_trailer_issue_key.rb +33 -0
  21. data/lib/git/lint/analyzers/commit_trailer_issue_value.rb +33 -0
  22. data/lib/git/lint/analyzers/commit_trailer_signer_capitalization.rb +35 -0
  23. data/lib/git/lint/analyzers/commit_trailer_signer_email.rb +39 -0
  24. data/lib/git/lint/analyzers/commit_trailer_signer_key.rb +33 -0
  25. data/lib/git/lint/analyzers/commit_trailer_signer_name.rb +39 -0
  26. data/lib/git/lint/analyzers/commit_trailer_tracker_key.rb +33 -0
  27. data/lib/git/lint/analyzers/commit_trailer_tracker_value.rb +33 -0
  28. data/lib/git/lint/cli/actions/analyze/branch.rb +1 -1
  29. data/lib/git/lint/cli/actions/analyze/commit.rb +8 -11
  30. data/lib/git/lint/cli/actions/hook.rb +4 -2
  31. data/lib/git/lint/commits/loader.rb +2 -2
  32. data/lib/git/lint/commits/systems/circle_ci.rb +5 -3
  33. data/lib/git/lint/commits/systems/git_hub_action.rb +5 -3
  34. data/lib/git/lint/commits/systems/local.rb +5 -3
  35. data/lib/git/lint/commits/systems/netlify_ci.rb +7 -7
  36. data/lib/git/lint/configuration/defaults.yml +58 -15
  37. data/lib/git/lint/container.rb +25 -4
  38. data/lib/git/lint/rake/{tasks.rb → register.rb} +6 -8
  39. data/lib/git/lint/reporters/commit.rb +1 -1
  40. data/lib/git/lint/validators/capitalization.rb +4 -7
  41. data/lib/git/lint/validators/email.rb +3 -4
  42. data/lib/git/lint/validators/name.rb +12 -9
  43. data/lib/git/lint.rb +0 -1
  44. data.tar.gz.sig +0 -0
  45. metadata +44 -21
  46. metadata.gz.sig +0 -0
  47. data/lib/git/lint/analyzers/commit_trailer_collaborator_duplication.rb +0 -46
  48. data/lib/git/lint/parsers/trailers/collaborator.rb +0 -50
  49. data/lib/git/lint/rake/setup.rb +0 -4
@@ -1,24 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "open3"
4
-
5
3
  module Git
6
4
  module Lint
7
5
  module Commits
8
6
  module Systems
9
7
  # Provides Netlify CI build environment feature branch information.
10
8
  class NetlifyCI
11
- include Git::Lint::Import[:repository, :executor, :environment]
9
+ include Git::Lint::Import[:git, :environment]
12
10
 
13
11
  def call
14
- executor.capture3 "git remote add -f origin #{environment["REPOSITORY_URL"]}"
15
- executor.capture3 "git fetch origin #{name}:#{name}"
16
- repository.commits "origin/#{repository.branch_default}..origin/#{name}"
12
+ git.call("remote", "add", "-f", "origin", environment["REPOSITORY_URL"])
13
+ .bind { git.call "fetch", "origin", "#{branch_name}:#{branch_name}" }
14
+ .bind { git.commits "origin/#{branch_default}..origin/#{branch_name}" }
17
15
  end
18
16
 
19
17
  private
20
18
 
21
- def name = environment["HEAD"]
19
+ def branch_default = git.branch_default.value_or nil
20
+
21
+ def branch_name = environment["HEAD"]
22
22
  end
23
23
  end
24
24
  end
@@ -23,18 +23,11 @@
23
23
  :enabled: true
24
24
  :severity: :error
25
25
  :includes: "\\-"
26
- :commit_body_tracker_shorthand:
27
- :enabled: true
28
- :severity: :error
29
- :excludes:
30
- - "(f|F)ix(es|ed)?\\s\\#\\d+"
31
- - "(c|C)lose(s|d)?\\s\\#\\d+"
32
- - "(r|R)esolve(s|d)?\\s\\#\\d+"
33
26
  :commit_body_leading_line:
34
- :enabled: false
27
+ :enabled: true
35
28
  :severity: :warn
36
29
  :commit_body_line_length:
37
- :enabled: true
30
+ :enabled: false
38
31
  :severity: :error
39
32
  :maximum: 72
40
33
  :commit_body_paragraph_capitalization:
@@ -71,13 +64,24 @@
71
64
  - "as\\sfar\\sas\\s.+\\sconcerned"
72
65
  - "of\\sthe\\s(fact|opinion)\\sthat"
73
66
  :commit_body_presence:
74
- :enabled: false
67
+ :enabled: true
75
68
  :severity: :warn
76
69
  :minimum: 1
77
70
  :commit_body_single_bullet:
78
71
  :enabled: true
79
72
  :severity: :error
80
73
  :includes: "\\-"
74
+ :commit_body_tracker_shorthand:
75
+ :enabled: true
76
+ :severity: :error
77
+ :excludes:
78
+ - "(f|F)ix(es|ed)?\\s\\#\\d+"
79
+ - "(c|C)lose(s|d)?\\s\\#\\d+"
80
+ - "(r|R)esolve(s|d)?\\s\\#\\d+"
81
+ :commit_signature:
82
+ :enabled: false
83
+ :severity: :error
84
+ :includes: Good
81
85
  :commit_subject_length:
82
86
  :enabled: true
83
87
  :severity: :error
@@ -102,18 +106,57 @@
102
106
  :commit_trailer_collaborator_capitalization:
103
107
  :enabled: true
104
108
  :severity: :error
105
- :commit_trailer_collaborator_duplication:
106
- :enabled: true
107
- :severity: :error
108
109
  :commit_trailer_collaborator_email:
109
110
  :enabled: true
110
111
  :severity: :error
111
112
  :commit_trailer_collaborator_key:
112
113
  :enabled: true
113
114
  :severity: :error
114
- :includes:
115
- - "Co-Authored-By"
115
+ :includes: Co-Authored-By
116
116
  :commit_trailer_collaborator_name:
117
117
  :enabled: true
118
118
  :severity: :error
119
119
  :minimum: 2
120
+ :commit_trailer_duplicate:
121
+ :enabled: true
122
+ :severity: :error
123
+ :commit_trailer_format_key:
124
+ :enabled: true
125
+ :severity: :error
126
+ :includes: Format
127
+ :commit_trailer_format_value:
128
+ :enabled: true
129
+ :severity: :error
130
+ :includes:
131
+ - ASCII
132
+ - Markdown
133
+ :commit_trailer_issue_key:
134
+ :enabled: true
135
+ :severity: :error
136
+ :includes: Issue
137
+ :commit_trailer_issue_value:
138
+ :enabled: true
139
+ :severity: :error
140
+ :includes: "[\\w-]+"
141
+ :commit_trailer_signer_capitalization:
142
+ :enabled: true
143
+ :severity: :error
144
+ :commit_trailer_signer_email:
145
+ :enabled: true
146
+ :severity: :error
147
+ :commit_trailer_signer_key:
148
+ :enabled: true
149
+ :severity: :error
150
+ :includes: Signed-By
151
+ :commit_trailer_signer_name:
152
+ :enabled: true
153
+ :severity: :error
154
+ :minimum: 2
155
+ :commit_trailer_tracker_key:
156
+ :enabled: true
157
+ :severity: :error
158
+ :includes: Tracker
159
+ :commit_trailer_tracker_value:
160
+ :enabled: true
161
+ :severity: :error
162
+ :includes: "[\\w\\-\\s]+"
@@ -2,8 +2,7 @@
2
2
 
3
3
  require "cogger"
4
4
  require "dry-container"
5
- require "git_plus"
6
- require "open3"
5
+ require "gitt"
7
6
  require "spek"
8
7
 
9
8
  module Git
@@ -14,11 +13,33 @@ module Git
14
13
 
15
14
  register(:configuration) { Configuration::Loader.call }
16
15
  register(:environment) { ENV }
17
- register(:repository) { GitPlus::Repository.new }
16
+ register(:git) { Gitt::Repository.new }
18
17
  register(:specification) { Spek::Loader.call "#{__dir__}/../../../git-lint.gemspec" }
19
18
  register(:kernel) { Kernel }
20
- register(:executor) { Open3 }
21
19
  register(:logger) { Cogger::Client.new }
20
+
21
+ namespace :trailers do
22
+ register(:collaborator) { /\ACo.*Authored.*By.*\Z/i }
23
+ register(:format) { /\AFormat.*\Z/i }
24
+ register(:issue) { /\AIssue.*\Z/i }
25
+ register(:signer) { /\ASigned.*By.*\Z/i }
26
+ register(:tracker) { /\ATracker.*\Z/i }
27
+ end
28
+
29
+ namespace :parsers do
30
+ register(:person) { Gitt::Parsers::Person.new }
31
+ end
32
+
33
+ namespace :sanitizers do
34
+ register(:email) { Gitt::Sanitizers::Email }
35
+ register(:signature) { Gitt::Sanitizers::Signature }
36
+ end
37
+
38
+ namespace :validators do
39
+ register(:capitalization) { Validators::Capitalization.new }
40
+ register(:email) { Validators::Email.new }
41
+ register(:name) { Validators::Name.new }
42
+ end
22
43
  end
23
44
  end
24
45
  end
@@ -1,26 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rake"
4
3
  require "git/lint"
4
+ require "rake"
5
5
 
6
6
  module Git
7
7
  module Lint
8
8
  module Rake
9
- # Defines and installs Rake tasks for use in downstream projects.
10
- class Tasks
9
+ # Registers Rake tasks for use.
10
+ class Register
11
11
  include ::Rake::DSL
12
12
 
13
- def self.setup = new.install
13
+ def self.call = new.call
14
14
 
15
15
  def initialize shell: CLI::Shell.new
16
16
  @shell = shell
17
17
  end
18
18
 
19
- def install
19
+ def call
20
20
  desc "Run Git Lint"
21
- task :git_lint do
22
- shell.call ["--analyze"]
23
- end
21
+ task(:git_lint) { shell.call ["--analyze"] }
24
22
  end
25
23
 
26
24
  private
@@ -13,7 +13,7 @@ module Git
13
13
  def to_s
14
14
  return "" if analyzers.empty?
15
15
 
16
- "#{commit.sha} (#{commit.author_name}, #{commit.author_date_relative}): " \
16
+ "#{commit.sha} (#{commit.author_name}, #{commit.authored_relative_at}): " \
17
17
  "#{commit.subject}\n#{report}\n"
18
18
  end
19
19
 
@@ -5,21 +5,18 @@ module Git
5
5
  module Validators
6
6
  # Validates the capitalizationn of text.
7
7
  class Capitalization
8
- DEFAULT_PATTERN = /\A[[:upper:]].*\Z/
8
+ PATTERN = /\A[[:upper:]].*\Z/
9
9
 
10
- def initialize text, delimiter: Name::DEFAULT_DELIMITER, pattern: DEFAULT_PATTERN
11
- @text = String text
10
+ def initialize delimiter: Name::DELIMITER, pattern: PATTERN
12
11
  @delimiter = delimiter
13
12
  @pattern = pattern
14
13
  end
15
14
 
16
- def valid? = parts.all? { |name| String(name).match? pattern }
15
+ def call(content) = String(content).split(delimiter).all? { |name| name.match? pattern }
17
16
 
18
17
  private
19
18
 
20
- attr_reader :text, :delimiter, :pattern
21
-
22
- def parts = text.split(delimiter)
19
+ attr_reader :delimiter, :pattern
23
20
  end
24
21
  end
25
22
  end
@@ -7,16 +7,15 @@ module Git
7
7
  module Validators
8
8
  # Validates the format of email addresses.
9
9
  class Email
10
- def initialize text, pattern: URI::MailTo::EMAIL_REGEXP
11
- @text = text
10
+ def initialize pattern: URI::MailTo::EMAIL_REGEXP
12
11
  @pattern = pattern
13
12
  end
14
13
 
15
- def valid? = String(text).match?(pattern)
14
+ def call(content) = String(content).match? pattern
16
15
 
17
16
  private
18
17
 
19
- attr_reader :text, :pattern
18
+ attr_reader :pattern
20
19
  end
21
20
  end
22
21
  end
@@ -1,26 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "refinements/strings"
4
+
3
5
  module Git
4
6
  module Lint
5
7
  module Validators
6
8
  # Validates the format of names.
7
9
  class Name
8
- DEFAULT_DELIMITER = /\s{1}/
9
- DEFAULT_MINIMUM = 2
10
+ using Refinements::Strings
11
+
12
+ DELIMITER = /\s{1}/
13
+ MINIMUM = 2
10
14
 
11
- def initialize text, delimiter: DEFAULT_DELIMITER, minimum: DEFAULT_MINIMUM
12
- @text = text
15
+ def initialize delimiter: DELIMITER
13
16
  @delimiter = delimiter
14
- @minimum = minimum
15
17
  end
16
18
 
17
- def valid? = parts.size >= minimum && parts.all? { |name| !String(name).empty? }
19
+ def call content, minimum: MINIMUM
20
+ parts = String(content).split delimiter
21
+ parts.size >= minimum && parts.all? { |name| !name.blank? }
22
+ end
18
23
 
19
24
  private
20
25
 
21
- attr_reader :text, :delimiter, :minimum
22
-
23
- def parts = String(text).split(delimiter)
26
+ attr_reader :delimiter
24
27
  end
25
28
  end
26
29
  end
data/lib/git/lint.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zeitwerk"
4
- require "git_plus"
5
4
 
6
5
  Zeitwerk::Loader.new.then do |loader|
7
6
  loader.inflector.inflect "cli" => "CLI",
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,7 +28,7 @@ cert_chain:
28
28
  CxDe2+VuChj4I1nvIHdu+E6XoEVlanUPKmSg6nddhkKn2gC45Kyzh6FZqnzH/CRp
29
29
  RFE=
30
30
  -----END CERTIFICATE-----
31
- date: 2022-10-22 00:00:00.000000000 Z
31
+ date: 2022-12-27 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: cogger
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0.4'
39
+ version: '0.5'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0.4'
46
+ version: '0.5'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: dry-container
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -59,33 +59,47 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0.11'
61
61
  - !ruby/object:Gem::Dependency
62
- name: git_plus
62
+ name: dry-monads
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '1.7'
67
+ version: '1.6'
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '1.7'
74
+ version: '1.6'
75
+ - !ruby/object:Gem::Dependency
76
+ name: gitt
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
75
89
  - !ruby/object:Gem::Dependency
76
90
  name: infusible
77
91
  requirement: !ruby/object:Gem::Requirement
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: '0.2'
95
+ version: '1.0'
82
96
  type: :runtime
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: '0.2'
102
+ version: '1.0'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: pastel
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -106,42 +120,42 @@ dependencies:
106
120
  requirements:
107
121
  - - "~>"
108
122
  - !ruby/object:Gem::Version
109
- version: '9.7'
123
+ version: '10.0'
110
124
  type: :runtime
111
125
  prerelease: false
112
126
  version_requirements: !ruby/object:Gem::Requirement
113
127
  requirements:
114
128
  - - "~>"
115
129
  - !ruby/object:Gem::Version
116
- version: '9.7'
130
+ version: '10.0'
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: runcom
119
133
  requirement: !ruby/object:Gem::Requirement
120
134
  requirements:
121
135
  - - "~>"
122
136
  - !ruby/object:Gem::Version
123
- version: '8.7'
137
+ version: '9.0'
124
138
  type: :runtime
125
139
  prerelease: false
126
140
  version_requirements: !ruby/object:Gem::Requirement
127
141
  requirements:
128
142
  - - "~>"
129
143
  - !ruby/object:Gem::Version
130
- version: '8.7'
144
+ version: '9.0'
131
145
  - !ruby/object:Gem::Dependency
132
146
  name: spek
133
147
  requirement: !ruby/object:Gem::Requirement
134
148
  requirements:
135
149
  - - "~>"
136
150
  - !ruby/object:Gem::Version
137
- version: '0.6'
151
+ version: '1.0'
138
152
  type: :runtime
139
153
  prerelease: false
140
154
  version_requirements: !ruby/object:Gem::Requirement
141
155
  requirements:
142
156
  - - "~>"
143
157
  - !ruby/object:Gem::Version
144
- version: '0.6'
158
+ version: '1.0'
145
159
  - !ruby/object:Gem::Dependency
146
160
  name: zeitwerk
147
161
  requirement: !ruby/object:Gem::Requirement
@@ -186,14 +200,25 @@ files:
186
200
  - lib/git/lint/analyzers/commit_body_presence.rb
187
201
  - lib/git/lint/analyzers/commit_body_single_bullet.rb
188
202
  - lib/git/lint/analyzers/commit_body_tracker_shorthand.rb
203
+ - lib/git/lint/analyzers/commit_signature.rb
189
204
  - lib/git/lint/analyzers/commit_subject_length.rb
190
205
  - lib/git/lint/analyzers/commit_subject_prefix.rb
191
206
  - lib/git/lint/analyzers/commit_subject_suffix.rb
192
207
  - lib/git/lint/analyzers/commit_trailer_collaborator_capitalization.rb
193
- - lib/git/lint/analyzers/commit_trailer_collaborator_duplication.rb
194
208
  - lib/git/lint/analyzers/commit_trailer_collaborator_email.rb
195
209
  - lib/git/lint/analyzers/commit_trailer_collaborator_key.rb
196
210
  - lib/git/lint/analyzers/commit_trailer_collaborator_name.rb
211
+ - lib/git/lint/analyzers/commit_trailer_duplicate.rb
212
+ - lib/git/lint/analyzers/commit_trailer_format_key.rb
213
+ - lib/git/lint/analyzers/commit_trailer_format_value.rb
214
+ - lib/git/lint/analyzers/commit_trailer_issue_key.rb
215
+ - lib/git/lint/analyzers/commit_trailer_issue_value.rb
216
+ - lib/git/lint/analyzers/commit_trailer_signer_capitalization.rb
217
+ - lib/git/lint/analyzers/commit_trailer_signer_email.rb
218
+ - lib/git/lint/analyzers/commit_trailer_signer_key.rb
219
+ - lib/git/lint/analyzers/commit_trailer_signer_name.rb
220
+ - lib/git/lint/analyzers/commit_trailer_tracker_key.rb
221
+ - lib/git/lint/analyzers/commit_trailer_tracker_value.rb
197
222
  - lib/git/lint/cli/actions/analyze/branch.rb
198
223
  - lib/git/lint/cli/actions/analyze/commit.rb
199
224
  - lib/git/lint/cli/actions/config.rb
@@ -222,9 +247,7 @@ files:
222
247
  - lib/git/lint/errors/sha.rb
223
248
  - lib/git/lint/import.rb
224
249
  - lib/git/lint/kit/filter_list.rb
225
- - lib/git/lint/parsers/trailers/collaborator.rb
226
- - lib/git/lint/rake/setup.rb
227
- - lib/git/lint/rake/tasks.rb
250
+ - lib/git/lint/rake/register.rb
228
251
  - lib/git/lint/reporters/branch.rb
229
252
  - lib/git/lint/reporters/commit.rb
230
253
  - lib/git/lint/reporters/line.rb
@@ -253,14 +276,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
253
276
  requirements:
254
277
  - - "~>"
255
278
  - !ruby/object:Gem::Version
256
- version: '3.1'
279
+ version: '3.2'
257
280
  required_rubygems_version: !ruby/object:Gem::Requirement
258
281
  requirements:
259
282
  - - ">="
260
283
  - !ruby/object:Gem::Version
261
284
  version: '0'
262
285
  requirements: []
263
- rubygems_version: 3.3.24
286
+ rubygems_version: 3.4.1
264
287
  signing_key:
265
288
  specification_version: 4
266
289
  summary: A command line interface for linting Git commits.
metadata.gz.sig CHANGED
Binary file
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- module Analyzers
6
- # Analyzes commit trailer collaborator duplication.
7
- class CommitTrailerCollaboratorDuplication < Abstract
8
- def initialize commit, parser: Parsers::Trailers::Collaborator, **dependencies
9
- super commit, **dependencies
10
- @parser = parser
11
- @tally = build_tally
12
- end
13
-
14
- def valid? = affected_commit_trailers.empty?
15
-
16
- def issue
17
- return {} if valid?
18
-
19
- {
20
- hint: "Avoid duplication.",
21
- lines: affected_commit_trailers
22
- }
23
- end
24
-
25
- protected
26
-
27
- def invalid_line? line
28
- collaborator = parser.new line
29
- collaborator.match? && tally[line] != 1
30
- end
31
-
32
- private
33
-
34
- attr_reader :parser, :tally
35
-
36
- def build_tally
37
- zeros = Hash.new { |new_hash, missing_key| new_hash[missing_key] = 0 }
38
-
39
- zeros.tap do |collection|
40
- commit.trailers.each { |line| collection[line] += 1 if parser.new(line).match? }
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- module Parsers
6
- module Trailers
7
- # Parses collaborator information within a commit trailer.
8
- class Collaborator
9
- DEFAULT_KEY_PATTERN = /\ACo.*Authored.*By.*\Z/i
10
-
11
- DEFAULT_MATCH_PATTERN = /
12
- (?<key>\A.+) # Key (anchored to start of line).
13
- (?<delimiter>:) # Key delimiter.
14
- (?<key_space>\s?) # Space delimiter (optional).
15
- (?<name>.*?) # Collaborator name (smallest possible).
16
- (?<name_space>\s?) # Space delimiter (optional).
17
- (?<email><.+>)? # Collaborator email (optional).
18
- \Z # End of line.
19
- /x
20
-
21
- def initialize text,
22
- key_pattern: DEFAULT_KEY_PATTERN,
23
- match_pattern: DEFAULT_MATCH_PATTERN
24
-
25
- @text = String text
26
- @key_pattern = key_pattern
27
- @match_pattern = match_pattern
28
- @matches = build_matches
29
- end
30
-
31
- def key = String(matches["key"])
32
-
33
- def name = String(matches["name"])
34
-
35
- def email = String(matches["email"]).delete_prefix("<").delete_suffix(">")
36
-
37
- def match? = text.match?(key_pattern)
38
-
39
- private
40
-
41
- attr_reader :text, :key_pattern, :match_pattern, :matches
42
-
43
- def build_matches
44
- text.match(match_pattern).then { |data| data ? data.named_captures : Hash.new }
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "git/lint/rake/tasks"
4
- Git::Lint::Rake::Tasks.setup