danger-rubocop 0.11.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a25805f10b9265549f39e7efb812f9b940d317727b031a8546aaa34e87a6f57
4
- data.tar.gz: 553e742ad2d0780f441a0bb443bcc24b18afd2d26a78fec7cb92b9f7b5abafe1
3
+ metadata.gz: 228bd1f2c8294e6ade21c5a33424af6ddfa0ceb08613f62ca22db33bdfecd212
4
+ data.tar.gz: cafedd57a18b594548ef05c3287fd96acbf9a5692306e291ad85f7cf3456e6ad
5
5
  SHA512:
6
- metadata.gz: df8c319c5b617f7ee5e2698e0db2d2610eeac3007dc3b5d183261295608aaba1805ae496f3b70897a7570bc79f222ed8be6f1af6859d3a0b5d2f6090377a297c
7
- data.tar.gz: 8611653f86ad51b236dd4f4b7104e4776c8748d30cfdbc47f70bad2e82580aff9e46b8b8726ccfd1261f48e719ac3459b123871864ca0ddda5ff87e86d5a06d2
6
+ metadata.gz: e30f4a47b31ce14a58e263da6a7d0cd80a81c016b989be786487393d60f45a131bbabf76f4dbbb08b22058331d1878ff30ddd917cceb3db1e34b5f3cb85fd039
7
+ data.tar.gz: 705e56f918fe479ee9633f513aaa9ce3396616456112be2d4fa2b1f9358b9c58c620f367ba8cedbb6159e5463d2bad2168e3fd1a949ff3477e6696b4fd24acc4
data/Gemfile.lock CHANGED
@@ -52,7 +52,8 @@ GEM
52
52
  faraday-net_http_persistent (1.1.0)
53
53
  ffi (1.15.0)
54
54
  formatador (0.2.5)
55
- git (1.8.1)
55
+ git (1.13.1)
56
+ addressable (~> 2.8)
56
57
  rchardet (~> 1.8)
57
58
  guard (2.16.2)
58
59
  formatador (>= 0.2.4)
@@ -107,7 +108,8 @@ GEM
107
108
  ffi (~> 1.0)
108
109
  rchardet (1.8.0)
109
110
  regexp_parser (2.1.1)
110
- rexml (3.2.5)
111
+ rexml (3.2.8)
112
+ strscan (>= 3.0.9)
111
113
  rspec (3.10.0)
112
114
  rspec-core (~> 3.10.0)
113
115
  rspec-expectations (~> 3.10.0)
@@ -138,11 +140,12 @@ GEM
138
140
  addressable (>= 2.3.5)
139
141
  faraday (> 0.8, < 2.0)
140
142
  shellany (0.0.1)
143
+ strscan (3.1.0)
141
144
  terminal-table (3.0.1)
142
145
  unicode-display_width (>= 1.1.1, < 3)
143
146
  thor (1.1.0)
144
147
  unicode-display_width (2.0.0)
145
- yard (0.9.26)
148
+ yard (0.9.36)
146
149
 
147
150
  PLATFORMS
148
151
  ruby
data/README.md CHANGED
@@ -57,15 +57,17 @@ The following keys are supported:
57
57
  (this option will instruct rubocop to ignore the files that your rubocop config ignores,
58
58
  despite the plugin providing the list of files explicitly)
59
59
  * `inline_comment`: pass `true` to comment inline of the diffs.
60
+ * `group_inline_comments`: pass `true` to group inline comments to be a single comment on each line with all issues for that line.
60
61
  * `fail_on_inline_comment`: pass `true` to use `fail` instead of `warn` on inline comment.
61
62
  * `report_severity`: pass `true` to use `fail` or `warn` based on Rubocop severity.
62
63
  * `report_danger`: pass true to report errors to Danger, and break CI.
64
+ * `include_cop_names`: pass true to include cop names when reporting errors with `report_danger`.
63
65
  * `config`: path to the `.rubocop.yml` file.
64
66
  * `only_report_new_offenses`: pass `true` to only report offenses that are in current user's scope.
