rubocop 1.13.0 → 1.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/config/default.yml +68 -8
  4. data/lib/rubocop.rb +9 -0
  5. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -3
  6. data/lib/rubocop/cop/bundler/gem_version.rb +99 -0
  7. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
  8. data/lib/rubocop/cop/layout/argument_alignment.rb +29 -11
  9. data/lib/rubocop/cop/layout/case_indentation.rb +57 -9
  10. data/lib/rubocop/cop/layout/dot_position.rb +7 -1
  11. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +13 -15
  12. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +12 -0
  13. data/lib/rubocop/cop/layout/hash_alignment.rb +34 -9
  14. data/lib/rubocop/cop/layout/indentation_width.rb +13 -2
  15. data/lib/rubocop/cop/layout/redundant_line_break.rb +24 -10
  16. data/lib/rubocop/cop/layout/single_line_block_chain.rb +53 -0
  17. data/lib/rubocop/cop/layout/space_around_keyword.rb +28 -0
  18. data/lib/rubocop/cop/layout/space_around_operators.rb +6 -0
  19. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +83 -39
  20. data/lib/rubocop/cop/lint/empty_block.rb +18 -2
  21. data/lib/rubocop/cop/lint/empty_in_pattern.rb +62 -0
  22. data/lib/rubocop/cop/lint/literal_as_condition.rb +13 -1
  23. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +32 -17
  24. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  25. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +105 -74
  26. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -0
  27. data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -12
  28. data/lib/rubocop/cop/lint/unreachable_loop.rb +12 -2
  29. data/lib/rubocop/cop/lint/unused_block_argument.rb +7 -1
  30. data/lib/rubocop/cop/lint/void.rb +1 -1
  31. data/lib/rubocop/cop/migration/department_name.rb +3 -1
  32. data/lib/rubocop/cop/mixin/check_line_breakable.rb +19 -3
  33. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +6 -0
  34. data/lib/rubocop/cop/mixin/gem_declaration.rb +13 -0
  35. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +14 -3
  36. data/lib/rubocop/cop/mixin/string_literals_help.rb +3 -5
  37. data/lib/rubocop/cop/mixin/symbol_help.rb +13 -0
  38. data/lib/rubocop/cop/style/class_and_module_children.rb +17 -5
  39. data/lib/rubocop/cop/style/empty_literal.rb +8 -1
  40. data/lib/rubocop/cop/style/hash_each_methods.rb +18 -1
  41. data/lib/rubocop/cop/style/identical_conditional_branches.rb +58 -8
  42. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -4
  43. data/lib/rubocop/cop/style/in_pattern_then.rb +56 -0
  44. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -1
  45. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +62 -0
  46. data/lib/rubocop/cop/style/multiline_when_then.rb +2 -11
  47. data/lib/rubocop/cop/style/negated_if_else_condition.rb +17 -9
  48. data/lib/rubocop/cop/style/nil_lambda.rb +29 -12
  49. data/lib/rubocop/cop/style/quoted_symbols.rb +110 -0
  50. data/lib/rubocop/cop/style/raise_args.rb +2 -0
  51. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  52. data/lib/rubocop/cop/style/redundant_self.rb +24 -2
  53. data/lib/rubocop/cop/style/regexp_literal.rb +9 -1
  54. data/lib/rubocop/cop/style/single_line_methods.rb +8 -3
  55. data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
  56. data/lib/rubocop/cop/style/string_literals.rb +1 -0
  57. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -0
  58. data/lib/rubocop/cop/style/top_level_method_definition.rb +83 -0
  59. data/lib/rubocop/cop/style/trivial_accessors.rb +65 -0
  60. data/lib/rubocop/cop/style/when_then.rb +6 -2
  61. data/lib/rubocop/cop/variable_force/branch.rb +15 -0
  62. data/lib/rubocop/directive_comment.rb +58 -6
  63. data/lib/rubocop/formatter/junit_formatter.rb +21 -6
  64. data/lib/rubocop/options.rb +14 -20
  65. data/lib/rubocop/rake_task.rb +1 -1
  66. data/lib/rubocop/remote_config.rb +10 -2
  67. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  68. data/lib/rubocop/target_finder.rb +9 -2
  69. data/lib/rubocop/target_ruby.rb +1 -1
  70. data/lib/rubocop/version.rb +1 -1
  71. metadata +18 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 580e325f7dc471739e2f4857d82e279776098ae14fff7367eaa803f688c9e58d
