diff --git a/Gemfile b/Gemfile index 5080b5af..86aa5831 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ source 'https://rubygems.org' gem "activesupport", require: false gem "parser" gem "pry", require: false -gem "rubocop", "1.36.0", require: false +gem "rubocop", "1.39.0", require: false gem "rubocop-i18n", require: false gem "rubocop-graphql", require: false gem "rubocop-minitest", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 7c289787..0102eb60 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,49 +24,49 @@ GEM rack (3.0.0) rainbow (3.1.1) rake (13.0.6) - regexp_parser (2.5.0) + regexp_parser (2.6.0) rexml (3.2.5) - rspec (3.11.0) - rspec-core (~> 3.11.0) - rspec-expectations (~> 3.11.0) - rspec-mocks (~> 3.11.0) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.1) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-mocks (3.11.1) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-support (3.11.1) - rubocop (1.36.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + rubocop (1.39.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.1.2.1) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.20.1, < 2.0) + rubocop-ast (>= 1.23.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.21.0) + rubocop-ast (1.23.0) parser (>= 3.1.1.0) - rubocop-graphql (0.14.6) + rubocop-graphql (0.18.0) rubocop (>= 0.87, < 2) rubocop-i18n (3.0.0) rubocop (~> 1.0) - rubocop-minitest (0.22.1) + rubocop-minitest (0.23.2) rubocop (>= 0.90, < 2.0) rubocop-performance (1.15.0) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.16.1) + rubocop-rails (2.17.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-rake (0.6.0) rubocop (~> 1.0) - rubocop-rspec (2.13.2) + rubocop-rspec (2.15.0) rubocop (~> 1.33) rubocop-sequel (0.3.4) rubocop (~> 1.0) @@ -77,7 +77,7 @@ GEM rubocop-thread_safety (0.4.4) rubocop (>= 0.53.0) ruby-progressbar (1.11.0) - test-prof (1.0.10) + test-prof (1.0.11) tzinfo (2.0.5) concurrent-ruby (~> 1.0) unicode-display_width (2.3.0) @@ -91,7 +91,7 @@ DEPENDENCIES pry rake rspec - rubocop (= 1.36.0) + rubocop (= 1.39.0) rubocop-graphql rubocop-i18n rubocop-minitest diff --git a/config/contents/layout/space_inside_array_percent_literal.md b/config/contents/layout/space_inside_array_percent_literal.md index aa8256c2..36d851e5 100644 --- a/config/contents/layout/space_inside_array_percent_literal.md +++ b/config/contents/layout/space_inside_array_percent_literal.md @@ -1,6 +1,9 @@ Checks for unnecessary additional spaces inside array percent literals (i.e. %i/%w). +Note that blank percent literals (e.g. `%i( )`) are checked by +`Layout/SpaceInsidePercentLiteralDelimiters`. + ### Example: # bad diff --git a/config/contents/layout/space_inside_hash_literal_braces.md b/config/contents/layout/space_inside_hash_literal_braces.md index d9e48b24..af63a47a 100644 --- a/config/contents/layout/space_inside_hash_literal_braces.md +++ b/config/contents/layout/space_inside_hash_literal_braces.md @@ -41,10 +41,13 @@ surrounding space depending on configuration. # bad foo = { } bar = { } + baz = { + } # good foo = {} bar = {} + baz = {} ### Example: EnforcedStyleForEmptyBraces: space # The `space` EnforcedStyleForEmptyBraces style enforces that @@ -55,5 +58,6 @@ surrounding space depending on configuration. # good foo = { } - foo = { } - foo = { } + foo = { } + foo = { + } diff --git a/config/contents/layout/space_inside_percent_literal_delimiters.md b/config/contents/layout/space_inside_percent_literal_delimiters.md index 54bf6fd8..b4c9e83c 100644 --- a/config/contents/layout/space_inside_percent_literal_delimiters.md +++ b/config/contents/layout/space_inside_percent_literal_delimiters.md @@ -3,11 +3,28 @@ Checks for unnecessary additional spaces inside the delimiters of ### Example: + # bad + %i( foo bar baz ) + # good %i(foo bar baz) # bad %w( foo bar baz ) + # good + %w(foo bar baz) + + # bad + %x( ls -l ) + + # good + %x(ls -l) + # bad - %x( ls -l ) \ No newline at end of file + %w( ) + %w( + ) + + # good + %w() \ No newline at end of file diff --git a/config/contents/layout/space_inside_reference_brackets.md b/config/contents/layout/space_inside_reference_brackets.md index 8ee084ed..6e8e03df 100644 --- a/config/contents/layout/space_inside_reference_brackets.md +++ b/config/contents/layout/space_inside_reference_brackets.md @@ -33,6 +33,8 @@ surrounding space depending on configuration. # bad foo[ ] foo[ ] + foo[ + ] # good foo[] @@ -44,6 +46,8 @@ surrounding space depending on configuration. # bad foo[] foo[ ] + foo[ + ] # good foo[ ] diff --git a/config/contents/lint/ambiguous_block_association.md b/config/contents/lint/ambiguous_block_association.md index 299e6beb..f7baee73 100644 --- a/config/contents/lint/ambiguous_block_association.md +++ b/config/contents/lint/ambiguous_block_association.md @@ -40,7 +40,7 @@ By default, there are no methods to allowed. # bad expect { do_something }.to change { object.attribute } -### Example: AllowedPatterns: [/change/] +### Example: AllowedPatterns: ['change'] # good expect { do_something }.to change { object.attribute } diff --git a/config/contents/lint/duplicate_magic_comment.md b/config/contents/lint/duplicate_magic_comment.md new file mode 100644 index 00000000..b6122cca --- /dev/null +++ b/config/contents/lint/duplicate_magic_comment.md @@ -0,0 +1,21 @@ +Checks for duplicated magic comments. + +### Example: + + # bad + + # encoding: ascii + # encoding: ascii + + # good + + # encoding: ascii + + # bad + + # frozen_string_literal: true + # frozen_string_literal: true + + # good + + # frozen_string_literal: true diff --git a/config/contents/lint/nested_method_definition.md b/config/contents/lint/nested_method_definition.md index 0ec82667..e69ae3de 100644 --- a/config/contents/lint/nested_method_definition.md +++ b/config/contents/lint/nested_method_definition.md @@ -25,6 +25,9 @@ Checks for nested method definitions. # good + # `class_eval`, `instance_eval`, `module_eval`, `class_exec`, `instance_exec`, and + # `module_exec` blocks are allowed by default. + def foo self.class.class_eval do def bar @@ -48,4 +51,40 @@ Checks for nested method definitions. def bar end end - end \ No newline at end of file + end + +### Example: AllowedMethods: [] (default) + # bad + def do_something + has_many :articles do + def find_or_create_by_name(name) + end + end + end + +### Example: AllowedMethods: ['has_many'] + # bad + def do_something + has_many :articles do + def find_or_create_by_name(name) + end + end + end + +### Example: AllowedPatterns: [] (default) + # bad + def foo(obj) + obj.do_baz do + def bar + end + end + end + +### Example: AllowedPatterns: ['baz'] + # good + def foo(obj) + obj.do_baz do + def bar + end + end + end diff --git a/config/contents/lint/number_conversion.md b/config/contents/lint/number_conversion.md index e4754c70..f0a50c38 100644 --- a/config/contents/lint/number_conversion.md +++ b/config/contents/lint/number_conversion.md @@ -57,7 +57,7 @@ input if it is not a standard class. # bad 10.minutes.to_i -### Example: AllowedPatterns: [/min*/] +### Example: AllowedPatterns: ['min*'] # good 10.minutes.to_i diff --git a/config/contents/lint/ordered_magic_comments.md b/config/contents/lint/ordered_magic_comments.md index c857fd41..fc2c19ac 100644 --- a/config/contents/lint/ordered_magic_comments.md +++ b/config/contents/lint/ordered_magic_comments.md @@ -2,6 +2,10 @@ Checks the proper ordering of magic comments and whether a magic comment is not placed before a shebang. +### Safety: + +This cop's autocorrection is unsafe because file encoding may change. + ### Example: # bad diff --git a/config/contents/lint/out_of_range_regexp_ref.md b/config/contents/lint/out_of_range_regexp_ref.md index e476b8c3..7c282ab7 100644 --- a/config/contents/lint/out_of_range_regexp_ref.md +++ b/config/contents/lint/out_of_range_regexp_ref.md @@ -1,4 +1,4 @@ -This cops looks for references of Regexp captures that are out of range +Looks for references of Regexp captures that are out of range and thus always returns nil. ### Safety: diff --git a/config/contents/lint/redundant_require_statement.md b/config/contents/lint/redundant_require_statement.md index 46ab7f0f..a01a22f8 100644 --- a/config/contents/lint/redundant_require_statement.md +++ b/config/contents/lint/redundant_require_statement.md @@ -1,13 +1,23 @@ Checks for unnecessary `require` statement. The following features are unnecessary `require` statement because -they are already loaded. +they are already loaded. e.g. Ruby 2.2: ruby -ve 'p $LOADED_FEATURES.reject { |feature| %r|/| =~ feature }' ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-darwin13] ["enumerator.so", "rational.so", "complex.so", "thread.rb"] -This cop targets Ruby 2.2 or higher containing these 4 features. +Below are the features that each `TargetRubyVersion` targets. + + * 2.0+ ... `enumerator` + * 2.1+ ... `thread` + * 2.2+ ... Add `rational` and `complex` above + * 2.5+ ... Add `pp` above + * 2.7+ ... Add `ruby2_keywords` above + * 3.1+ ... Add `fiber` above + * 3.2+ ... `set` + +This cop target those features. ### Example: # bad diff --git a/config/contents/lint/shadowing_outer_local_variable.md b/config/contents/lint/shadowing_outer_local_variable.md index a778f3f0..04353df3 100644 --- a/config/contents/lint/shadowing_outer_local_variable.md +++ b/config/contents/lint/shadowing_outer_local_variable.md @@ -7,9 +7,11 @@ NOTE: Shadowing of variables in block passed to `Ractor.new` is allowed because `Ractor` should not access outer variables. eg. following style is encouraged: + ```ruby worker_id, pipe = env Ractor.new(worker_id, pipe) do |worker_id, pipe| end + ``` ### Example: diff --git a/config/contents/lint/unreachable_loop.md b/config/contents/lint/unreachable_loop.md index 961c9ea9..c635f9c5 100644 --- a/config/contents/lint/unreachable_loop.md +++ b/config/contents/lint/unreachable_loop.md @@ -74,7 +74,7 @@ code that would otherwise be registered as an offense (eg. `times` used not in a # bad 2.times { raise ArgumentError } -### Example: AllowedPatterns: [/(exactly|at_least|at_most)\(\d+\)\.times/] (default) +### Example: AllowedPatterns: ['(exactly|at_least|at_most)\(\d+\)\.times'] (default) # good exactly(2).times { raise StandardError } \ No newline at end of file diff --git a/config/contents/metrics/abc_size.md b/config/contents/metrics/abc_size.md index f010753a..ab4ed720 100644 --- a/config/contents/metrics/abc_size.md +++ b/config/contents/metrics/abc_size.md @@ -15,7 +15,7 @@ is meant to distinguish actual `attr_reader` from other methods. ### Example: CountRepeatedAttributes: false (default is true) - # `model` and `current_user`, refenced 3 times each, + # `model` and `current_user`, referenced 3 times each, # are each counted as only 1 branch each if # `CountRepeatedAttributes` is set to 'false' diff --git a/config/contents/naming/inclusive_language.md b/config/contents/naming/inclusive_language.md index b1c1e6e9..7ad5c834 100644 --- a/config/contents/naming/inclusive_language.md +++ b/config/contents/naming/inclusive_language.md @@ -1,4 +1,4 @@ -This cops recommends the use of inclusive language instead of problematic terms. +Recommends the use of inclusive language instead of problematic terms. The cop can check the following locations for offenses: - identifiers - constants diff --git a/config/contents/style/block_delimiters.md b/config/contents/style/block_delimiters.md index 7d77ec31..51505f77 100644 --- a/config/contents/style/block_delimiters.md +++ b/config/contents/style/block_delimiters.md @@ -151,7 +151,7 @@ Additional methods can be added to the `AllowedMethods`. process(something) } -### Example: AllowedPatterns: [/map/] +### Example: AllowedPatterns: ['map'] # good things.map { |thing| diff --git a/config/contents/style/class_equality_comparison.md b/config/contents/style/class_equality_comparison.md index 693ec1f0..65928cb0 100644 --- a/config/contents/style/class_equality_comparison.md +++ b/config/contents/style/class_equality_comparison.md @@ -43,7 +43,7 @@ These are customizable with `AllowedMethods` option. var.class.eql?(Date) var.class.name == 'Date' -### Example: AllowedPatterns: [`/eq/`] +### Example: AllowedPatterns: ['eq'] # good var.instance_of?(Date) var.class.equal?(Date) diff --git a/config/contents/style/collection_compact.md b/config/contents/style/collection_compact.md index 1212f056..f7bc8ccc 100644 --- a/config/contents/style/collection_compact.md +++ b/config/contents/style/collection_compact.md @@ -4,7 +4,9 @@ and hashes can be replaced with `{Array,Hash}#{compact,compact!}`. ### Safety: It is unsafe by default because false positives may occur in the -`nil` check of block arguments to the receiver object. +`nil` check of block arguments to the receiver object. Additionally, + we can't know the type of the receiver object for sure, which may + result in false positives as well. For example, `[[1, 2], [3, nil]].reject { |first, second| second.nil? }` and `[[1, 2], [3, nil]].compact` are not compatible. This will work fine diff --git a/config/contents/style/endless_method.md b/config/contents/style/endless_method.md index 751b978e..9c650804 100644 --- a/config/contents/style/endless_method.md +++ b/config/contents/style/endless_method.md @@ -34,7 +34,7 @@ corrected to a multi-line definition. ### Example: EnforcedStyle: disallow # bad - def my_method; x end + def my_method() = x # bad def my_method() = x.foo diff --git a/config/contents/style/format_string_token.md b/config/contents/style/format_string_token.md index fd72652e..132e186e 100644 --- a/config/contents/style/format_string_token.md +++ b/config/contents/style/format_string_token.md @@ -72,7 +72,7 @@ if the number of them is less than or equals to # bad redirect('foo/%{bar_id}') -### Example: AllowedPatterns: [/redirect/] +### Example: AllowedPatterns: ['redirect'] # good redirect('foo/%{bar_id}') diff --git a/config/contents/style/guard_clause.md b/config/contents/style/guard_clause.md index c0b38d60..87d8409e 100644 --- a/config/contents/style/guard_clause.md +++ b/config/contents/style/guard_clause.md @@ -5,6 +5,9 @@ A condition with an `elsif` or `else` branch is allowed unless one of `return`, `break`, `next`, `raise`, or `fail` is used in the body of the conditional expression. +NOTE: Autocorrect works in most cases except with if-else statements + that contain logical operators such as `foo || raise('exception')` + ### Example: # bad def test diff --git a/config/contents/style/hash_except.md b/config/contents/style/hash_except.md index 5a53691c..ab9b2cf1 100644 --- a/config/contents/style/hash_except.md +++ b/config/contents/style/hash_except.md @@ -8,6 +8,11 @@ For safe detection, it is limited to commonly used string and symbol comparisons when used `==`. And do not check `Hash#delete_if` and `Hash#keep_if` to change receiver object. +### Safety: + +This cop is unsafe because it cannot be guaranteed that the receiver +is a `Hash` or responds to the replacement method. + ### Example: # bad diff --git a/config/contents/style/hash_syntax.md b/config/contents/style/hash_syntax.md index c77beee6..0d3c3637 100644 --- a/config/contents/style/hash_syntax.md +++ b/config/contents/style/hash_syntax.md @@ -23,7 +23,7 @@ The supported styles are: * always - forces use of the 3.1 syntax (e.g. {foo:}) * never - forces use of explicit hash literal value * either - accepts both shorthand and explicit use of hash literal value -* consistent - like "always", but will avoid mixing styles in a single hash +* consistent - like "either", but will avoid mixing styles in a single hash ### Example: EnforcedStyle: ruby19 (default) # bad diff --git a/config/contents/style/if_with_boolean_literal_branches.md b/config/contents/style/if_with_boolean_literal_branches.md index 8caf3365..14cb25a4 100644 --- a/config/contents/style/if_with_boolean_literal_branches.md +++ b/config/contents/style/if_with_boolean_literal_branches.md @@ -1,9 +1,25 @@ Checks for redundant `if` with boolean literal branches. It checks only conditions to return boolean value (`true` or `false`) for safe detection. -The conditions to be checked are comparison methods, predicate methods, and double negative. +The conditions to be checked are comparison methods, predicate methods, and +double negation (!!). `nonzero?` method is allowed by default. These are customizable with `AllowedMethods` option. +This cop targets only `if`s with a single `elsif` or `else` branch. The following +code will be allowed, because it has two `elsif` branches: + +```ruby +if foo + true +elsif bar > baz + true +elsif qux > quux # Single `elsif` is warned, but two or more `elsif`s are not. + true +else + false +end +``` + ### Safety: Autocorrection is unsafe because there is no guarantee that all predicate methods diff --git a/config/contents/style/module_function.md b/config/contents/style/module_function.md index e402b20e..0de186bc 100644 --- a/config/contents/style/module_function.md +++ b/config/contents/style/module_function.md @@ -1,10 +1,12 @@ -Checks for use of `extend self` or `module_function` in a -module. +Checks for use of `extend self` or `module_function` in a module. -Supported styles are: module_function, extend_self, forbidden. `forbidden` -style prohibits the usage of both styles. +Supported styles are: `module_function` (default), `extend_self` and `forbidden`. -NOTE: the cop won't be activated when the module contains any private methods. +A couple of things to keep in mind: + +- `forbidden` style prohibits the usage of both styles +- in default mode (`module_function`), the cop won't be activated when the module + contains any private methods ### Safety: @@ -24,7 +26,6 @@ and `module_function` do not behave exactly the same. # ... end -### Example: EnforcedStyle: module_function (default) # good module Test extend self @@ -33,6 +34,13 @@ and `module_function` do not behave exactly the same. # ... end + # good + module Test + class << self + # ... + end + end + ### Example: EnforcedStyle: extend_self # bad module Test @@ -46,6 +54,13 @@ and `module_function` do not behave exactly the same. # ... end + # good + module Test + class << self + # ... + end + end + ### Example: EnforcedStyle: forbidden # bad module Test @@ -65,4 +80,11 @@ and `module_function` do not behave exactly the same. # ... private # ... + end + + # good + module Test + class << self + # ... + end end \ No newline at end of file diff --git a/config/contents/style/numeric_predicate.md b/config/contents/style/numeric_predicate.md index 03414c9a..50902e37 100644 --- a/config/contents/style/numeric_predicate.md +++ b/config/contents/style/numeric_predicate.md @@ -62,7 +62,7 @@ to a false positive for non-standard classes. foo.negative? bar.baz.positive? -### Example: AllowedPatterns: [/zero/] with EnforcedStyle: predicate +### Example: AllowedPatterns: ['zero'] with EnforcedStyle: predicate # good # bad foo.zero? diff --git a/config/contents/style/operator_method_call.md b/config/contents/style/operator_method_call.md new file mode 100644 index 00000000..57ff738b --- /dev/null +++ b/config/contents/style/operator_method_call.md @@ -0,0 +1,13 @@ +Checks for redundant dot before operator method call. +The target operator methods are `|`, `^`, `&`, `<=>`, `==`, `===`, `=~`, `>`, `>=`, `<`, +`<=`, `<<`, `>>`, `+`, `-`, `*`, `/`, `%`, `**`, `~`, `!`, `!=`, and `!~`. + +### Example: + + # bad + foo.+ bar + foo.& bar + + # good + foo + bar + foo & bar diff --git a/config/contents/style/redundant_each.md b/config/contents/style/redundant_each.md new file mode 100644 index 00000000..9f87295b --- /dev/null +++ b/config/contents/style/redundant_each.md @@ -0,0 +1,28 @@ +Checks for redundant `each`. + +### Safety: + +This cop is unsafe, as it can produce false positives if the receiver +is not an `Enumerator`. + +### Example: + + # bad + array.each.each { |v| do_something(v) } + + # good + array.each { |v| do_something(v) } + + # bad + array.each.each_with_index { |v, i| do_something(v, i) } + + # good + array.each.with_index { |v, i| do_something(v, i) } + array.each_with_index { |v, i| do_something(v, i) } + + # bad + array.each.each_with_object { |v, o| do_something(v, o) } + + # good + array.each.with_object { |v, o| do_something(v, o) } + array.each_with_object { |v, o| do_something(v, o) } diff --git a/config/contents/style/redundant_string_escape.md b/config/contents/style/redundant_string_escape.md new file mode 100644 index 00000000..1de2a158 --- /dev/null +++ b/config/contents/style/redundant_string_escape.md @@ -0,0 +1,31 @@ +Checks for redundant escapes in string literals. + +### Example: + # bad - no need to escape # without following {/$/@ + "\#foo" + + # bad - no need to escape single quotes inside double quoted string + "\'foo\'" + + # bad - heredocs are also checked for unnecessary escapes + <<~STR + \#foo \"foo\" + STR + + # good + "#foo" + + # good + "\#{no_interpolation}" + + # good + "'foo'" + + # good + "foo\ + bar" + + # good + <<~STR + #foo "foo" + STR \ No newline at end of file diff --git a/config/contents/style/rescue_modifier.md b/config/contents/style/rescue_modifier.md index ea3f4bb1..2215d4de 100644 --- a/config/contents/style/rescue_modifier.md +++ b/config/contents/style/rescue_modifier.md @@ -4,7 +4,7 @@ The cop to check `rescue` in its modifier form is added for following reasons: * The syntax of modifier form `rescue` can be misleading because it - might led us to believe that `rescue` handles the given exception + might lead us to believe that `rescue` handles the given exception but it actually rescue all exceptions to return the given rescue block. In this case, value returned by handle_error or SomeException. diff --git a/config/contents/style/symbol_proc.md b/config/contents/style/symbol_proc.md index 1317e26b..52e70076 100644 --- a/config/contents/style/symbol_proc.md +++ b/config/contents/style/symbol_proc.md @@ -77,6 +77,6 @@ call(&:bar) # bad something.map { |s| s.upcase } -### Example: AllowedPatterns: [/map/] (default) +### Example: AllowedPatterns: ['map'] (default) # good something.map { |s| s.upcase } diff --git a/lib/cc/engine/source_file.rb b/lib/cc/engine/source_file.rb index dd1ef264..31be980a 100644 --- a/lib/cc/engine/source_file.rb +++ b/lib/cc/engine/source_file.rb @@ -24,7 +24,10 @@ def inspect attr_reader :config_store, :io, :path, :root def processed_source - RuboCop::ProcessedSource.from_file(path, target_ruby_version) + processed_source = RuboCop::ProcessedSource.from_file(path, target_ruby_version) + processed_source.config = config_store if processed_source.respond_to?(:config=) + processed_source.registry = RuboCop::Cop::Cop.registry if processed_source.respond_to?(:registry=) + processed_source end def target_ruby_version