65
67
  Note that this won't mark offenses for _Metrics/XXXLength_ if you add lines to an already existing scope.
66
68
  * `include_cop_names`: Prepends cop names to the output messages. Example: "Layout/EmptyLinesAroundBlockBody: Extra empty line detected at block body end."
67
69
  * `rubocop_cmd`: Allows you to change the rubocop executable that's invoked. This is used to support rubocop wrappers like [Standard](https://github.com/testdouble/standard/) by passing `standardrb` as the value.
68
-
70
+ * `skip_bundle_exec`: When there is a `Gemfile` in the project, Rubocop will be executed using [Bundler](https://bundler.io). When `true`, this flag will force Rubocop to run without `bundle exec`.
69
71
 
70
72
  Passing `files` as only argument is also supported for backward compatibility.
71
73
 
data/lib/danger_plugin.rb CHANGED
@@ -34,18 +34,22 @@ module Danger
34
34
  report_danger = config[:report_danger] || false
35
35
  only_report_new_offenses = config[:only_report_new_offenses] || false
36
36
  inline_comment = config[:inline_comment] || false
37
+ group_inline_comments = config[:group_inline_comments] || false
37
38
  fail_on_inline_comment = config[:fail_on_inline_comment] || false
38
39
  report_severity = config[:report_severity] || false
39
40
  include_cop_names = config[:include_cop_names] || false
40
41
  rubocop_cmd = config[:rubocop_cmd] || 'rubocop'
42
+ skip_bundle_exec = config[:skip_bundle_exec] || false
41
43
 
42
44
  files_to_lint = fetch_files_to_lint(files)
43
- files_to_report = rubocop(files_to_lint, force_exclusion, only_report_new_offenses, cmd: rubocop_cmd, config_path: config_path)
45
+ files_to_report = rubocop(files_to_lint, force_exclusion, only_report_new_offenses, cmd: rubocop_cmd, config_path: config_path, skip_bundle_exec: skip_bundle_exec)
44
46
 
45
47
  return if files_to_report.empty?
46
- return report_failures files_to_report if report_danger
48
+ return report_failures(files_to_report, include_cop_names: include_cop_names) if report_danger
47
49
 
48
- if inline_comment
50
+ if inline_comment && group_inline_comments
51
+ add_grouped_violation_for_each_line(files_to_report, fail_on_inline_comment, report_severity, include_cop_names: include_cop_names)
52
+ elsif inline_comment
49
53
  add_violation_for_each_line(files_to_report, fail_on_inline_comment, report_severity, include_cop_names: include_cop_names)
50
54
  else
51
55
  markdown offenses_message(files_to_report, include_cop_names: include_cop_names)
@@ -54,12 +58,12 @@ module Danger
54
58
 
55
59
  private
56
60
 
57
- def rubocop(files_to_lint, force_exclusion, only_report_new_offenses, cmd: 'rubocop', config_path: nil)
61
+ def rubocop(files_to_lint, force_exclusion, only_report_new_offenses, cmd: 'rubocop', config_path: nil, skip_bundle_exec: false)
58
62
  base_command = [cmd, '-f', 'json', '--only-recognized-file-types']
59
63
  base_command.concat(['--force-exclusion']) if force_exclusion
60
64
  base_command.concat(['--config', config_path.shellescape]) unless config_path.nil?
61
65
 
62
- rubocop_output = `#{'bundle exec ' if File.exist?('Gemfile')}#{base_command.join(' ')} #{files_to_lint}`
66
+ rubocop_output = `#{'bundle exec ' if File.exist?('Gemfile') && !skip_bundle_exec}#{base_command.join(' ')} #{files_to_lint}`
63
67
 
64
68
  return [] if rubocop_output.empty?
65
69
 
@@ -108,8 +112,7 @@ module Danger
108
112
  style: { border_i: '|' },
109
113
  rows: offending_files.flat_map do |file|
110
114
  file['offenses'].map do |offense|
111
- offense_message = offense['message']
112
- offense_message = offense['cop_name'] + ': ' + offense_message if include_cop_names
115
+ offense_message = offense_message(offense, include_cop_names: include_cop_names)
113
116
  [file['path'], offense['location']['line'], offense_message]
114
117
  end
115
118
  end
@@ -117,10 +120,11 @@ module Danger
117
120
  message + table.split("\n")[1..-2].join("\n")
118
121
  end
119
122
 
120
- def report_failures(offending_files)
123
+ def report_failures(offending_files, include_cop_names: false)
121
124
  offending_files.each do |file|
122
125
  file['offenses'].each do |offense|
123
- fail "#{file['path']} | #{offense['location']['line']} | #{offense['message']}"
126
+ offense_message = offense_message(offense, include_cop_names: include_cop_names)
127
+ fail "#{file['path']} | #{offense['location']['line']} | #{offense_message}"
124
128
  end
125
129
  end
126
130
  end
@@ -128,8 +132,7 @@ module Danger
128
132
  def add_violation_for_each_line(offending_files, fail_on_inline_comment, report_severity, include_cop_names: false)
129
133
  offending_files.flat_map do |file|
130
134
  file['offenses'].map do |offense|
131
- offense_message = offense['message']
132
- offense_message = offense['cop_name'] + ': ' + offense_message if include_cop_names
135
+ offense_message = offense_message(offense, include_cop_names: include_cop_names)
133
136
  kargs = {
134
137
  file: file['path'],
135
138
  line: offense['location']['line']
@@ -145,6 +148,37 @@ module Danger
145
148
  end
146
149
  end
147
150
 
151
+ def add_grouped_violation_for_each_line(offending_files, fail_on_inline_comment, report_severity, include_cop_names: false)
152
+ grouped_offense_messages = Hash.new { |h, k| h[k] = [] }
153
+ offending_files.flat_map do |file|
154
+ file['offenses'].map do |offense|
155
+ offense_message = offense_message(offense, include_cop_names: include_cop_names)
156
+ kargs = {
157
+ file: file['path'],
158
+ line: offense['location']['line']
159
+ }
160
+ grouped_offense_messages[kargs] << offense_message
161
+ end
162
+ end
163
+
164
+ grouped_offense_messages.each do |kargs, offense_messages|
165
+ grouped_offense_message = if offense_messages.length > 1
166
+ "\n" + offense_messages.map do |offense_message|
167
+ "* #{offense_message}"
168
+ end.join("\n")
169
+ else
170
+ offense_messages[0]
171
+ end
172
+ if fail_on_inline_comment
173
+ fail(grouped_offense_message, **kargs)
174
+ elsif report_severity && %w[error fatal].include?(offense['severity'])
175
+ fail(grouped_offense_message, **kargs)
176
+ else
177
+ warn(grouped_offense_message, **kargs)
178
+ end
179
+ end
180
+ end
181
+
148
182
  def fetch_files_to_lint(files = nil)
149
183
  to_lint = if files.nil?
150
184
  # when files are renamed, git.modified_files contains the old name not the new one, so we need to do the convertion
@@ -155,5 +189,11 @@ module Danger
155
189
  end
156
190
  Shellwords.join(to_lint)
157
191
  end
192
+
193
+ def offense_message(offense, include_cop_names: false)
194
+ return offense['message'] unless include_cop_names
195
+
196
+ "#{offense['cop_name']}: #{offense['message']}"
197
+ end
158
198
  end
159
199
  end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DangerRubocop
2
- VERSION = '0.11.0'.freeze
2
+ VERSION = '0.13.0'.freeze
3
3
  end
@@ -299,7 +299,7 @@ EOS
299
299
  end
300
300
 
301
301
  context 'with fail_on_inline_comment option' do
302
- it 'reports violations as line by line failures' do
302
+ before do
303
303
  allow(@rubocop.git).to receive(:modified_files)
304
304
  .and_return(['spec/fixtures/ruby_file.rb'])
305
305
  allow(@rubocop.git).to receive(:added_files).and_return([])
@@ -307,64 +307,176 @@ EOS
307
307
  allow(@rubocop).to receive(:`)
308
308
  .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/ruby_file.rb')
309
309
  .and_return(response_ruby_file)
310
+ end
310
311
 
312
+ it 'reports violations as line by line failures' do
311
313
  @rubocop.lint(fail_on_inline_comment: true, inline_comment: true)
312
314
 
313
315
  expect(@rubocop.violation_report[:errors].first.to_s)
314
316
  .to eq("Violation Don't do that! { sticky: false, file: spec/fixtures/ruby_file.rb, line: 13, type: error }")
315
317
  end
316
- end
317
-
318
- context 'with report_severity option' do
319
- context 'file with error' do
320
- it 'reports violations by rubocop severity' do
321
- allow(@rubocop.git).to receive(:added_files).and_return([])
322
- allow(@rubocop.git).to receive(:modified_files)
323
- .and_return(["spec/fixtures/another_ruby_file.rb"])
324
- allow(@rubocop.git).to receive(:renamed_files).and_return([])
325
318
 
326
- allow(@rubocop).to receive(:`)
327
- .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/another_ruby_file.rb')
328
- .and_return(response_another_ruby_file)
319
+ it 'includes cop names when include_cop_names is set' do
320
+ @rubocop.lint(fail_on_inline_comment: true, inline_comment: true, include_cop_names: true)
329
321
 
330
- @rubocop.lint(report_severity: true, inline_comment: true)
322
+ expect(@rubocop.violation_report[:errors].first.to_s)
323
+ .to eq("Violation Syntax/WhetherYouShouldDoThat: Don't do that! { sticky: false, file: spec/fixtures/ruby_file.rb, line: 13, type: error }")
324
+ end
325
+ end
331
326
 
332
- expect(@rubocop.violation_report[:errors].first.to_s)
333
- .to eq("Violation Don't do that! { sticky: false, file: spec/fixtures/another_ruby_file.rb, line: 23, type: error }")
327
+ context 'with group_inline_comments' do
328
+ context 'with multiple violations on the same line' do
329
+ let(:response_ruby_file) do
330
+ {
331
+ 'files' => [
332
+ {
333
+ 'path' => 'spec/fixtures/ruby_file.rb',
334
+ 'offenses' => [
335
+ {
336
+ 'cop_name' => 'Syntax/WhetherYouShouldDoThat',
337
+ 'message' => "Don't do that!",
338
+ 'severity' => 'warning',
339
+ 'location' => { 'line' => 13 }
340
+ },
341
+ {
342
+ 'cop_name' => 'Syntax/WhetherYouShouldDoThat',
343
+ 'message' => "Also don't do that!",
344
+ 'severity' => 'warning',
345
+ 'location' => { 'line' => 13 }
346
+ }
347
+ ]
348
+ }
349
+ ]
350
+ }.to_json
334
351
  end
335
- end
336
352
 
337
- context 'file with warning' do
338
- it 'reports violations by rubocop severity' do
339
- allow(@rubocop.git).to receive(:added_files).and_return([])
353
+ it 'reports multiple violations grouped by line in a bulleted list' do
340
354
  allow(@rubocop.git).to receive(:modified_files)
341
- .and_return(["spec/fixtures/ruby_file.rb"])
355
+ .and_return(['spec/fixtures/ruby_file.rb'])
356
+ allow(@rubocop.git).to receive(:added_files).and_return([])
342
357
  allow(@rubocop.git).to receive(:renamed_files).and_return([])
343
-
344
358
  allow(@rubocop).to receive(:`)
345
359
  .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/ruby_file.rb')
346
360
  .and_return(response_ruby_file)
347
361
 
348
- @rubocop.lint(report_severity: true, inline_comment: true)
349
-
350
- expect(@rubocop.violation_report[:warnings].first.to_s)
351
- .to eq("Violation Don't do that! { sticky: false, file: spec/fixtures/ruby_file.rb, line: 13, type: warning }")
362
+ @rubocop.lint(inline_comment: true, group_inline_comments: true)
363
+
364
+ warning = @rubocop.violation_report[:warnings].first
365
+ expect(warning.file)
366
+ .to eq("spec/fixtures/ruby_file.rb")
367
+ expect(warning.line)
368
+ .to eq(13)
369
+ expect(warning.message)
370
+ .to eq(
371
+ <<~HEREDOC
372
+
373
+ * Don't do that!
374
+ * Also don't do that!
375
+ HEREDOC
376
+ .chomp
377
+ )
352
378
  end
353
379
  end
354
- end
355
380
 
356
- context 'using standardrb cmd' do
357
- it 'executes using the standardrb cmd' do
381
+ it 'reports single violations grouped by line as normal line by line warnings' do
382
+ allow(@rubocop.git).to receive(:modified_files)
383
+ .and_return(['spec/fixtures/ruby_file.rb'])
384
+ allow(@rubocop.git).to receive(:added_files).and_return([])
385
+ allow(@rubocop.git).to receive(:renamed_files).and_return([])
358
386
  allow(@rubocop).to receive(:`)
359
- .with('bundle exec standardrb -f json --only-recognized-file-types --config path/to/rubocop.yml spec/fixtures/ruby_file.rb')
387
+ .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/ruby_file.rb')
360
388
  .and_return(response_ruby_file)
361
389
 
362
- # Do it
363
- @rubocop.lint(files: 'spec/fixtures/ruby*.rb', rubocop_cmd: 'standardrb', config: 'path/to/rubocop.yml')
390
+ @rubocop.lint(inline_comment: true, group_inline_comments: true)
391
+
392
+ warning = @rubocop.violation_report[:warnings].first
393
+ expect(warning.file)
394
+ .to eq("spec/fixtures/ruby_file.rb")
395
+ expect(warning.line)
396
+ .to eq(13)
397
+ expect(warning.message)
398
+ .to eq("Don't do that!")
399
+ end
400
+ end
401
+ end
402
+
403
+ context 'with report_severity option' do
404
+ context 'file with error' do
405
+ it 'reports violations by rubocop severity' do
406
+ allow(@rubocop.git).to receive(:added_files).and_return([])
407
+ allow(@rubocop.git).to receive(:modified_files)
408
+ .and_return(["spec/fixtures/another_ruby_file.rb"])
409
+ allow(@rubocop.git).to receive(:renamed_files).and_return([])
410
+
411
+ allow(@rubocop).to receive(:`)
412
+ .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/another_ruby_file.rb')
413
+ .and_return(response_another_ruby_file)
414
+
415
+ @rubocop.lint(report_severity: true, inline_comment: true)
416
+
417
+ expect(@rubocop.violation_report[:errors].first.to_s)
418
+ .to eq("Violation Don't do that! { sticky: false, file: spec/fixtures/another_ruby_file.rb, line: 23, type: error }")
364
419
  end
365
420
  end
366
421
  end
367
422
 
423
+ context 'file with warning' do
424
+ it 'reports violations by rubocop severity' do
425
+ allow(@rubocop.git).to receive(:added_files).and_return([])
426
+ allow(@rubocop.git).to receive(:modified_files)
427
+ .and_return(["spec/fixtures/ruby_file.rb"])
428
+ allow(@rubocop.git).to receive(:renamed_files).and_return([])
429
+
430
+ allow(@rubocop).to receive(:`)
431
+ .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/ruby_file.rb')
432
+ .and_return(response_ruby_file)
433
+
434
+ @rubocop.lint(report_severity: true, inline_comment: true)
435
+
436
+ expect(@rubocop.violation_report[:warnings].first.to_s)
437
+ .to eq("Violation Don't do that! { sticky: false, file: spec/fixtures/ruby_file.rb, line: 13, type: warning }")
438
+ end
439
+ end
440
+
441
+ context 'using standardrb cmd' do
442
+ it 'executes using the standardrb cmd' do
443
+ allow(@rubocop).to receive(:`)
444
+ .with('bundle exec standardrb -f json --only-recognized-file-types --config path/to/rubocop.yml spec/fixtures/ruby_file.rb')
445
+ .and_return(response_ruby_file)
446
+
447
+ # Do it
448
+ @rubocop.lint(files: 'spec/fixtures/ruby*.rb', rubocop_cmd: 'standardrb', config: 'path/to/rubocop.yml')
449
+ end
450
+ end
451
+
452
+ context 'using Bundler' do
453
+ it 'uses `bundle exec` when there is a Gemfile' do
454
+ allow(@rubocop).to receive(:`)
455
+ .with('bundle exec rubocop -f json --only-recognized-file-types --config path/to/rubocop.yml spec/fixtures/ruby_file.rb')
456
+ .and_return(response_ruby_file)
457
+
458
+ @rubocop.lint(files: 'spec/fixtures/ruby*.rb', config: 'path/to/rubocop.yml')
459
+ end
460
+
461
+ it 'doesn\'t use `bundle exec` when there is no Gemfile' do
462
+ allow(File).to receive(:exist?).with('Gemfile').and_return(false)
463
+
464
+ allow(@rubocop).to receive(:`)
465
+ .with('rubocop -f json --only-recognized-file-types --config path/to/rubocop.yml spec/fixtures/ruby_file.rb')
466
+ .and_return(response_ruby_file)
467
+
468
+ @rubocop.lint(files: 'spec/fixtures/ruby*.rb', config: 'path/to/rubocop.yml')
469
+ end
470
+
471
+ it 'doesn\'t use `bundle exec` when there is a Gemfile but skip_bundle_exec is true' do
472
+ allow(@rubocop).to receive(:`)
473
+ .with('rubocop -f json --only-recognized-file-types --config path/to/rubocop.yml spec/fixtures/ruby_file.rb')
474
+ .and_return(response_ruby_file)
475
+
476
+ @rubocop.lint(files: 'spec/fixtures/ruby*.rb', config: 'path/to/rubocop.yml', skip_bundle_exec: true)
477
+ end
478
+ end
479
+
368
480
  describe 'a filename with special characters' do
369
481
  it 'is shell escaped' do
370
482
  modified_files = [
@@ -382,8 +494,7 @@ EOS
382
494
  end
383
495
 
384
496
  describe 'report to danger' do
385
- let(:fail_msg) { %{spec/fixtures/ruby_file.rb | 13 | Don't do that!} }
386
- it 'reports to danger' do
497
+ before do
387
498
  allow(@rubocop.git).to receive(:modified_files)
388
499
  .and_return(['spec/fixtures/ruby_file.rb'])
389
500
  allow(@rubocop.git).to receive(:added_files).and_return([])
@@ -391,10 +502,20 @@ EOS
391
502
  allow(@rubocop).to receive(:`)
392
503
  .with('bundle exec rubocop -f json --only-recognized-file-types spec/fixtures/ruby_file.rb')
393
504
  .and_return(response_ruby_file)
505
+ end
394
506
 
507
+ it 'reports to danger' do
508
+ fail_msg = %{spec/fixtures/ruby_file.rb | 13 | Don't do that!}
395
509
  expect(@rubocop).to receive(:fail).with(fail_msg)
396
510
  @rubocop.lint(report_danger: true)
397
511
  end
512
+
513
+ it 'includes cop names when include_cop_names is set' do
514
+ fail_msg = %{spec/fixtures/ruby_file.rb | 13 | Syntax/WhetherYouShouldDoThat: Don't do that!}
515
+
516
+ expect(@rubocop).to receive(:fail).with(fail_msg)
517
+ @rubocop.lint(report_danger: true, include_cop_names: true)
518
+ end
398
519
  end
399
520
  end
400
521
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danger-rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ash Furrow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-16 00:00:00.000000000 Z
11
+ date: 2024-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: danger
@@ -192,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
192
  - !ruby/object:Gem::Version
193
193
  version: '0'
194
194
  requirements: []
195
- rubygems_version: 3.3.13
195
+ rubygems_version: 3.4.10
196
196
  signing_key:
197
197
  specification_version: 4
198
198
  summary: A Danger plugin for running Ruby files through Rubocop.