git-lint 4.6.0 → 5.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 (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