4
- data.tar.gz: c8331c8b2ebbecb239d4a63dee21375172d1d2939572516bba910109ef5375a1
3
+ metadata.gz: f038acc03307acfc14ddf1dd971bf78978fac3401b4588b78b6bab4f4b7d8e13
4
+ data.tar.gz: 4f5da9053cce2f82b955f15d311d4b0d1f78396b2d49c8672c27d380804d5ba8
5
5
  SHA512:
6
- metadata.gz: 5f9ecd1e28e7fa7946b22aaecc0d5571337d85ca6b9a198e9542a9d26d05c9d0806597ccd66d0090c4318d349c7023fe201103fa197eaa88d5e98534d25ff755
7
- data.tar.gz: 4bc7ec5d20c127826a1761b9495669242d53b740509ca13060c1202d0114062fb73a52738b9fb717f5348fdad7cb2a2fb5ee0ea4cc8a9b5823298908a0ce6a5b
6
+ metadata.gz: 6c4b743259b607ed588066f260b69cfdfd03772cd89f533eaf80705e689005a771ef76cf29873d73c0e5f97e3b7b4be6e6080a5890a63ebb19150d951ae272e1
7
+ data.tar.gz: 7505601eb0e34cc563cb8b7efdec9b6340e709f6a29eec7a7b952f84386df60fe8912b8ebd0849d9ba59e22e7701b980276f8bd728330985d5fa9bdf99c2d9ad
data/README.md CHANGED
@@ -29,6 +29,8 @@ RuboCop is extremely flexible and most aspects of its behavior can be tweaked vi
29
29
  [![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-sponsors)
30
30
  [![Tidelift](https://tidelift.com/badges/package/rubygems/rubocop)](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source=rubygems-rubocop&utm_medium=referral&utm_campaign=readme)
31
31
 
32
+ Working on RuboCop is often fun, but it also requires a great deal of time and energy.
33
+
32
34
  **Please consider [financially supporting its ongoing development](#funding).**
33
35
 
34
36
  ## Installation
@@ -52,7 +54,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
52
54
  in your `Gemfile`:
53
55
 
54
56
  ```rb
55
- gem 'rubocop', '~> 1.13', require: false
57
+ gem 'rubocop', '~> 1.17', require: false
56
58
  ```
57
59
 
58
60
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -130,7 +130,7 @@ AllCops:
130
130
  # What MRI version of the Ruby interpreter is the inspected code intended to
131
131
  # run on? (If there is more than one, set this to the lowest version.)
132
132
  # If a value is specified for TargetRubyVersion then it is used. Acceptable
133
- # values are specificed as a float (i.e. 2.5); the teeny version of Ruby
133
+ # values are specificed as a float (i.e. 3.0); the teeny version of Ruby
134
134
  # should not be included. If the project specifies a Ruby version in the
135
135
  # .tool-versions or .ruby-version files, Gemfile or gems.rb file, RuboCop will
136
136
  # try to determine the desired version of Ruby by inspecting the
@@ -138,7 +138,7 @@ AllCops:
138
138
  # or gems.locked file. (Although the Ruby version is specified in the Gemfile
139
139
  # or gems.rb file, RuboCop reads the final value from the lock file.) If the
140
140
  # Ruby version is still unresolved, RuboCop will use the oldest officially
141
- # supported Ruby version (currently Ruby 2.4).
141
+ # supported Ruby version (currently Ruby 2.5).
142
142
  TargetRubyVersion: ~
143
143
  # Determines if a notification for extension libraries should be shown when
144
144
  # rubocop is run. Keys are the name of the extension, and values are an array
@@ -174,6 +174,20 @@ Bundler/GemComment:
174
174
  IgnoredGems: []
175
175
  OnlyFor: []
176
176
 
177
+ Bundler/GemVersion:
178
+ Description: 'Requires or forbids specifying gem versions.'
179
+ Enabled: false
180
+ VersionAdded: '1.14'
181
+ EnforcedStyle: 'required'
182
+ SupportedStyles:
183
+ - 'required'
184
+ - 'forbidden'
185
+ Include:
186
+ - '**/*.gemfile'
187
+ - '**/Gemfile'
188
+ - '**/gems.rb'
189
+ AllowedGems: []
190
+
177
191
  Bundler/InsecureProtocolSource:
178
192
  Description: >-
179
193
  The source `:gemcutter`, `:rubygems` and `:rubyforge` are deprecated
@@ -363,10 +377,11 @@ Layout/BlockEndNewline:
363
377
  VersionAdded: '0.49'
364
378
 
365
379
  Layout/CaseIndentation:
366
- Description: 'Indentation of when in a case/when/[else/]end.'
380
+ Description: 'Indentation of when in a case/(when|in)/[else/]end.'
367
381
  StyleGuide: '#indent-when-to-case'
368
382
  Enabled: true
369
383
  VersionAdded: '0.49'
384
+ VersionChanged: '1.16'
370
385
  EnforcedStyle: case
371
386
  SupportedStyles:
372
387
  - case
@@ -757,7 +772,7 @@ Layout/HashAlignment:
757
772
  Enabled: true
758
773
  AllowMultipleStyles: true
759
774
  VersionAdded: '0.49'
760
- VersionChanged: '0.77'
775
+ VersionChanged: '1.16'
761
776
  # Alignment of entries using hash rocket as separator. Valid values are:
762
777
  #
763
778
  # key - left alignment of keys
@@ -1114,6 +1129,11 @@ Layout/RescueEnsureAlignment:
1114
1129
  Enabled: true
1115
1130
  VersionAdded: '0.49'
1116
1131
 
1132
+ Layout/SingleLineBlockChain:
1133
+ Description: 'Put method call on a separate line if chained to a single line block.'
1134
+ Enabled: false
1135
+ VersionAdded: '1.14'
1136
+
1117
1137
  Layout/SpaceAfterColon:
1118
1138
  Description: 'Use spaces after colons.'
1119
1139
  StyleGuide: '#spaces-operators'
@@ -1593,7 +1613,7 @@ Lint/EmptyBlock:
1593
1613
  Description: 'This cop checks for blocks without a body.'
1594
1614
  Enabled: pending
1595
1615
  VersionAdded: '1.1'
1596
- VersionChanged: '1.3'
1616
+ VersionChanged: '1.15'
1597
1617
  AllowComments: true
1598
1618
  AllowEmptyLambdas: true
1599
1619
 
@@ -1626,6 +1646,12 @@ Lint/EmptyFile:
1626
1646
  AllowComments: true
1627
1647
  VersionAdded: '0.90'
1628
1648
 
1649
+ Lint/EmptyInPattern:
1650
+ Description: 'Checks for the presence of `in` pattern branches without a body.'
1651
+ Enabled: pending
1652
+ AllowComments: true
1653
+ VersionAdded: '1.16'
1654
+
1629
1655
  Lint/EmptyInterpolation:
1630
1656
  Description: 'Checks for empty string interpolation.'
1631
1657
  Enabled: true
@@ -2073,6 +2099,7 @@ Lint/SymbolConversion:
2073
2099
  Description: 'Checks for unnecessary symbol conversions.'
2074
2100
  Enabled: pending
2075
2101
  VersionAdded: '1.9'
2102
+ VersionChanged: '1.16'
2076
2103
  EnforcedStyle: strict
2077
2104
  SupportedStyles:
2078
2105
  - strict
@@ -3461,6 +3488,7 @@ Style/HashAsLastArrayItem:
3461
3488
 
3462
3489
  Style/HashConversion:
3463
3490
  Description: 'Avoid Hash[] in favor of ary.to_h or literal hashes.'
3491
+ StyleGuide: '#avoid-hash-constructor'
3464
3492
  Enabled: pending
3465
3493
  VersionAdded: '1.10'
3466
3494
  VersionChanged: '1.11'
@@ -3470,8 +3498,10 @@ Style/HashEachMethods:
3470
3498
  Description: 'Use Hash#each_key and Hash#each_value.'
3471
3499
  StyleGuide: '#hash-each'
3472
3500
  Enabled: true
3473
- VersionAdded: '0.80'
3474
3501
  Safe: false
3502
+ VersionAdded: '0.80'
3503
+ VersionChanged: '1.16'
3504
+ AllowedReceivers: []
3475
3505
 
3476
3506
  Style/HashExcept:
3477
3507
  Description: >-
@@ -3534,6 +3564,7 @@ Style/IdenticalConditionalBranches:
3534
3564
  out of the conditional.
3535
3565
  Enabled: true
3536
3566
  VersionAdded: '0.36'
3567
+ VersionChanged: '1.16'
3537
3568
 
3538
3569
  Style/IfInsideElse:
3539
3570
  Description: 'Finds if nodes inside else, which can be converted to elsif.'
@@ -3580,6 +3611,12 @@ Style/ImplicitRuntimeError:
3580
3611
  Enabled: false
3581
3612
  VersionAdded: '0.41'
3582
3613
 
3614
+ Style/InPatternThen:
3615
+ Description: 'Checks for `in;` uses in `case` expressions.'
3616
+ StyleGuide: '#no-in-pattern-semicolons'
3617
+ Enabled: pending
3618
+ VersionAdded: '1.16'
3619
+
3583
3620
  Style/InfiniteLoop:
3584
3621
  Description: >-
3585
3622
  Use Kernel#loop for infinite loops.
@@ -3808,6 +3845,12 @@ Style/MultilineIfThen:
3808
3845
  VersionAdded: '0.9'
3809
3846
  VersionChanged: '0.26'
3810
3847
 
3848
+ Style/MultilineInPatternThen:
3849
+ Description: 'Do not use `then` for multi-line `in` statement.'
3850
+ StyleGuide: '#no-then'
3851
+ Enabled: pending
3852
+ VersionAdded: '1.16'
3853
+
3811
3854
  Style/MultilineMemoization:
3812
3855
  Description: 'Wrap multiline memoizations in a `begin` and `end` block.'
3813
3856
  Enabled: true
@@ -3979,6 +4022,7 @@ Style/NilLambda:
3979
4022
  Description: 'Prefer `-> {}` to `-> { nil }`.'
3980
4023
  Enabled: pending
3981
4024
  VersionAdded: '1.3'
4025
+ VersionChanged: '1.15'
3982
4026
 
3983
4027
  Style/NonNilCheck:
3984
4028
  Description: 'Checks for redundant nil checks.'
@@ -4165,6 +4209,16 @@ Style/Proc:
4165
4209
  VersionAdded: '0.9'
4166
4210
  VersionChanged: '0.18'
4167
4211
 
4212
+ Style/QuotedSymbols:
4213
+ Description: 'Use a consistent style for quoted symbols.'
4214
+ Enabled: pending
4215
+ VersionAdded: '1.16'
4216
+ EnforcedStyle: same_as_string_literals
4217
+ SupportedStyles:
4218
+ - same_as_string_literals
4219
+ - single_quotes
4220
+ - double_quotes
4221
+
4168
4222
  Style/RaiseArgs:
4169
4223
  Description: 'Checks the arguments passed to raise/fail.'
4170
4224
  StyleGuide: '#exception-class-messages'
@@ -4632,6 +4686,12 @@ Style/TernaryParentheses:
4632
4686
  - require_parentheses_when_complex
4633
4687
  AllowSafeAssignment: true
4634
4688
 
4689
+ Style/TopLevelMethodDefinition:
4690
+ Description: 'This cop looks for top-level method definitions.'
4691
+ StyleGuide: '#top-level-methods'
4692
+ Enabled: false
4693
+ VersionAdded: '1.15'
4694
+
4635
4695
  Style/TrailingBodyOnClass:
4636
4696
  Description: 'Class body goes below class statement.'
4637
4697
  Enabled: true
@@ -4718,7 +4778,7 @@ Style/TrivialAccessors:
4718
4778
  StyleGuide: '#attr_family'
4719
4779
  Enabled: true
4720
4780
  VersionAdded: '0.9'
4721
- VersionChanged: '0.77'
4781
+ VersionChanged: '1.15'
4722
4782
  # When set to `false` the cop will suggest the use of accessor methods
4723
4783
  # in situations like:
4724
4784
  #
@@ -4737,7 +4797,7 @@ Style/TrivialAccessors:
4737
4797
  # on_exception :restart
4738
4798
  #
4739
4799
  # Commonly used in DSLs
4740
- AllowDSLWriters: false
4800
+ AllowDSLWriters: true
4741
4801
  IgnoreClassMethods: false
4742
4802
  AllowedMethods:
4743
4803
  - to_ary
data/lib/rubocop.rb CHANGED
@@ -82,6 +82,7 @@ require_relative 'rubocop/cop/mixin/end_keyword_alignment'
82
82
  require_relative 'rubocop/cop/mixin/enforce_superclass'
83
83
  require_relative 'rubocop/cop/mixin/first_element_line_break'
84
84
  require_relative 'rubocop/cop/mixin/frozen_string_literal'
85
+ require_relative 'rubocop/cop/mixin/gem_declaration'
85
86
  require_relative 'rubocop/cop/mixin/hash_alignment_styles'
86
87
  require_relative 'rubocop/cop/mixin/hash_transform_method'
87
88
  require_relative 'rubocop/cop/mixin/ignored_pattern'
@@ -118,6 +119,7 @@ require_relative 'rubocop/cop/mixin/surrounding_space'
118
119
  require_relative 'rubocop/cop/mixin/statement_modifier'
119
120
  require_relative 'rubocop/cop/mixin/string_help'
120
121
  require_relative 'rubocop/cop/mixin/string_literals_help'
122
+ require_relative 'rubocop/cop/mixin/symbol_help'
121
123
  require_relative 'rubocop/cop/mixin/target_ruby_version'
122
124
  require_relative 'rubocop/cop/mixin/trailing_body'
123
125
  require_relative 'rubocop/cop/mixin/trailing_comma'
@@ -148,6 +150,7 @@ require_relative 'rubocop/cop/correctors/unused_arg_corrector'
148
150
 
149
151
  require_relative 'rubocop/cop/bundler/duplicated_gem'
150
152
  require_relative 'rubocop/cop/bundler/gem_comment'
153
+ require_relative 'rubocop/cop/bundler/gem_version'
151
154
  require_relative 'rubocop/cop/bundler/insecure_protocol_source'
152
155
  require_relative 'rubocop/cop/bundler/ordered_gems'
153
156
 
@@ -223,6 +226,7 @@ require_relative 'rubocop/cop/layout/multiline_operation_indentation'
223
226
  require_relative 'rubocop/cop/layout/parameter_alignment'
224
227
  require_relative 'rubocop/cop/layout/redundant_line_break'
225
228
  require_relative 'rubocop/cop/layout/rescue_ensure_alignment'
229
+ require_relative 'rubocop/cop/layout/single_line_block_chain'
226
230
  require_relative 'rubocop/cop/layout/space_after_colon'
227
231
  require_relative 'rubocop/cop/layout/space_after_comma'
228
232
  require_relative 'rubocop/cop/layout/space_after_method_name'
@@ -284,6 +288,7 @@ require_relative 'rubocop/cop/lint/empty_conditional_body'
284
288
  require_relative 'rubocop/cop/lint/empty_ensure'
285
289
  require_relative 'rubocop/cop/lint/empty_expression'
286
290
  require_relative 'rubocop/cop/lint/empty_file'
291
+ require_relative 'rubocop/cop/lint/empty_in_pattern'
287
292
  require_relative 'rubocop/cop/lint/empty_interpolation'
288
293
  require_relative 'rubocop/cop/lint/empty_when'
289
294
  require_relative 'rubocop/cop/lint/ensure_return'
@@ -487,6 +492,7 @@ require_relative 'rubocop/cop/style/if_unless_modifier_of_if_unless'
487
492
  require_relative 'rubocop/cop/style/if_with_boolean_literal_branches'
488
493
  require_relative 'rubocop/cop/style/if_with_semicolon'
489
494
  require_relative 'rubocop/cop/style/implicit_runtime_error'
495
+ require_relative 'rubocop/cop/style/in_pattern_then'
490
496
  require_relative 'rubocop/cop/style/infinite_loop'
491
497
  require_relative 'rubocop/cop/style/inverse_methods'
492
498
  require_relative 'rubocop/cop/style/inline_comment'
@@ -497,6 +503,7 @@ require_relative 'rubocop/cop/style/lambda_call'
497
503
  require_relative 'rubocop/cop/style/line_end_concatenation'
498
504
  require_relative 'rubocop/cop/style/method_call_without_args_parentheses'
499
505
  require_relative 'rubocop/cop/style/method_call_with_args_parentheses'
506
+ require_relative 'rubocop/cop/style/multiline_in_pattern_then'
500
507
  require_relative 'rubocop/cop/style/redundant_assignment'
501
508
  require_relative 'rubocop/cop/style/redundant_fetch_block'
502
509
  require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
@@ -547,6 +554,7 @@ require_relative 'rubocop/cop/style/percent_q_literals'
547
554
  require_relative 'rubocop/cop/style/perl_backrefs'
548
555
  require_relative 'rubocop/cop/style/preferred_hash_methods'
549
556
  require_relative 'rubocop/cop/style/proc'
557
+ require_relative 'rubocop/cop/style/quoted_symbols'
550
558
  require_relative 'rubocop/cop/style/raise_args'
551
559
  require_relative 'rubocop/cop/style/random_with_offset'
552
560
  require_relative 'rubocop/cop/style/redundant_argument'
@@ -595,6 +603,7 @@ require_relative 'rubocop/cop/style/symbol_array'
595
603
  require_relative 'rubocop/cop/style/symbol_literal'
596
604
  require_relative 'rubocop/cop/style/symbol_proc'
597
605
  require_relative 'rubocop/cop/style/ternary_parentheses'
606
+ require_relative 'rubocop/cop/style/top_level_method_definition'
598
607
  require_relative 'rubocop/cop/style/trailing_body_on_class'
599
608
  require_relative 'rubocop/cop/style/trailing_body_on_method_definition'
600
609
  require_relative 'rubocop/cop/style/trailing_body_on_module'
@@ -82,6 +82,7 @@ module RuboCop
82
82
  #
83
83
  class GemComment < Base
84
84
  include DefNode
85
+ include GemDeclaration
85
86
 
86
87
  MSG = 'Missing gem description comment.'
87
88
  CHECKED_OPTIONS_CONFIG = 'OnlyFor'
@@ -90,9 +91,6 @@ module RuboCop
90
91
  RESTRICTIVE_VERSION_PATTERN = /<|~>/.freeze
91
92
  RESTRICT_ON_SEND = %i[gem].freeze
92
93
 
93
- # @!method gem_declaration?(node)
94
- def_node_matcher :gem_declaration?, '(send nil? :gem str ...)'
95
-
96
94
  def on_send(node)
97
95
  return unless gem_declaration?(node)
98
96
  return if ignored_gem?(node)
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Bundler
6
+ # Enforce that Gem version specifications are either required
7
+ # or forbidden.
8
+ #
9
+ # @example EnforcedStyle: required (default)
10
+ # # bad
11
+ # gem 'rubocop'
12
+ #
13
+ # # good
14
+ # gem 'rubocop', '~> 1.12'
15
+ #
16
+ # # good
17
+ # gem 'rubocop', '>= 1.10.0'
18
+ #
19
+ # # good
20
+ # gem 'rubocop', '>= 1.5.0', '< 1.10.0'
21
+ #
22
+ # @example EnforcedStyle: forbidden
23
+ # # good
24
+ # gem 'rubocop'
25
+ #
26
+ # # bad
27
+ # gem 'rubocop', '~> 1.12'
28
+ #
29
+ # # bad
30
+ # gem 'rubocop', '>= 1.10.0'
31
+ #
32
+ # # bad
33
+ # gem 'rubocop', '>= 1.5.0', '< 1.10.0'
34
+ #
35
+ class GemVersion < Base
36
+ include ConfigurableEnforcedStyle
37
+ include GemDeclaration
38
+
39
+ REQUIRED_MSG = 'Gem version specification is required.'
40
+ FORBIDDEN_MSG = 'Gem version specification is forbidden.'
41
+ VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze
42
+
43
+ # @!method includes_version_specification?(node)
44
+ def_node_matcher :includes_version_specification?, <<~PATTERN
45
+ (send nil? :gem <(str #version_specification?) ...>)
46
+ PATTERN
47
+
48
+ def on_send(node)
49
+ return unless gem_declaration?(node)
50
+ return if allowed_gem?(node)
51
+
52
+ if offense?(node)
53
+ add_offense(node)
54
+ opposite_style_detected
55
+ else
56
+ correct_style_detected
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def allowed_gem?(node)
63
+ allowed_gems.include?(node.first_argument.value)
64
+ end
65
+
66
+ def allowed_gems
67
+ Array(cop_config['AllowedGems'])
68
+ end
69
+
70
+ def message(range)
71
+ gem_specification = range.source
72
+
73
+ if required_style?
74
+ format(REQUIRED_MSG, gem_specification: gem_specification)
75
+ elsif forbidden_style?
76
+ format(FORBIDDEN_MSG, gem_specification: gem_specification)
77
+ end
78
+ end
79
+
80
+ def offense?(node)
81
+ (required_style? && !includes_version_specification?(node)) ||
82
+ (forbidden_style? && includes_version_specification?(node))
83
+ end
84
+
85
+ def forbidden_style?
86
+ style == :forbidden
87
+ end
88
+
89
+ def required_style?
90
+ style == :required
91
+ end
92
+
93
+ def version_specification?(expression)
94
+ expression.match?(VERSION_SPECIFICATION_REGEX)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -41,7 +41,7 @@ module RuboCop
41
41
 
42
42
  EXPECT_NO_OFFENSES_INCORRECT_DESCRIPTIONS = [
43
43
  /^(adds|registers|reports|finds) (an? )?offense/,
44
- /^flags\b/
44
+ /^(flags|handles|works)\b/
45
45
  ].freeze
46
46
 
47
47
  EXPECT_OFFENSE_INCORRECT_DESCRIPTIONS = [
@@ -10,33 +10,39 @@ module RuboCop
10
10
  # # good
11
11
  #
12
12
  # foo :bar,
13
- # :baz
13
+ # :baz,
14
+ # key: value
14
15
  #
15
16
  # foo(
16
17
  # :bar,
17
- # :baz
18
+ # :baz,
19
+ # key: value
18
20
  # )
19
21
  #
20
22
  # # bad
21
23
  #
22
24
  # foo :bar,
23
- # :baz
25
+ # :baz,
26
+ # key: value
24
27
  #
25
28
  # foo(
26
29
  # :bar,
27
- # :baz
30
+ # :baz,
31
+ # key: value
28
32
  # )
29
33
  #
30
34
  # @example EnforcedStyle: with_fixed_indentation
31
35
  # # good
32
36
  #
33
37
  # foo :bar,
34
- # :baz
38
+ # :baz,
39
+ # key: value
35
40
  #
36
41
  # # bad
37
42
  #
38
43
  # foo :bar,
39
- # :baz
44
+ # :baz,
45
+ # key: value
40
46
  class ArgumentAlignment < Base
41
47
  include Alignment
42
48
  extend AutoCorrector
@@ -47,14 +53,26 @@ module RuboCop
47
53
  'following the first line of a multi-line method call.'
48
54
 
49
55
  def on_send(node)
50
- return if node.arguments.size < 2 || node.send_type? && node.method?(:[]=)
56
+ first_arg = node.first_argument
57
+ return if !multiple_arguments?(node, first_arg) || node.send_type? && node.method?(:[]=)
51
58
 
52
- check_alignment(node.arguments, base_column(node, node.arguments))
59
+ if first_arg.hash_type? && !first_arg.braces?
60
+ pairs = first_arg.pairs
61
+ check_alignment(pairs, base_column(node, pairs.first))
62
+ else
63
+ check_alignment(node.arguments, base_column(node, first_arg))
64
+ end
53
65
  end
54
66
  alias on_csend on_send
55
67
 
56
68
  private
57
69
 
70
+ def multiple_arguments?(node, first_argument)
71
+ return true if node.arguments.size >= 2
72
+
73
+ first_argument&.hash_type? && first_argument.pairs.count >= 2
74
+ end
75
+
58
76
  def autocorrect(corrector, node)
59
77
  AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
60
78
  end
@@ -67,14 +85,14 @@ module RuboCop
67
85
  cop_config['EnforcedStyle'] == 'with_fixed_indentation'
68
86
  end
69
87
 
70
- def base_column(node, args)
71
- if fixed_indentation?
88
+ def base_column(node, first_argument)
89
+ if fixed_indentation? || first_argument.nil?
72
90
  lineno = target_method_lineno(node)
73
91
  line = node.source_range.source_buffer.source_line(lineno)
74
92
  indentation_of_line = /\S.*/.match(line).begin(0)
75
93
  indentation_of_line + configured_indentation_width
76
94
  else
77
- display_column(args.first.source_range)
95
+ display_column(first_argument.source_range)
78
96
  end
79
97
  end
80
98