From e97a67996a6f7757a1a01540bc858816ca61478c Mon Sep 17 00:00:00 2001 From: Filipe Esperandio Date: Thu, 11 May 2017 15:56:49 -0300 Subject: [PATCH 1/4] Replace Cop.all with Cop.registry to follow rubocop refactoring --- lib/cc/engine/source_file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cc/engine/source_file.rb b/lib/cc/engine/source_file.rb index 83a97403..63be4c28 100644 --- a/lib/cc/engine/source_file.rb +++ b/lib/cc/engine/source_file.rb @@ -32,7 +32,7 @@ def target_ruby_version end def rubocop_team - RuboCop::Cop::Team.new(RuboCop::Cop::Cop.all, config_store) + RuboCop::Cop::Team.new(RuboCop::Cop::Cop.registry, config_store) end def display_path From 23ccb275d4726f1f7f9e63f9a190d71a9f9579cb Mon Sep 17 00:00:00 2001 From: Filipe Esperandio Date: Thu, 11 May 2017 17:41:32 -0300 Subject: [PATCH 2/4] Make the failure more informative --- spec/cc/engine/content_resolver_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/cc/engine/content_resolver_spec.rb b/spec/cc/engine/content_resolver_spec.rb index 9d30b27c..4decb23b 100644 --- a/spec/cc/engine/content_resolver_spec.rb +++ b/spec/cc/engine/content_resolver_spec.rb @@ -18,7 +18,7 @@ module CC::Engine describe "#{cop.name}" do it "has content" do resolver = ContentResolver.new(cop.name) - expect(resolver.content).to be_a(String) + expect(resolver.content).to be_a(String), "#{cop.name} has no content, consider running `rake docs:scrape`" expect(resolver.content.length).to (be > 0), "#{cop.name} should have content. Hint, update: #{resolver.content_path}" end end From 22e763575fac6c8fe0fa08c1194a7c6f1df5a56f Mon Sep 17 00:00:00 2001 From: Alexander Mankuta Date: Wed, 4 Oct 2017 15:43:57 +0300 Subject: [PATCH 3/4] Rubocop 0.50.0 * Updated docs * Updated other gems --- Gemfile | 2 +- Gemfile.lock | 69 ++++----- .../bundler/insecure_protocol_source.md | 22 +++ config/contents/bundler/ordered_gems.md | 9 +- .../lint/ambiguous_block_association.md | 21 +++ config/contents/lint/ambiguous_operator.md | 13 +- .../contents/lint/ambiguous_regexp_literal.md | 7 + .../contents/lint/assignment_in_condition.md | 18 +++ config/contents/lint/block_alignment.md | 32 ++++- config/contents/lint/boolean_symbol.md | 18 +++ .../lint/circular_argument_reference.md | 14 ++ config/contents/lint/condition_position.md | 10 ++ config/contents/lint/debugger.md | 29 ++++ config/contents/lint/def_end_alignment.md | 24 +++- .../contents/lint/deprecated_class_methods.md | 13 ++ .../contents/lint/duplicate_case_condition.md | 26 +++- config/contents/lint/duplicate_methods.md | 24 ++++ config/contents/lint/duplicated_key.md | 11 +- .../lint/each_with_object_argument.md | 11 +- config/contents/lint/else_layout.md | 13 ++ config/contents/lint/empty_ensure.md | 39 ++++++ config/contents/lint/empty_expression.md | 10 ++ config/contents/lint/empty_interpolation.md | 10 +- config/contents/lint/empty_when.md | 10 ++ config/contents/lint/end_alignment.md | 30 +++- config/contents/lint/end_in_method.md | 24 ++++ config/contents/lint/ensure_return.md | 22 +++ config/contents/lint/float_out_of_range.md | 5 + .../lint/format_parameter_mismatch.md | 8 ++ config/contents/lint/handle_exceptions.md | 41 ++++++ .../lint/implicit_string_concatenation.md | 5 + .../lint/ineffective_access_modifier.md | 9 ++ config/contents/lint/interpolation_check.md | 13 ++ .../lint/invalid_character_literal.md | 3 + config/contents/lint/literal_in_condition.md | 14 ++ .../contents/lint/literal_in_interpolation.md | 10 +- config/contents/lint/loop.md | 37 +++++ config/contents/lint/multiple_compare.md | 18 +++ .../contents/lint/nested_method_definition.md | 41 ++++++ .../contents/lint/next_without_accumulator.md | 5 + .../lint/non_local_exit_from_iterator.md | 15 +- .../lint/parentheses_as_grouped_expression.md | 10 +- config/contents/lint/percent_string_array.md | 20 ++- config/contents/lint/percent_symbol_array.md | 20 ++- config/contents/lint/rand_one.md | 6 +- config/contents/lint/redundant_with_index.md | 22 +++ config/contents/lint/require_parentheses.md | 10 +- config/contents/lint/rescue_exception.md | 21 +++ config/contents/lint/rescue_type.md | 31 ++++ .../lint/rescue_without_error_class.md | 17 +++ .../contents/lint/return_in_void_context.md | 28 ++++ config/contents/lint/safe_navigation_chain.md | 20 +++ config/contents/lint/shadowed_exception.md | 5 + .../lint/shadowing_outer_local_variable.md | 26 +++- .../string_conversion_in_interpolation.md | 10 +- .../lint/underscore_prefixed_variable_name.md | 26 ++++ config/contents/lint/unified_integer.md | 5 + .../contents/lint/unneeded_splat_expansion.md | 5 + config/contents/lint/unreachable_code.md | 30 +++- config/contents/lint/unused_block_argument.md | 14 +- .../contents/lint/unused_method_argument.md | 10 ++ config/contents/lint/uri_escape_unescape.md | 25 ++++ config/contents/lint/uri_regexp.md | 9 ++ .../contents/lint/useless_access_modifier.md | 12 ++ config/contents/lint/useless_assignment.md | 20 ++- config/contents/lint/useless_comparison.md | 4 +- .../lint/useless_else_without_rescue.md | 17 ++- config/contents/lint/useless_setter_call.md | 20 ++- config/contents/lint/void.md | 38 +++++ config/contents/metrics/block_length.md | 3 +- config/contents/metrics/block_nesting.md | 7 +- config/contents/performance/caller.md | 15 ++ .../performance/compare_with_block.md | 4 +- config/contents/performance/end_with.md | 3 +- .../contents/performance/redundant_match.md | 2 +- config/contents/performance/regexp_match.md | 55 ++++++++ config/contents/performance/start_with.md | 3 +- .../contents/performance/unfreeze_string.md | 20 +++ .../performance/uri_default_parser.md | 9 ++ config/contents/rails/action_filter.md | 5 +- .../contents/rails/active_support_aliases.md | 15 ++ config/contents/rails/application_job.md | 13 ++ config/contents/rails/application_record.md | 13 ++ config/contents/rails/blank.md | 34 +++++ config/contents/rails/date.md | 2 +- config/contents/rails/delegate.md | 34 ++++- config/contents/rails/file_path.md | 11 ++ .../rails/has_many_or_has_one_dependent.md | 15 ++ .../rails/http_positional_arguments.md | 9 +- config/contents/rails/not_null_column.md | 5 +- config/contents/rails/output_safety.md | 59 ++++++-- config/contents/rails/present.md | 31 ++++ .../contents/rails/relative_date_constant.md | 15 ++ config/contents/rails/request_referer.md | 17 +++ config/contents/rails/reversible_migration.md | 122 ++++++++++++++++ .../contents/rails/skips_model_validations.md | 20 +++ config/contents/rails/time_zone.md | 2 +- config/contents/rails/uniq_before_pluck.md | 4 +- config/contents/security/eval.md | 8 ++ config/contents/security/marshal_load.md | 14 ++ config/contents/security/yaml_load.md | 11 ++ config/contents/style/alias.md | 28 +++- config/contents/style/and_or.md | 27 ++++ .../contents/style/auto_resource_cleanup.md | 2 +- .../style/braces_around_hash_parameters.md | 36 +++++ config/contents/style/copyright.md | 4 +- config/contents/style/dir.md | 13 ++ config/contents/style/documentation_method.md | 2 +- config/contents/style/empty_method.md | 21 ++- config/contents/style/format_string_token.md | 27 ++++ config/contents/style/hash_syntax.md | 2 +- .../style/identical_conditional_branches.md | 45 +++++- .../style/if_unless_modifier_of_if_unless.md | 2 +- config/contents/style/inverse_methods.md | 24 ++++ .../method_call_with_args_parentheses.md | 36 +++++ .../method_call_without_args_parentheses.md | 8 ++ config/contents/style/min_max.md | 11 ++ config/contents/style/mixin_grouping.md | 31 ++++ .../contents/style/multiline_memoization.md | 23 ++- config/contents/style/multiple_comparison.md | 11 ++ config/contents/style/negated_if.md | 71 ++++++++++ config/contents/style/next.md | 2 +- config/contents/style/numeric_literals.md | 19 +++ config/contents/style/numeric_predicate.md | 6 +- config/contents/style/or_assignment.md | 23 +++ .../style/percent_literal_delimiters.md | 20 +++ config/contents/style/raise_args.md | 5 +- .../contents/style/redundant_conditional.md | 21 +++ config/contents/style/redundant_self.md | 4 + config/contents/style/return_nil.md | 29 ++++ .../style/string_literals_in_interpolation.md | 22 +++ config/contents/style/symbol_array.md | 25 +++- config/contents/style/ternary_parentheses.md | 9 +- .../style/trailing_underscore_variable.md | 7 +- config/contents/style/word_array.md | 25 +++- config/contents/style/yoda_condition.md | 31 ++++ .../contents/style/zero_length_predicate.md | 15 +- spec/support/currently_undocumented_cops.txt | 132 +++++++++++------- 138 files changed, 2423 insertions(+), 212 deletions(-) create mode 100644 config/contents/bundler/insecure_protocol_source.md create mode 100644 config/contents/lint/ambiguous_block_association.md create mode 100644 config/contents/lint/assignment_in_condition.md create mode 100644 config/contents/lint/boolean_symbol.md create mode 100644 config/contents/lint/debugger.md create mode 100644 config/contents/lint/deprecated_class_methods.md create mode 100644 config/contents/lint/empty_ensure.md create mode 100644 config/contents/lint/end_in_method.md create mode 100644 config/contents/lint/ensure_return.md create mode 100644 config/contents/lint/handle_exceptions.md create mode 100644 config/contents/lint/interpolation_check.md create mode 100644 config/contents/lint/loop.md create mode 100644 config/contents/lint/multiple_compare.md create mode 100644 config/contents/lint/redundant_with_index.md create mode 100644 config/contents/lint/rescue_exception.md create mode 100644 config/contents/lint/rescue_type.md create mode 100644 config/contents/lint/rescue_without_error_class.md create mode 100644 config/contents/lint/return_in_void_context.md create mode 100644 config/contents/lint/safe_navigation_chain.md create mode 100644 config/contents/lint/underscore_prefixed_variable_name.md create mode 100644 config/contents/lint/uri_escape_unescape.md create mode 100644 config/contents/lint/uri_regexp.md create mode 100644 config/contents/lint/void.md create mode 100644 config/contents/performance/caller.md create mode 100644 config/contents/performance/regexp_match.md create mode 100644 config/contents/performance/unfreeze_string.md create mode 100644 config/contents/performance/uri_default_parser.md create mode 100644 config/contents/rails/active_support_aliases.md create mode 100644 config/contents/rails/application_job.md create mode 100644 config/contents/rails/application_record.md create mode 100644 config/contents/rails/blank.md create mode 100644 config/contents/rails/file_path.md create mode 100644 config/contents/rails/has_many_or_has_one_dependent.md create mode 100644 config/contents/rails/present.md create mode 100644 config/contents/rails/relative_date_constant.md create mode 100644 config/contents/rails/request_referer.md create mode 100644 config/contents/rails/reversible_migration.md create mode 100644 config/contents/rails/skips_model_validations.md create mode 100644 config/contents/security/eval.md create mode 100644 config/contents/security/marshal_load.md create mode 100644 config/contents/security/yaml_load.md create mode 100644 config/contents/style/and_or.md create mode 100644 config/contents/style/braces_around_hash_parameters.md create mode 100644 config/contents/style/dir.md create mode 100644 config/contents/style/format_string_token.md create mode 100644 config/contents/style/inverse_methods.md create mode 100644 config/contents/style/method_call_with_args_parentheses.md create mode 100644 config/contents/style/method_call_without_args_parentheses.md create mode 100644 config/contents/style/min_max.md create mode 100644 config/contents/style/mixin_grouping.md create mode 100644 config/contents/style/multiple_comparison.md create mode 100644 config/contents/style/negated_if.md create mode 100644 config/contents/style/numeric_literals.md create mode 100644 config/contents/style/or_assignment.md create mode 100644 config/contents/style/percent_literal_delimiters.md create mode 100644 config/contents/style/redundant_conditional.md create mode 100644 config/contents/style/return_nil.md create mode 100644 config/contents/style/string_literals_in_interpolation.md create mode 100644 config/contents/style/yoda_condition.md diff --git a/Gemfile b/Gemfile index 506fbd37..9962c74c 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ source 'https://rubygems.org' gem "activesupport", require: false gem "parser", "~> 2.4.0" gem "pry", require: false -gem "rubocop", "~> 0.45", require: false +gem "rubocop", "~> 0.50.0", require: false gem "rubocop-migrations", require: false gem "rubocop-rspec", require: false gem "safe_yaml" diff --git a/Gemfile.lock b/Gemfile.lock index e961e2c5..864515a9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,57 +1,58 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.0.1) + activesupport (5.1.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) ast (2.3.0) - coderay (1.1.1) - concurrent-ruby (1.0.3) - diff-lcs (1.2.5) - i18n (0.7.0) - method_source (0.8.2) - minitest (5.10.1) + coderay (1.1.2) + concurrent-ruby (1.0.5) + diff-lcs (1.3) + i18n (0.8.6) + method_source (0.9.0) + minitest (5.10.3) + parallel (1.12.0) parser (2.4.0.0) ast (~> 2.2) powerpack (0.1.1) - pry (0.10.4) + pry (0.11.1) coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) - rainbow (2.1.0) - rake (12.0.0) - rspec (3.5.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-core (3.5.4) - rspec-support (~> 3.5.0) - rspec-expectations (3.5.0) + method_source (~> 0.9.0) + rainbow (2.2.2) + rake + rake (12.1.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-mocks (3.5.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-support (3.5.0) - rubocop (0.46.0) - parser (>= 2.3.1.1, < 3.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + rubocop (0.50.0) + parallel (~> 1.10) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) - rainbow (>= 1.99.1, < 3.0) + rainbow (>= 2.2.2, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) rubocop-migrations (0.1.2) rubocop (~> 0.41) - rubocop-rspec (1.8.0) - rubocop (>= 0.42.0) - ruby-progressbar (1.8.1) + rubocop-rspec (1.18.0) + rubocop (>= 0.50.0) + ruby-progressbar (1.9.0) safe_yaml (1.0.4) - slop (3.6.0) - thread_safe (0.3.5) - tzinfo (1.2.2) + thread_safe (0.3.6) + tzinfo (1.2.3) thread_safe (~> 0.1) - unicode-display_width (1.1.2) + unicode-display_width (1.3.0) PLATFORMS ruby @@ -62,7 +63,7 @@ DEPENDENCIES pry rake rspec - rubocop (~> 0.45) + rubocop (~> 0.50.0) rubocop-migrations rubocop-rspec safe_yaml diff --git a/config/contents/bundler/insecure_protocol_source.md b/config/contents/bundler/insecure_protocol_source.md new file mode 100644 index 00000000..b405c76f --- /dev/null +++ b/config/contents/bundler/insecure_protocol_source.md @@ -0,0 +1,22 @@ +The symbol argument `:gemcutter`, `:rubygems` and `:rubyforge` +are deprecated. So please change your source to URL string that +'https://rubygems.org' if possible, or 'http://rubygems.org' if not. + +This autocorrect will replace these symbols with 'https://rubygems.org'. +Because it is secure, HTTPS request is strongly recommended. And in +most use cases HTTPS will be fine. + +However, it don't replace all `sources` of `http://` with `https://`. +For example, when specifying an internal gem server using HTTP on the +intranet, a use case where HTTPS can not be specified was considered. +Consider using HTTP only if you can not use HTTPS. + +### Example: + # bad + source :gemcutter + source :rubygems + source :rubyforge + + # good + source 'https://rubygems.org' # strongly recommended + source 'http://rubygems.org' \ No newline at end of file diff --git a/config/contents/bundler/ordered_gems.md b/config/contents/bundler/ordered_gems.md index 9a36db79..84d8f9a2 100644 --- a/config/contents/bundler/ordered_gems.md +++ b/config/contents/bundler/ordered_gems.md @@ -1,4 +1,5 @@ -Gems in consecutive lines should be alphabetically sorted +Gems should be alphabetically sorted within groups. + ### Example: # bad gem 'rubocop' @@ -11,4 +12,10 @@ Gems in consecutive lines should be alphabetically sorted # good gem 'rubocop' + gem 'rspec' + + # good only if TreatCommentsAsGroupSeparators is true + # For code quality + gem 'rubocop' + # For tests gem 'rspec' \ No newline at end of file diff --git a/config/contents/lint/ambiguous_block_association.md b/config/contents/lint/ambiguous_block_association.md new file mode 100644 index 00000000..455ef0d2 --- /dev/null +++ b/config/contents/lint/ambiguous_block_association.md @@ -0,0 +1,21 @@ +This cop checks for ambiguous block association with method +when param passed without parentheses. + +### Example: + + # bad + some_method a { |val| puts val } + +### Example: + + # good + # With parentheses, there's no ambiguity. + some_method(a) { |val| puts val } + + # good + # Operator methods require no disambiguation + foo == bar { |b| b.baz } + + # good + # Lambda arguments require no disambiguation + foo = ->(bar) { bar.baz } \ No newline at end of file diff --git a/config/contents/lint/ambiguous_operator.md b/config/contents/lint/ambiguous_operator.md index 62dc2876..733a4a97 100644 --- a/config/contents/lint/ambiguous_operator.md +++ b/config/contents/lint/ambiguous_operator.md @@ -2,11 +2,16 @@ This cop checks for ambiguous operators in the first argument of a method invocation without parentheses. ### Example: - array = [1, 2, 3] + + # bad # The `*` is interpreted as a splat operator but it could possibly be - # a `*` method invocation (i.e. `do_something.*(array)`). - do_something *array + # a `*` method invocation (i.e. `do_something.*(some_array)`). + do_something *some_array + +### Example: + + # good # With parentheses, there's no ambiguity. - do_something(*array) \ No newline at end of file + do_something(*some_array) \ No newline at end of file diff --git a/config/contents/lint/ambiguous_regexp_literal.md b/config/contents/lint/ambiguous_regexp_literal.md index cbd59a4c..2c5b232f 100644 --- a/config/contents/lint/ambiguous_regexp_literal.md +++ b/config/contents/lint/ambiguous_regexp_literal.md @@ -2,10 +2,17 @@ This cop checks for ambiguous regexp literals in the first argument of a method invocation without parentheses. ### Example: + + # bad + # This is interpreted as a method invocation with a regexp literal, # but it could possibly be `/` method invocations. # (i.e. `do_something./(pattern)./(i)`) do_something /pattern/i +### Example: + + # good + # With parentheses, there's no ambiguity. do_something(/pattern/i) \ No newline at end of file diff --git a/config/contents/lint/assignment_in_condition.md b/config/contents/lint/assignment_in_condition.md new file mode 100644 index 00000000..60a37861 --- /dev/null +++ b/config/contents/lint/assignment_in_condition.md @@ -0,0 +1,18 @@ +This cop checks for assignments in the conditions of +if/while/until. + +### Example: + + # bad + + if some_var = true + do_something + end + +### Example: + + # good + + if some_var == true + do_something + end \ No newline at end of file diff --git a/config/contents/lint/block_alignment.md b/config/contents/lint/block_alignment.md index 21a6c722..b4b47d91 100644 --- a/config/contents/lint/block_alignment.md +++ b/config/contents/lint/block_alignment.md @@ -1,8 +1,8 @@ This cop checks whether the end keywords are aligned properly for do end blocks. -Three modes are supported through the `AlignWith` configuration -parameter: +Three modes are supported through the `EnforcedStyleAlignWith` +configuration parameter: `start_of_block` : the `end` shall be aligned with the start of the line where the `do` appeared. @@ -15,18 +15,40 @@ location. The autofixer will default to `start_of_line`. ### Example: - # either + # bad + + foo.bar + .each do + baz + end + +### Example: + + # EnforcedStyleAlignWith: either (default) + + # good + variable = lambda do |i| i end - # start_of_block +### Example: + + # EnforcedStyleAlignWith: start_of_block + + # good + foo.bar .each do baz end - # start_of_line +### Example: + + # EnforcedStyleAlignWith: start_of_line + + # good + foo.bar .each do baz diff --git a/config/contents/lint/boolean_symbol.md b/config/contents/lint/boolean_symbol.md new file mode 100644 index 00000000..bb4fe218 --- /dev/null +++ b/config/contents/lint/boolean_symbol.md @@ -0,0 +1,18 @@ +This cop checks for `:true` and `:false` symbols. +In most cases it would be a typo. + +### Example: + + # bad + :true + + # good + true + +### Example: + + # bad + :false + + # good + false \ No newline at end of file diff --git a/config/contents/lint/circular_argument_reference.md b/config/contents/lint/circular_argument_reference.md index 4bc805f7..628c4239 100644 --- a/config/contents/lint/circular_argument_reference.md +++ b/config/contents/lint/circular_argument_reference.md @@ -4,27 +4,41 @@ arguments and optional ordinal arguments. This cop mirrors a warning produced by MRI since 2.2. ### Example: + # bad + def bake(pie: pie) pie.heat_up end +### Example: + # good + def bake(pie:) pie.refrigerate end +### Example: + # good + def bake(pie: self.pie) pie.feed_to(user) end +### Example: + # bad + def cook(dry_ingredients = dry_ingredients) dry_ingredients.reduce(&:+) end +### Example: + # good + def cook(dry_ingredients = self.dry_ingredients) dry_ingredients.combine end \ No newline at end of file diff --git a/config/contents/lint/condition_position.md b/config/contents/lint/condition_position.md index 153c29ac..5f4557fd 100644 --- a/config/contents/lint/condition_position.md +++ b/config/contents/lint/condition_position.md @@ -3,7 +3,17 @@ if/while/until. ### Example: + # bad + if some_condition do_something + end + +### Example: + + # good + + if some_condition + do_something end \ No newline at end of file diff --git a/config/contents/lint/debugger.md b/config/contents/lint/debugger.md new file mode 100644 index 00000000..a66591c9 --- /dev/null +++ b/config/contents/lint/debugger.md @@ -0,0 +1,29 @@ +This cop checks for calls to debugger or pry. + +### Example: + + # bad (ok during development) + + # using pry + def some_method + binding.pry + do_something + end + +### Example: + + # bad (ok during development) + + # using byebug + def some_method + byebug + do_something + end + +### Example: + + # good + + def some_method + do_something + end \ No newline at end of file diff --git a/config/contents/lint/def_end_alignment.md b/config/contents/lint/def_end_alignment.md index aed3fea8..a67b073d 100644 --- a/config/contents/lint/def_end_alignment.md +++ b/config/contents/lint/def_end_alignment.md @@ -1,7 +1,7 @@ This cop checks whether the end keywords of method definitions are aligned properly. -Two modes are supported through the AlignWith configuration +Two modes are supported through the EnforcedStyleAlignWith configuration parameter. If it's set to `start_of_line` (which is the default), the `end` shall be aligned with the start of the line where the `def` keyword is. If it's set to `def`, the `end` shall be aligned with the @@ -9,5 +9,25 @@ keyword is. If it's set to `def`, the `end` shall be aligned with the ### Example: + # bad + + private def foo + end + +### Example: + + # EnforcedStyleAlignWith: start_of_line (default) + + # good + + private def foo + end + +### Example: + + # EnforcedStyleAlignWith: def + + # good + private def foo - end \ No newline at end of file + end \ No newline at end of file diff --git a/config/contents/lint/deprecated_class_methods.md b/config/contents/lint/deprecated_class_methods.md new file mode 100644 index 00000000..0ede887f --- /dev/null +++ b/config/contents/lint/deprecated_class_methods.md @@ -0,0 +1,13 @@ +This cop checks for uses of the deprecated class method usages. + +### Example: + + # bad + + File.exists?(some_path) + +### Example: + + # good + + File.exist?(some_path) \ No newline at end of file diff --git a/config/contents/lint/duplicate_case_condition.md b/config/contents/lint/duplicate_case_condition.md index 3dccf3b8..691ee2fe 100644 --- a/config/contents/lint/duplicate_case_condition.md +++ b/config/contents/lint/duplicate_case_condition.md @@ -3,10 +3,22 @@ used in case 'when' expressions. ### Example: - # bad - case x - when 'first' - do_something - when 'first' - do_something_else - end + # bad + + case x + when 'first' + do_something + when 'first' + do_something_else + end + +### Example: + + # good + + case x + when 'first' + do_something + when 'second' + do_something_else + end \ No newline at end of file diff --git a/config/contents/lint/duplicate_methods.md b/config/contents/lint/duplicate_methods.md index f210aafc..a38d165e 100644 --- a/config/contents/lint/duplicate_methods.md +++ b/config/contents/lint/duplicate_methods.md @@ -2,11 +2,35 @@ This cop checks for duplicated instance (or singleton) method definitions. ### Example: + # bad + def duplicated 1 end def duplicated 2 + end + +### Example: + + # bad + + def duplicated + 1 + end + + alias duplicated other_duplicated + +### Example: + + # good + + def duplicated + 1 + end + + def other_duplicated + 2 end \ No newline at end of file diff --git a/config/contents/lint/duplicated_key.md b/config/contents/lint/duplicated_key.md index 6ec346f2..6bab0890 100644 --- a/config/contents/lint/duplicated_key.md +++ b/config/contents/lint/duplicated_key.md @@ -3,4 +3,13 @@ This cop checks for duplicated keys in hash literals. This cop mirrors a warning in Ruby 2.2. ### Example: - hash = { food: 'apple', food: 'orange' } \ No newline at end of file + + # bad + + hash = { food: 'apple', food: 'orange' } + +### Example: + + # good + + hash = { food: 'apple', other_food: 'orange' } \ No newline at end of file diff --git a/config/contents/lint/each_with_object_argument.md b/config/contents/lint/each_with_object_argument.md index b2a37be4..2cbab47c 100644 --- a/config/contents/lint/each_with_object_argument.md +++ b/config/contents/lint/each_with_object_argument.md @@ -6,4 +6,13 @@ It's definitely a bug. ### Example: - sum = numbers.each_with_object(0) { |e, a| a += e } \ No newline at end of file + # bad + + sum = numbers.each_with_object(0) { |e, a| a += e } + +### Example: + + # good + + num = 0 + sum = numbers.each_with_object(num) { |e, a| a += e } \ No newline at end of file diff --git a/config/contents/lint/else_layout.md b/config/contents/lint/else_layout.md index 23715628..4f64659e 100644 --- a/config/contents/lint/else_layout.md +++ b/config/contents/lint/else_layout.md @@ -4,8 +4,21 @@ which is usually a mistake. ### Example: + # bad + if something ... else do_this do_that + end + +### Example: + + # good + + if something + ... + else + do_this + do_that end \ No newline at end of file diff --git a/config/contents/lint/empty_ensure.md b/config/contents/lint/empty_ensure.md new file mode 100644 index 00000000..af1a57a7 --- /dev/null +++ b/config/contents/lint/empty_ensure.md @@ -0,0 +1,39 @@ +This cop checks for empty `ensure` blocks + +### Example: + + # bad + + def some_method + do_something + ensure + end + +### Example: + + # bad + + begin + do_something + ensure + end + +### Example: + + # good + + def some_method + do_something + ensure + do_something_else + end + +### Example: + + # good + + begin + do_something + ensure + do_something_else + end \ No newline at end of file diff --git a/config/contents/lint/empty_expression.md b/config/contents/lint/empty_expression.md index 00c073f4..16f8d0ad 100644 --- a/config/contents/lint/empty_expression.md +++ b/config/contents/lint/empty_expression.md @@ -3,7 +3,17 @@ This cop checks for the presence of empty expressions. ### Example: # bad + foo = () if () bar + end + +### Example: + + # good + + foo = (some_expression) + if (some_expression) + bar end \ No newline at end of file diff --git a/config/contents/lint/empty_interpolation.md b/config/contents/lint/empty_interpolation.md index f07b17f1..e6b9e1cd 100644 --- a/config/contents/lint/empty_interpolation.md +++ b/config/contents/lint/empty_interpolation.md @@ -2,4 +2,12 @@ This cop checks for empty interpolation. ### Example: - "result is #{}" \ No newline at end of file + # bad + + "result is #{}" + +### Example: + + # good + + "result is #{some_result}" \ No newline at end of file diff --git a/config/contents/lint/empty_when.md b/config/contents/lint/empty_when.md index da74fb3a..1d345d6e 100644 --- a/config/contents/lint/empty_when.md +++ b/config/contents/lint/empty_when.md @@ -3,7 +3,17 @@ This cop checks for the presence of `when` branches without a body. ### Example: # bad + case foo when bar then 1 when baz then # nothing + end + +### Example: + + # good + + case foo + when bar then 1 + when baz then 2 end \ No newline at end of file diff --git a/config/contents/lint/end_alignment.md b/config/contents/lint/end_alignment.md index cc8ca6b1..4185a455 100644 --- a/config/contents/lint/end_alignment.md +++ b/config/contents/lint/end_alignment.md @@ -1,7 +1,7 @@ This cop checks whether the end keywords are aligned properly. -Three modes are supported through the `AlignWith` configuration -parameter: +Three modes are supported through the `EnforcedStyleAlignWith` +configuration parameter: If it's set to `keyword` (which is the default), the `end` shall be aligned with the start of the keyword (if, class, etc.). @@ -13,15 +13,35 @@ If it's set to `start_of_line`, the `end` shall be aligned with the start of the line where the matching keyword appears. ### Example: + + # bad + + variable = if true + end + +### Example: + + # EnforcedStyleAlignWith: keyword (default) + # good - # keyword style + variable = if true end - # variable style +### Example: + + # EnforcedStyleAlignWith: variable + + # good + variable = if true end - # start_of_line style +### Example: + + # EnforcedStyleAlignWith: start_of_line + + # good + puts(if true end) \ No newline at end of file diff --git a/config/contents/lint/end_in_method.md b/config/contents/lint/end_in_method.md new file mode 100644 index 00000000..34f440e0 --- /dev/null +++ b/config/contents/lint/end_in_method.md @@ -0,0 +1,24 @@ +This cop checks for END blocks in method definitions. + +### Example: + + # bad + + def some_method + END { do_something } + end + +### Example: + + # good + + def some_method + at_exit { do_something } + end + +### Example: + + # good + + # outside defs + END { do_something } \ No newline at end of file diff --git a/config/contents/lint/ensure_return.md b/config/contents/lint/ensure_return.md new file mode 100644 index 00000000..c155ed2e --- /dev/null +++ b/config/contents/lint/ensure_return.md @@ -0,0 +1,22 @@ +This cop checks for *return* from an *ensure* block. + +### Example: + + # bad + + begin + do_something + ensure + do_something_else + return + end + +### Example: + + # good + + begin + do_something + ensure + do_something_else + end \ No newline at end of file diff --git a/config/contents/lint/float_out_of_range.md b/config/contents/lint/float_out_of_range.md index 5da6a5ca..c910b236 100644 --- a/config/contents/lint/float_out_of_range.md +++ b/config/contents/lint/float_out_of_range.md @@ -3,8 +3,13 @@ really really really really really big. Too big. No-one needs Floats that big. If you need a float that big, something is wrong with you. ### Example: + # bad + float = 3.0e400 +### Example: + # good + float = 42.9 \ No newline at end of file diff --git a/config/contents/lint/format_parameter_mismatch.md b/config/contents/lint/format_parameter_mismatch.md index b66988b3..8945029e 100644 --- a/config/contents/lint/format_parameter_mismatch.md +++ b/config/contents/lint/format_parameter_mismatch.md @@ -4,4 +4,12 @@ passed as arguments. ### Example: + # bad + format('A value: %s and another: %i', a_value) + +### Example: + + # good + + format('A value: %s and another: %i', a_value, another) \ No newline at end of file diff --git a/config/contents/lint/handle_exceptions.md b/config/contents/lint/handle_exceptions.md new file mode 100644 index 00000000..18f4c96a --- /dev/null +++ b/config/contents/lint/handle_exceptions.md @@ -0,0 +1,41 @@ +This cop checks for *rescue* blocks with no body. + +### Example: + + # bad + + def some_method + do_something + rescue + # do nothing + end + +### Example: + + # bad + + begin + do_something + rescue + # do nothing + end + +### Example: + + # good + + def some_method + do_something + rescue + handle_exception + end + +### Example: + + # good + + begin + do_something + rescue + handle_exception + end \ No newline at end of file diff --git a/config/contents/lint/implicit_string_concatenation.md b/config/contents/lint/implicit_string_concatenation.md index e957b838..e0ec682e 100644 --- a/config/contents/lint/implicit_string_concatenation.md +++ b/config/contents/lint/implicit_string_concatenation.md @@ -2,10 +2,15 @@ This cop checks for implicit string concatenation of string literals which are on the same line. ### Example: + # bad + array = ['Item 1' 'Item 2'] +### Example: + # good + array = ['Item 1Item 2'] array = ['Item 1' + 'Item 2'] array = [ diff --git a/config/contents/lint/ineffective_access_modifier.md b/config/contents/lint/ineffective_access_modifier.md index 8238b25d..7ea298fd 100644 --- a/config/contents/lint/ineffective_access_modifier.md +++ b/config/contents/lint/ineffective_access_modifier.md @@ -4,7 +4,9 @@ singleton methods private/protected. `private_class_method` can be used for that. ### Example: + # bad + class C private @@ -13,7 +15,10 @@ used for that. end end +### Example: + # good + class C def self.method puts 'hi' @@ -22,6 +27,10 @@ used for that. private_class_method :method end +### Example: + + # good + class C class << self private diff --git a/config/contents/lint/interpolation_check.md b/config/contents/lint/interpolation_check.md new file mode 100644 index 00000000..c74e058f --- /dev/null +++ b/config/contents/lint/interpolation_check.md @@ -0,0 +1,13 @@ +This cop checks for interpolation in a single quoted string. + +### Example: + + # bad + + foo = 'something with #{interpolation} inside' + +### Example: + + # good + + foo = "something with #{interpolation} inside" \ No newline at end of file diff --git a/config/contents/lint/invalid_character_literal.md b/config/contents/lint/invalid_character_literal.md index a4b42eba..20d01a72 100644 --- a/config/contents/lint/invalid_character_literal.md +++ b/config/contents/lint/invalid_character_literal.md @@ -11,4 +11,7 @@ warning without syntax errors. ^ ### Example: + + # bad + p(? ) \ No newline at end of file diff --git a/config/contents/lint/literal_in_condition.md b/config/contents/lint/literal_in_condition.md index 622844dd..8a7d79be 100644 --- a/config/contents/lint/literal_in_condition.md +++ b/config/contents/lint/literal_in_condition.md @@ -4,10 +4,24 @@ if/while/until. ### Example: + # bad + if 20 do_something end +### Example: + + # bad + if some_var && true do_something end + +### Example: + + # good + + if some_var && some_condition + do_something + end \ No newline at end of file diff --git a/config/contents/lint/literal_in_interpolation.md b/config/contents/lint/literal_in_interpolation.md index 2d64b0a2..859ee1d0 100644 --- a/config/contents/lint/literal_in_interpolation.md +++ b/config/contents/lint/literal_in_interpolation.md @@ -2,4 +2,12 @@ This cop checks for interpolated literals. ### Example: - "result is #{10}" \ No newline at end of file + # bad + + "result is #{10}" + +### Example: + + # good + + "result is 10" \ No newline at end of file diff --git a/config/contents/lint/loop.md b/config/contents/lint/loop.md new file mode 100644 index 00000000..63d115a0 --- /dev/null +++ b/config/contents/lint/loop.md @@ -0,0 +1,37 @@ +This cop checks for uses of *begin...end while/until something*. + +### Example: + + # bad + + # using while + begin + do_something + end while some_condition + +### Example: + + # bad + + # using until + begin + do_something + end until some_condition + +### Example: + + # good + + # using while + while some_condition + do_something + end + +### Example: + + # good + + # using until + until some_condition + do_something + end \ No newline at end of file diff --git a/config/contents/lint/multiple_compare.md b/config/contents/lint/multiple_compare.md new file mode 100644 index 00000000..ad4bdabe --- /dev/null +++ b/config/contents/lint/multiple_compare.md @@ -0,0 +1,18 @@ +In math and Python, we can use `x < y < z` style comparison to compare +multiple value. However, we can't use the comparison in Ruby. However, +the comparison is not syntax error. This cop checks the bad usage of +comparison operators. + +### Example: + + # bad + + x < y < z + 10 <= x <= 20 + +### Example: + + # good + + x < y && y < z + 10 <= x && x <= 20 \ No newline at end of file diff --git a/config/contents/lint/nested_method_definition.md b/config/contents/lint/nested_method_definition.md index df93cb89..32e0b308 100644 --- a/config/contents/lint/nested_method_definition.md +++ b/config/contents/lint/nested_method_definition.md @@ -1,6 +1,9 @@ This cop checks for nested method definitions. ### Example: + + # bad + # `bar` definition actually produces methods in the same scope # as the outer `foo` method. Furthermore, the `bar` method # will be redefined every time `foo` is invoked. @@ -8,3 +11,41 @@ This cop checks for nested method definitions. def bar end end + +### Example: + + # good + + def foo + bar = -> { puts 'hello' } + bar.call + end + +### Example: + + # good + + def foo + self.class_eval do + def bar + end + end + end + + def foo + self.module_exec do + def bar + end + end + end + +### Example: + + # good + + def foo + class << self + def bar + end + end + end \ No newline at end of file diff --git a/config/contents/lint/next_without_accumulator.md b/config/contents/lint/next_without_accumulator.md index afa476c3..b3226b11 100644 --- a/config/contents/lint/next_without_accumulator.md +++ b/config/contents/lint/next_without_accumulator.md @@ -1,13 +1,18 @@ Don't omit the accumulator when calling `next` in a `reduce` block. ### Example: + # bad + result = (1..4).reduce(0) do |acc, i| next if i.odd? acc + i end +### Example: + # good + result = (1..4).reduce(0) do |acc, i| next acc if i.odd? acc + i diff --git a/config/contents/lint/non_local_exit_from_iterator.md b/config/contents/lint/non_local_exit_from_iterator.md index 1b8036c9..25268aa1 100644 --- a/config/contents/lint/non_local_exit_from_iterator.md +++ b/config/contents/lint/non_local_exit_from_iterator.md @@ -1,8 +1,13 @@ -This cop checks for non-local exit from iterator, without return value. -It warns only when satisfies all of these: `return` doesn't have return -value, the block is preceded by a method chain, the block has arguments, -and the method which receives the block is not `define_method` -or `define_singleton_method`. +This cop checks for non-local exits from iterators without a return +value. It registers an offense under these conditions: + + - No value is returned, + - the block is preceded by a method chain, + - the block has arguments, + - the method which receives the block is not `define_method` + or `define_singleton_method`, + - the return is not contained in an inner scope, e.g. a lambda or a + method definition. ### Example: diff --git a/config/contents/lint/parentheses_as_grouped_expression.md b/config/contents/lint/parentheses_as_grouped_expression.md index 336f2db7..8b765e01 100644 --- a/config/contents/lint/parentheses_as_grouped_expression.md +++ b/config/contents/lint/parentheses_as_grouped_expression.md @@ -3,4 +3,12 @@ parenthesis. ### Example: - puts (x + y) \ No newline at end of file + # bad + + puts (x + y) + +### Example: + + # good + + puts(x + y) \ No newline at end of file diff --git a/config/contents/lint/percent_string_array.md b/config/contents/lint/percent_string_array.md index fe7e821c..4f674b5a 100644 --- a/config/contents/lint/percent_string_array.md +++ b/config/contents/lint/percent_string_array.md @@ -1,7 +1,17 @@ -This cop checks for quotes and commas in %w, e.g. +This cop checks for quotes and commas in %w, e.g. `%w('foo', "bar")` - `%w('foo', "bar")` - -it is more likely that the additional characters are unintended (for +It is more likely that the additional characters are unintended (for example, mistranslating an array of literals to percent string notation) -rather than meant to be part of the resulting strings. \ No newline at end of file +rather than meant to be part of the resulting strings. + +### Example: + + # bad + + %w('foo', "bar") + +### Example: + + # good + + %w(foo bar) \ No newline at end of file diff --git a/config/contents/lint/percent_symbol_array.md b/config/contents/lint/percent_symbol_array.md index c247d5f9..bb4331de 100644 --- a/config/contents/lint/percent_symbol_array.md +++ b/config/contents/lint/percent_symbol_array.md @@ -1,7 +1,17 @@ -This cop checks for colons and commas in %i, e.g. +This cop checks for colons and commas in %i, e.g. `%i(:foo, :bar)` - `%i(:foo, :bar)` - -it is more likely that the additional characters are unintended (for +It is more likely that the additional characters are unintended (for example, mistranslating an array of literals to percent string notation) -rather than meant to be part of the resulting symbols. \ No newline at end of file +rather than meant to be part of the resulting symbols. + +### Example: + + # bad + + %i(:foo, :bar) + +### Example: + + # good + + %i(foo bar) \ No newline at end of file diff --git a/config/contents/lint/rand_one.md b/config/contents/lint/rand_one.md index 4b9fcd04..ecd016d8 100644 --- a/config/contents/lint/rand_one.md +++ b/config/contents/lint/rand_one.md @@ -4,10 +4,14 @@ Such calls always return `0`. ### Example: # bad + rand 1 Kernel.rand(-1) rand 1.0 rand(-1.0) +### Example: + # good - 0 \ No newline at end of file + + 0 # just use 0 instead \ No newline at end of file diff --git a/config/contents/lint/redundant_with_index.md b/config/contents/lint/redundant_with_index.md new file mode 100644 index 00000000..3dc86d07 --- /dev/null +++ b/config/contents/lint/redundant_with_index.md @@ -0,0 +1,22 @@ +This cop checks for redundant `with_index`. + +### Example: + # bad + ary.each_with_index do |v| + v + end + + # good + ary.each do |v| + v + end + + # bad + ary.each.with_index do |v| + v + end + + # good + ary.each do |v| + v + end diff --git a/config/contents/lint/require_parentheses.md b/config/contents/lint/require_parentheses.md index 18ba6dc6..da99dcde 100644 --- a/config/contents/lint/require_parentheses.md +++ b/config/contents/lint/require_parentheses.md @@ -9,6 +9,14 @@ an operand of &&/||. ### Example: + # bad + if day.is? :tuesday && month == :jan ... - end \ No newline at end of file + end + +### Example: + + # good + + if day.is?(:tuesday) && month == :jan \ No newline at end of file diff --git a/config/contents/lint/rescue_exception.md b/config/contents/lint/rescue_exception.md new file mode 100644 index 00000000..ebd8411f --- /dev/null +++ b/config/contents/lint/rescue_exception.md @@ -0,0 +1,21 @@ +This cop checks for *rescue* blocks targeting the Exception class. + +### Example: + + # bad + + begin + do_something + rescue Exception + handle_exception + end + +### Example: + + # good + + begin + do_something + rescue ArgumentError + handle_exception + end \ No newline at end of file diff --git a/config/contents/lint/rescue_type.md b/config/contents/lint/rescue_type.md new file mode 100644 index 00000000..cfd8ef2e --- /dev/null +++ b/config/contents/lint/rescue_type.md @@ -0,0 +1,31 @@ +Check for arguments to `rescue` that will result in a `TypeError` +if an exception is raised. + +### Example: + # bad + begin + bar + rescue nil + baz + end + + # bad + def foo + bar + rescue 1, 'a', "#{b}", 0.0, [], {} + baz + end + + # good + begin + bar + rescue + baz + end + + # good + def foo + bar + rescue NameError + baz + end \ No newline at end of file diff --git a/config/contents/lint/rescue_without_error_class.md b/config/contents/lint/rescue_without_error_class.md new file mode 100644 index 00000000..8d75472a --- /dev/null +++ b/config/contents/lint/rescue_without_error_class.md @@ -0,0 +1,17 @@ +This cop checks for uses of `rescue` with no error class specified. + +### Example: + + # good + begin + foo + rescue BarError + bar + end + + # bad + begin + foo + rescue + bar + end \ No newline at end of file diff --git a/config/contents/lint/return_in_void_context.md b/config/contents/lint/return_in_void_context.md new file mode 100644 index 00000000..3c378996 --- /dev/null +++ b/config/contents/lint/return_in_void_context.md @@ -0,0 +1,28 @@ +This cop checks for the use of a return with a value in a context +where the value will be ignored. (initialize and setter methods) + +### Example: + + # bad + def initialize + foo + return :qux if bar? + baz + end + + def foo=(bar) + return 42 + end + +### Example: + + # good + def initialize + foo + return if bar? + baz + end + + def foo=(bar) + return + end \ No newline at end of file diff --git a/config/contents/lint/safe_navigation_chain.md b/config/contents/lint/safe_navigation_chain.md new file mode 100644 index 00000000..d4ba8403 --- /dev/null +++ b/config/contents/lint/safe_navigation_chain.md @@ -0,0 +1,20 @@ +The safe navigation operator returns nil if the receiver is +nil. If you chain an ordinary method call after a safe +navigation operator, it raises NoMethodError. We should use a +safe navigation operator after a safe navigation operator. +This cop checks for the problem outlined above. + +### Example: + + # bad + + x&.foo.bar + x&.foo + bar + x&.foo[bar] + +### Example: + + # good + + x&.foo&.bar + x&.foo || bar \ No newline at end of file diff --git a/config/contents/lint/shadowed_exception.md b/config/contents/lint/shadowed_exception.md index 02f43cc9..f8f7a240 100644 --- a/config/contents/lint/shadowed_exception.md +++ b/config/contents/lint/shadowed_exception.md @@ -3,7 +3,9 @@ less specific exception being rescued before a more specific exception is rescued. ### Example: + # bad + begin something rescue Exception @@ -12,7 +14,10 @@ exception is rescued. handle_standard_error end +### Example: + # good + begin something rescue StandardError diff --git a/config/contents/lint/shadowing_outer_local_variable.md b/config/contents/lint/shadowing_outer_local_variable.md index 634cb302..e203a051 100644 --- a/config/contents/lint/shadowing_outer_local_variable.md +++ b/config/contents/lint/shadowing_outer_local_variable.md @@ -1,4 +1,28 @@ This cop looks for use of the same name as outer local variables for block arguments or block local variables. This is a mimic of the warning -"shadowing outer local variable - foo" from `ruby -cw`. \ No newline at end of file +"shadowing outer local variable - foo" from `ruby -cw`. + +### Example: + + # bad + + def some_method + foo = 1 + + 2.times do |foo| # shadowing outer `foo` + do_something(foo) + end + end + +### Example: + + # good + + def some_method + foo = 1 + + 2.times do |bar| + do_something(bar) + end + end \ No newline at end of file diff --git a/config/contents/lint/string_conversion_in_interpolation.md b/config/contents/lint/string_conversion_in_interpolation.md index d57c1973..49db53fa 100644 --- a/config/contents/lint/string_conversion_in_interpolation.md +++ b/config/contents/lint/string_conversion_in_interpolation.md @@ -3,4 +3,12 @@ which is redundant. ### Example: - "result is #{something.to_s}" \ No newline at end of file + # bad + + "result is #{something.to_s}" + +### Example: + + # good + + "result is #{something}" \ No newline at end of file diff --git a/config/contents/lint/underscore_prefixed_variable_name.md b/config/contents/lint/underscore_prefixed_variable_name.md new file mode 100644 index 00000000..a5a77a76 --- /dev/null +++ b/config/contents/lint/underscore_prefixed_variable_name.md @@ -0,0 +1,26 @@ +This cop checks for underscore-prefixed variables that are actually +used. + +### Example: + + # bad + + [1, 2, 3].each do |_num| + do_something(_num) + end + +### Example: + + # good + + [1, 2, 3].each do |num| + do_something(num) + end + +### Example: + + # good + + [1, 2, 3].each do |_num| + do_something # not using `_num` + end \ No newline at end of file diff --git a/config/contents/lint/unified_integer.md b/config/contents/lint/unified_integer.md index 33e3b235..b8b2ac73 100644 --- a/config/contents/lint/unified_integer.md +++ b/config/contents/lint/unified_integer.md @@ -1,9 +1,14 @@ This cop checks for using Fixnum or Bignum constant. ### Example: + # bad + 1.is_a?(Fixnum) 1.is_a?(Bignum) +### Example: + # good + 1.is_a?(Integer) \ No newline at end of file diff --git a/config/contents/lint/unneeded_splat_expansion.md b/config/contents/lint/unneeded_splat_expansion.md index 14dff6cb..af4953f0 100644 --- a/config/contents/lint/unneeded_splat_expansion.md +++ b/config/contents/lint/unneeded_splat_expansion.md @@ -1,7 +1,9 @@ This cop checks for unneeded usages of splat expansion ### Example: + # bad + a = *[1, 2, 3] a = *'a' a = *1 @@ -19,7 +21,10 @@ This cop checks for unneeded usages of splat expansion baz end +### Example: + # good + c = [1, 2, 3] a = *c a, b = *c diff --git a/config/contents/lint/unreachable_code.md b/config/contents/lint/unreachable_code.md index fcfcbce9..e00b649f 100644 --- a/config/contents/lint/unreachable_code.md +++ b/config/contents/lint/unreachable_code.md @@ -1,3 +1,31 @@ This cop checks for unreachable code. The check are based on the presence of flow of control -statement in non-final position in *begin*(implicit) blocks. \ No newline at end of file +statement in non-final position in *begin*(implicit) blocks. + +### Example: + + # bad + + def some_method + return + do_something + end + + # bad + + def some_method + if cond + return + else + return + end + do_something + end + +### Example: + + # good + + def some_method + do_something + end \ No newline at end of file diff --git a/config/contents/lint/unused_block_argument.md b/config/contents/lint/unused_block_argument.md index d5715db9..d4263b69 100644 --- a/config/contents/lint/unused_block_argument.md +++ b/config/contents/lint/unused_block_argument.md @@ -2,30 +2,32 @@ This cop checks for unused block arguments. ### Example: - #good + # bad do_something do |used, unused| puts used end - do_something do + do_something do |bar| puts :foo end - define_method(:foo) do |_bar| + define_method(:foo) do |bar| puts :baz end - # bad +### Example: + + #good do_something do |used, _unused| puts used end - do_something do |bar| + do_something do puts :foo end - define_method(:foo) do |bar| + define_method(:foo) do |_bar| puts :baz end \ No newline at end of file diff --git a/config/contents/lint/unused_method_argument.md b/config/contents/lint/unused_method_argument.md index f7ffa118..05105013 100644 --- a/config/contents/lint/unused_method_argument.md +++ b/config/contents/lint/unused_method_argument.md @@ -2,6 +2,16 @@ This cop checks for unused method arguments. ### Example: + # bad + def some_method(used, unused, _unused_but_allowed) puts used + end + +### Example: + + # good + + def some_method(used, _unused, _unused_but_allowed) + puts used end \ No newline at end of file diff --git a/config/contents/lint/uri_escape_unescape.md b/config/contents/lint/uri_escape_unescape.md new file mode 100644 index 00000000..5ac52c40 --- /dev/null +++ b/config/contents/lint/uri_escape_unescape.md @@ -0,0 +1,25 @@ +This cop identifies places where `URI.escape` can be replaced by +`CGI.escape`, `URI.encode_www_form` or `URI.encode_www_form_component` +depending on your specific use case. +Also this cop identifies places where `URI.unescape` can be replaced by +`CGI.unescape`, `URI.decode_www_form` or `URI.decode_www_form_component` +depending on your specific use case. + +### Example: + # bad + URI.escape('http://example.com') + URI.encode('http://example.com') + + # good + CGI.escape('http://example.com') + URI.encode_www_form('http://example.com') + URI.encode_www_form_component('http://example.com') + + # bad + URI.unescape(enc_uri) + URI.decode(enc_uri) + + # good + CGI.unescape(enc_uri) + URI.decode_www_form(enc_uri) + URI.decode_www_form_component(enc_uri) \ No newline at end of file diff --git a/config/contents/lint/uri_regexp.md b/config/contents/lint/uri_regexp.md new file mode 100644 index 00000000..269f95eb --- /dev/null +++ b/config/contents/lint/uri_regexp.md @@ -0,0 +1,9 @@ +This cop identifies places where `URI.regexp` is obsolete and should +not be used. Instead, use `URI::DEFAULT_PARSER.make_regexp`. + +### Example: + # bad + URI.regexp('http://example.com') + + # good + URI::DEFAULT_PARSER.make_regexp('http://example.com') diff --git a/config/contents/lint/useless_access_modifier.md b/config/contents/lint/useless_access_modifier.md index 7e422305..244449bd 100644 --- a/config/contents/lint/useless_access_modifier.md +++ b/config/contents/lint/useless_access_modifier.md @@ -72,4 +72,16 @@ are not redundant. def some_other_private_method end + end + +### Example: + # Lint/UselessAccessModifier: + # MethodCreatingMethods: + # - delegate + require 'active_support/core_ext/module/delegation' + class Foo + # this is not redundant because `delegate` creates methods + private + + delegate :method_a, to: :method_b end \ No newline at end of file diff --git a/config/contents/lint/useless_assignment.md b/config/contents/lint/useless_assignment.md index 42a33b4c..2ed8d7e2 100644 --- a/config/contents/lint/useless_assignment.md +++ b/config/contents/lint/useless_assignment.md @@ -6,4 +6,22 @@ The basic idea for this cop was from the warning of `ruby -cw`: Currently this cop has advanced logic that detects unreferenced reassignments and properly handles varied cases such as branch, loop, -rescue, ensure, etc. \ No newline at end of file +rescue, ensure, etc. + +### Example: + + # bad + + def some_method + some_var = 1 + do_something + end + +### Example: + + # good + + def some_method + some_var = 1 + do_something(some_var) + end \ No newline at end of file diff --git a/config/contents/lint/useless_comparison.md b/config/contents/lint/useless_comparison.md index fa38ec62..9aacab37 100644 --- a/config/contents/lint/useless_comparison.md +++ b/config/contents/lint/useless_comparison.md @@ -2,4 +2,6 @@ This cop checks for comparison of something with itself. ### Example: - x.top >= x.top \ No newline at end of file + # bad + + x.top >= x.top \ No newline at end of file diff --git a/config/contents/lint/useless_else_without_rescue.md b/config/contents/lint/useless_else_without_rescue.md index 0eec0fef..0aae7485 100644 --- a/config/contents/lint/useless_else_without_rescue.md +++ b/config/contents/lint/useless_else_without_rescue.md @@ -1,8 +1,23 @@ This cop checks for useless `else` in `begin..end` without `rescue`. ### Example: + + # bad + + begin + do_something + else + do_something_else # This will never be run. + end + +### Example: + + # good + begin do_something + rescue + handle_errors else - handle_errors # This will never be run. + do_something_else end \ No newline at end of file diff --git a/config/contents/lint/useless_setter_call.md b/config/contents/lint/useless_setter_call.md index 239dfd5d..fa5ca9e6 100644 --- a/config/contents/lint/useless_setter_call.md +++ b/config/contents/lint/useless_setter_call.md @@ -3,7 +3,19 @@ expression of a function definition. ### Example: - def something - x = Something.new - x.attr = 5 - end \ No newline at end of file + # bad + + def something + x = Something.new + x.attr = 5 + end + +### Example: + + # good + + def something + x = Something.new + x.attr = 5 + x + end \ No newline at end of file diff --git a/config/contents/lint/void.md b/config/contents/lint/void.md new file mode 100644 index 00000000..816a07d7 --- /dev/null +++ b/config/contents/lint/void.md @@ -0,0 +1,38 @@ +This cop checks for operators, variables and literals used +in void context. + +### Example: + + # bad + + def some_method + some_num * 10 + do_something + end + +### Example: + + # bad + + def some_method(some_var) + some_var + do_something + end + +### Example: + + # good + + def some_method + do_something + some_num * 10 + end + +### Example: + + # good + + def some_method(some_var) + do_something + some_var + end \ No newline at end of file diff --git a/config/contents/metrics/block_length.md b/config/contents/metrics/block_length.md index 68dfd3fa..585f1e86 100644 --- a/config/contents/metrics/block_length.md +++ b/config/contents/metrics/block_length.md @@ -1,3 +1,4 @@ This cop checks if the length of a block exceeds some maximum value. Comment lines can optionally be ignored. -The maximum allowed length is configurable. \ No newline at end of file +The maximum allowed length is configurable. +The cop can be configured to ignore blocks passed to certain methods. \ No newline at end of file diff --git a/config/contents/metrics/block_nesting.md b/config/contents/metrics/block_nesting.md index 67994d76..d575e978 100644 --- a/config/contents/metrics/block_nesting.md +++ b/config/contents/metrics/block_nesting.md @@ -1,5 +1,8 @@ This cop checks for excessive nesting of conditional and looping -constructs. Despite the cop's name, blocks are not considered as an -extra level of nesting. +constructs. + +You can configure if blocks are considered using the `CountBlocks` +option. When set to `false` (the default) blocks are not counted +towards the nesting level. Set to `true` to count blocks as well. The maximum level of nesting allowed is configurable. \ No newline at end of file diff --git a/config/contents/performance/caller.md b/config/contents/performance/caller.md new file mode 100644 index 00000000..618ecb1f --- /dev/null +++ b/config/contents/performance/caller.md @@ -0,0 +1,15 @@ +This cop identifies places where `caller[n]` +can be replaced by `caller(n..n).first`. + +### Example: + # bad + caller[1] + caller.first + caller_locations[1] + caller_locations.first + + # good + caller(2..2).first + caller(1..1).first + caller_locations(2..2).first + caller_locations(1..1).first \ No newline at end of file diff --git a/config/contents/performance/compare_with_block.md b/config/contents/performance/compare_with_block.md index 896044df..9cf8359f 100644 --- a/config/contents/performance/compare_with_block.md +++ b/config/contents/performance/compare_with_block.md @@ -7,6 +7,7 @@ This cop also checks `max` and `min` methods. array.sort { |a, b| a.foo <=> b.foo } array.max { |a, b| a.foo <=> b.foo } array.min { |a, b| a.foo <=> b.foo } + array.sort { |a, b| a[:foo] <=> b[:foo] } # good array.sort_by(&:foo) @@ -15,4 +16,5 @@ This cop also checks `max` and `min` methods. var.foo end array.max_by(&:foo) - array.min_by(&:foo) \ No newline at end of file + array.min_by(&:foo) + array.sort_by { |a| a[:foo] } \ No newline at end of file diff --git a/config/contents/performance/end_with.md b/config/contents/performance/end_with.md index d17db641..28288b6d 100644 --- a/config/contents/performance/end_with.md +++ b/config/contents/performance/end_with.md @@ -7,5 +7,4 @@ would suffice. 'abc'.match(/bc\Z/) # good - 'abc' =~ /ab/ - 'abc' =~ /\w*\Z/ \ No newline at end of file + 'abc'.end_with?('bc') \ No newline at end of file diff --git a/config/contents/performance/redundant_match.md b/config/contents/performance/redundant_match.md index d6645bdd..748bd177 100644 --- a/config/contents/performance/redundant_match.md +++ b/config/contents/performance/redundant_match.md @@ -1,4 +1,4 @@ -This cop identifies use of `Regexp#match` or `String#match in a context +This cop identifies use of `Regexp#match` or `String#match` in a context where the integral return value of `=~` would do just as well. ### Example: diff --git a/config/contents/performance/regexp_match.md b/config/contents/performance/regexp_match.md new file mode 100644 index 00000000..a7e00f14 --- /dev/null +++ b/config/contents/performance/regexp_match.md @@ -0,0 +1,55 @@ +In Ruby 2.4, `String#match?`, `Regexp#match?` and `Symbol#match?` +have been added. The methods are faster than `match`. +Because the methods avoid creating a `MatchData` object or saving +backref. +So, when `MatchData` is not used, use `match?` instead of `match`. + +### Example: + # bad + def foo + if x =~ /re/ + do_something + end + end + + # bad + def foo + if x.match(/re/) + do_something + end + end + + # bad + def foo + if /re/ === x + do_something + end + end + + # good + def foo + if x.match?(/re/) + do_something + end + end + + # good + def foo + if x =~ /re/ + do_something(Regexp.last_match) + end + end + + # good + def foo + if x.match(/re/) + do_something($~) + end + end + + # good + def foo + if /re/ === x + do_something($~) + end + end \ No newline at end of file diff --git a/config/contents/performance/start_with.md b/config/contents/performance/start_with.md index 2ab24a29..47218efa 100644 --- a/config/contents/performance/start_with.md +++ b/config/contents/performance/start_with.md @@ -7,5 +7,4 @@ This cop identifies unnecessary use of a regex where 'abc'.match(/\Aab/) # good - 'abc' =~ /ab/ - 'abc' =~ /\A\w*/ \ No newline at end of file + 'abc'.start_with?('ab') \ No newline at end of file diff --git a/config/contents/performance/unfreeze_string.md b/config/contents/performance/unfreeze_string.md new file mode 100644 index 00000000..6fae6aed --- /dev/null +++ b/config/contents/performance/unfreeze_string.md @@ -0,0 +1,20 @@ +In Ruby 2.3 or later, use unary plus operator to unfreeze a string +literal instead of `String#dup` and `String.new`. +Unary plus operator is faster than `String#dup`. + +Note: `String.new` (without operator) is not exactly the same as `+''`. +These differ in encoding. `String.new.encoding` is always `ASCII-8BIT`. +However, `(+'').encoding` is the same as script encoding(e.g. `UTF-8`). +So, if you expect `ASCII-8BIT` encoding, disable this cop. + +### Example: + # bad + ''.dup + "something".dup + String.new + String.new('') + String.new('something') + + # good + +'something' + +'' \ No newline at end of file diff --git a/config/contents/performance/uri_default_parser.md b/config/contents/performance/uri_default_parser.md new file mode 100644 index 00000000..aba62454 --- /dev/null +++ b/config/contents/performance/uri_default_parser.md @@ -0,0 +1,9 @@ +This cop identifies places where `URI::Parser.new` +can be replaced by `URI::DEFAULT_PARSER`. + +### Example: + # bad + URI::Parser.new + + # good + URI::DEFAULT_PARSER diff --git a/config/contents/rails/action_filter.md b/config/contents/rails/action_filter.md index ec40111d..d253b9d4 100644 --- a/config/contents/rails/action_filter.md +++ b/config/contents/rails/action_filter.md @@ -1,4 +1,7 @@ This cop enforces the consistent use of action filter methods. The cop is configurable and can enforce the use of the older -something_filter methods or the newer something_action methods. \ No newline at end of file +something_filter methods or the newer something_action methods. + +If the TargetRailsVersion is set to less than 4.0, the cop will enforce +the use of filter methods. \ No newline at end of file diff --git a/config/contents/rails/active_support_aliases.md b/config/contents/rails/active_support_aliases.md new file mode 100644 index 00000000..d544026f --- /dev/null +++ b/config/contents/rails/active_support_aliases.md @@ -0,0 +1,15 @@ +This cop checks that ActiveSupport aliases to core ruby methods +are not used. + +### Example: + # good + 'some_string'.start_with?('prefix') + 'some_string'.end_with?('suffix') + [1, 2, 'a'] << 'b' + [1, 2, 'a'].unshift('b') + + # bad + 'some_string'.starts_with?('prefix') + 'some_string'.ends_with?('suffix') + [1, 2, 'a'].append('b') + [1, 2, 'a'].prepend('b') diff --git a/config/contents/rails/application_job.md b/config/contents/rails/application_job.md new file mode 100644 index 00000000..0f82d5fe --- /dev/null +++ b/config/contents/rails/application_job.md @@ -0,0 +1,13 @@ +This cop checks that jobs subclass ApplicationJob with Rails 5.0. + +### Example: + + # good + class Rails5Job < ApplicationJob + ... + end + + # bad + class Rails4Job < ActiveJob::Base + ... + end \ No newline at end of file diff --git a/config/contents/rails/application_record.md b/config/contents/rails/application_record.md new file mode 100644 index 00000000..d0f39367 --- /dev/null +++ b/config/contents/rails/application_record.md @@ -0,0 +1,13 @@ +This cop checks that models subclass ApplicationRecord with Rails 5.0. + +### Example: + + # good + class Rails5Model < ApplicationRecord + ... + end + + # bad + class Rails4Model < ActiveRecord::Base + ... + end \ No newline at end of file diff --git a/config/contents/rails/blank.md b/config/contents/rails/blank.md new file mode 100644 index 00000000..96dc9c0a --- /dev/null +++ b/config/contents/rails/blank.md @@ -0,0 +1,34 @@ +This cops checks for code that can be changed to `blank?`. +Settings: + NilOrEmpty: Convert checks for `nil` or `empty?` to `blank?` + NotPresent: Convert usages of not `present?` to `blank?` + UnlessPresent: Convert usages of `unless` `present?` to `blank?` + +### Example: + # NilOrEmpty: true + # bad + foo.nil? || foo.empty? + foo == nil || foo.empty? + + # good + foo.blank? + + # NotPresent: true + # bad + !foo.present? + + # good + foo.blank? + + # UnlessPresent: true + # bad + something unless foo.present? + unless foo.present? + something + end + + # good + something if foo.blank? + if foo.blank? + something + end \ No newline at end of file diff --git a/config/contents/rails/date.md b/config/contents/rails/date.md index 33406493..9fcf60c3 100644 --- a/config/contents/rails/date.md +++ b/config/contents/rails/date.md @@ -20,7 +20,7 @@ and only 'to_time' is reported as warning. Time.zone.today Time.zone.today - 1.day - # acceptable + # flexible Date.current Date.yesterday diff --git a/config/contents/rails/delegate.md b/config/contents/rails/delegate.md index 3741c1f3..3fdb58c3 100644 --- a/config/contents/rails/delegate.md +++ b/config/contents/rails/delegate.md @@ -1,5 +1,14 @@ -This cop looks for delegations, that could have been created -automatically with delegate method. +This cop looks for delegations that could have been created +automatically with the `delegate` method. + +Safe navigation `&.` is ignored because Rails' `allow_nil` +option checks not just for nil but also delegates if nil +responds to the delegated method. + +The `EnforceForPrefixed` option (defaulted to `true`) means that +using the target object as a prefix of the method name +without using the `delegate` method will be a violation. +When set to `false`, this case is legal. ### Example: # bad @@ -10,6 +19,18 @@ automatically with delegate method. # good delegate :bar, to: :foo + # good + def bar + foo&.bar + end + + # good + private + def bar + foo.bar + end + + # EnforceForPrefixed: true # bad def foo_bar foo.bar @@ -18,8 +39,11 @@ automatically with delegate method. # good delegate :bar, to: :foo, prefix: true + # EnforceForPrefixed: false # good - private - def bar + def foo_bar foo.bar - end \ No newline at end of file + end + + # good + delegate :bar, to: :foo, prefix: true \ No newline at end of file diff --git a/config/contents/rails/file_path.md b/config/contents/rails/file_path.md new file mode 100644 index 00000000..399cc86a --- /dev/null +++ b/config/contents/rails/file_path.md @@ -0,0 +1,11 @@ +This cop is used to identify usages of file path joining process +to use `Rails.root.join` clause. + +### Example: + # bad + Rails.root.join('app/models/goober') + File.join(Rails.root, 'app/models/goober') + "#{Rails.root}/app/models/goober" + + # good + Rails.root.join('app', 'models', 'goober') \ No newline at end of file diff --git a/config/contents/rails/has_many_or_has_one_dependent.md b/config/contents/rails/has_many_or_has_one_dependent.md new file mode 100644 index 00000000..b0e59188 --- /dev/null +++ b/config/contents/rails/has_many_or_has_one_dependent.md @@ -0,0 +1,15 @@ +This cop looks for `has_many` or `has_one` associations that don't +specify a `:dependent` option. + +### Example: + # bad + class User < ActiveRecord::Base + has_many :comments + has_one :avatar + end + + # good + class User < ActiveRecord::Base + has_many :comments, dependent: :restrict_with_exception + has_one :avatar, dependent: :destroy + end \ No newline at end of file diff --git a/config/contents/rails/http_positional_arguments.md b/config/contents/rails/http_positional_arguments.md index ac8dc938..c3676a5f 100644 --- a/config/contents/rails/http_positional_arguments.md +++ b/config/contents/rails/http_positional_arguments.md @@ -1,6 +1,9 @@ -This cop is used to identify usages of http methods -like `get`, `post`, `put`, `path` without the usage of keyword arguments -in your tests and change them to use keyword arguments. +This cop is used to identify usages of http methods like `get`, `post`, +`put`, `patch` without the usage of keyword arguments in your tests and +change them to use keyword args. This cop only applies to Rails >= 5 . +If you are running Rails < 5 you should disable the +Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your +.rubocop.yml file to 4.0, etc. ### Example: # bad diff --git a/config/contents/rails/not_null_column.md b/config/contents/rails/not_null_column.md index 5fab57e9..069f0cb3 100644 --- a/config/contents/rails/not_null_column.md +++ b/config/contents/rails/not_null_column.md @@ -4,7 +4,10 @@ in migration file. ### Example: # bad add_column :users, :name, :string, null: false + add_reference :products, :category, null: false # good add_column :users, :name, :string, null: true - add_column :users, :name, :string, null: false, default: '' \ No newline at end of file + add_column :users, :name, :string, null: false, default: '' + add_reference :products, :category + add_reference :products, :category, null: false, default: 1 \ No newline at end of file diff --git a/config/contents/rails/output_safety.md b/config/contents/rails/output_safety.md index 186df2f7..3a629a84 100644 --- a/config/contents/rails/output_safety.md +++ b/config/contents/rails/output_safety.md @@ -1,21 +1,64 @@ -This cop checks for the use of output safety calls like html_safe and -raw. +This cop checks for the use of output safety calls like html_safe, +raw, and safe_concat. These methods do not escape content. They +simply return a SafeBuffer containing the content as is. Instead, +use safe_join to join content and escape it and concat to +concatenate content and escape it, ensuring its safety. ### Example: + user_content = "hi" + # bad - "

#{text}

".html_safe + "

#{user_content}

".html_safe + => ActiveSupport::SafeBuffer + "

hi

" # good - content_tag(:p, text) + content_tag(:p, user_content) + => ActiveSupport::SafeBuffer + "

<b>hi</b>

" # bad out = "" - out << content_tag(:li, "one") - out << content_tag(:li, "two") + out << "
  • #{user_content}
  • " + out << "
  • #{user_content}
  • " out.html_safe + => ActiveSupport::SafeBuffer + "
  • hi
  • hi
  • " # good out = [] - out << content_tag(:li, "one") - out << content_tag(:li, "two") + out << content_tag(:li, user_content) + out << content_tag(:li, user_content) safe_join(out) + => ActiveSupport::SafeBuffer + "
  • <b>hi</b>
  • <b>hi</b>
  • " + + # bad + out = "

    trusted content

    ".html_safe + out.safe_concat(user_content) + => ActiveSupport::SafeBuffer + "

    trusted_content

    hi" + + # good + out = "

    trusted content

    ".html_safe + out.concat(user_content) + => ActiveSupport::SafeBuffer + "

    trusted_content

    <b>hi</b>" + + # safe, though maybe not good style + out = "trusted content" + result = out.concat(user_content) + => String "trusted contenthi" + # because when rendered in ERB the String will be escaped: + <%= result %> + => trusted content<b>hi</b> + + # bad + (user_content + " " + content_tag(:span, user_content)).html_safe + => ActiveSupport::SafeBuffer + "hi hi" + + # good + safe_join([user_content, " ", content_tag(:span, user_content)]) + => ActiveSupport::SafeBuffer + "<b>hi</b> <b>hi</b>" diff --git a/config/contents/rails/present.md b/config/contents/rails/present.md new file mode 100644 index 00000000..efd552ae --- /dev/null +++ b/config/contents/rails/present.md @@ -0,0 +1,31 @@ +This cops checks for code that can be changed to `blank?`. +Settings: + NotNilAndNotEmpty: Convert checks for not `nil` and `not empty?` + to `present?` + NotBlank: Convert usages of not `blank?` to `present?` + UnlessBlank: Convert usages of `unless` `blank?` to `if` `present?` + +### Example: + # NotNilAndNotEmpty: true + # bad + !foo.nil? && !foo.empty? + foo != nil && !foo.empty? + !foo.blank? + + # good + foo.present? + + # NotBlank: true + # bad + !foo.blank? + not foo.blank? + + # good + foo.present? + + # UnlessBlank: true + # bad + something unless foo.blank? + + # good + something if foo.present? \ No newline at end of file diff --git a/config/contents/rails/relative_date_constant.md b/config/contents/rails/relative_date_constant.md new file mode 100644 index 00000000..6393d81a --- /dev/null +++ b/config/contents/rails/relative_date_constant.md @@ -0,0 +1,15 @@ +This cop checks whether constant value isn't relative date. +Because the relative date will be evaluated only once. + +### Example: + # bad + class SomeClass + EXPIRED_AT = 1.week.since + end + + # good + class SomeClass + def self.expired_at + 1.week.since + end + end \ No newline at end of file diff --git a/config/contents/rails/request_referer.md b/config/contents/rails/request_referer.md new file mode 100644 index 00000000..5fe8d653 --- /dev/null +++ b/config/contents/rails/request_referer.md @@ -0,0 +1,17 @@ +This cop checks for consistent uses of `request.referer` or +`request.referrer`, depending on the cop's configuration. + +### Example: + # EnforcedStyle: referer + # bad + request.referrer + + # good + request.referer + + # EnforcedStyle: referrer + # bad + request.referer + + # good + request.referrer \ No newline at end of file diff --git a/config/contents/rails/reversible_migration.md b/config/contents/rails/reversible_migration.md new file mode 100644 index 00000000..37f97475 --- /dev/null +++ b/config/contents/rails/reversible_migration.md @@ -0,0 +1,122 @@ +This cop checks whether the change method of the migration file is +reversible. + +### Example: + # bad + def change + change_table :users do |t| + t.remove :name + end + end + + # good + def change + create_table :users do |t| + t.string :name + end + end + + # good + def change + reversible do |dir| + change_table :users do |t| + dir.up do + t.column :name, :string + end + + dir.down do + t.remove :name + end + end + end + end + +### Example: + # drop_table + + # bad + def change + drop_table :users + end + + # good + def change + drop_table :users do |t| + t.string :name + end + end + +### Example: + # change_column_default + + # bad + def change + change_column_default(:suppliers, :qualification, 'new') + end + + # good + def change + change_column_default(:posts, :state, from: nil, to: "draft") + end + +### Example: + # remove_column + + # bad + def change + remove_column(:suppliers, :qualification) + end + + # good + def change + remove_column(:suppliers, :qualification, :string) + end + +### Example: + # remove_foreign_key + + # bad + def change + remove_foreign_key :accounts, column: :owner_id + end + + # good + def change + remove_foreign_key :accounts, :branches + end + +### Example: + # change_table + + # bad + def change + change_table :users do |t| + t.remove :name + t.change_default :authorized, 1 + t.change :price, :string + end + end + + # good + def change + change_table :users do |t| + t.string :name + end + end + + # good + def change + reversible do |dir| + change_table :users do |t| + dir.up do + t.change :price, :string + end + + dir.down do + t.change :price, :integer + end + end + end + end + +@see http://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html \ No newline at end of file diff --git a/config/contents/rails/skips_model_validations.md b/config/contents/rails/skips_model_validations.md new file mode 100644 index 00000000..88c62222 --- /dev/null +++ b/config/contents/rails/skips_model_validations.md @@ -0,0 +1,20 @@ +This cop checks for the use of methods which skip +validations which are listed in +http://guides.rubyonrails.org/active_record_validations.html#skipping-validations + +### Example: + # bad + Article.first.decrement!(:view_count) + DiscussionBoard.decrement_counter(:post_count, 5) + Article.first.increment!(:view_count) + DiscussionBoard.increment_counter(:post_count, 5) + person.toggle :active + product.touch + Billing.update_all("category = 'authorized', author = 'David'") + user.update_attribute(website: 'example.com') + user.update_columns(last_request_at: Time.current) + Post.update_counters 5, comment_count: -1, action_count: 1 + + # good + user.update_attributes(website: 'example.com') + FileUtils.touch('file') \ No newline at end of file diff --git a/config/contents/rails/time_zone.md b/config/contents/rails/time_zone.md index c97d2871..1e60c2c3 100644 --- a/config/contents/rails/time_zone.md +++ b/config/contents/rails/time_zone.md @@ -18,7 +18,7 @@ to use Time.in_time_zone. Time.zone.now Time.zone.parse('2015-03-02 19:05:37') - # no offense only if style is 'acceptable' + # no offense only if style is 'flexible' Time.current DateTime.strptime(str, "%Y-%m-%d %H:%M %Z").in_time_zone Time.at(timestamp).in_time_zone \ No newline at end of file diff --git a/config/contents/rails/uniq_before_pluck.md b/config/contents/rails/uniq_before_pluck.md index bade13e0..a1b69c1b 100644 --- a/config/contents/rails/uniq_before_pluck.md +++ b/config/contents/rails/uniq_before_pluck.md @@ -10,11 +10,11 @@ the database. # good Model.uniq.pluck(:id) -This cop has two different enforcement modes. When the EnforcedMode +This cop has two different enforcement modes. When the EnforcedStyle is conservative (the default) then only calls to pluck on a constant (i.e. a model class) before uniq are added as offenses. -When the EnforcedMode is aggressive then all calls to pluck before +When the EnforcedStyle is aggressive then all calls to pluck before uniq are added as offenses. This may lead to false positives as the cop cannot distinguish between calls to pluck on an ActiveRecord::Relation vs a call to pluck on an ActiveRecord::Associations::CollectionProxy. diff --git a/config/contents/security/eval.md b/config/contents/security/eval.md new file mode 100644 index 00000000..5de6ce2b --- /dev/null +++ b/config/contents/security/eval.md @@ -0,0 +1,8 @@ +This cop checks for the use of `Kernel#eval` and `Binding#eval`. + +### Example: + + # bad + + eval(something) + binding.eval(something) \ No newline at end of file diff --git a/config/contents/security/marshal_load.md b/config/contents/security/marshal_load.md new file mode 100644 index 00000000..66c2a6b1 --- /dev/null +++ b/config/contents/security/marshal_load.md @@ -0,0 +1,14 @@ +This cop checks for the use of Marshal class methods which have +potential security issues leading to remote code execution when +loading from an untrusted source. + +### Example: + # bad + Marshal.load("{}") + Marshal.restore("{}") + + # good + Marshal.dump("{}") + + # okish - deep copy hack + Marshal.load(Marshal.dump({})) diff --git a/config/contents/security/yaml_load.md b/config/contents/security/yaml_load.md new file mode 100644 index 00000000..c428452c --- /dev/null +++ b/config/contents/security/yaml_load.md @@ -0,0 +1,11 @@ +This cop checks for the use of YAML class methods which have +potential security issues leading to remote code execution when +loading from an untrusted source. + +### Example: + # bad + YAML.load("--- foo") + + # good + YAML.safe_load("--- foo") + YAML.dump("foo") diff --git a/config/contents/style/alias.md b/config/contents/style/alias.md index 58222c98..8bcd5ef0 100644 --- a/config/contents/style/alias.md +++ b/config/contents/style/alias.md @@ -1,4 +1,24 @@ -This cop finds uses of `alias` where `alias_method` would be more -appropriate (or is simply preferred due to configuration), and vice -versa. -It also finds uses of `alias :symbol` rather than `alias bareword`. \ No newline at end of file +This cop enforces the use of either `#alias` or `#alias_method` +depending on configuration. +It also flags uses of `alias :symbol` rather than `alias bareword`. + +### Example: + + # EnforcedStyle: prefer_alias + + # good + alias bar foo + + # bad + alias_method :bar, :foo + alias :bar :foo + +### Example: + + # EnforcedStyle: prefer_alias_method + + # good + alias_method :bar, :foo + + # bad + alias bar foo \ No newline at end of file diff --git a/config/contents/style/and_or.md b/config/contents/style/and_or.md new file mode 100644 index 00000000..20e407f5 --- /dev/null +++ b/config/contents/style/and_or.md @@ -0,0 +1,27 @@ +This cop checks for uses of `and` and `or`, and suggests using `&&` and +`|| instead`. It can be configured to check only in conditions, or in +all contexts. + +### Example: + + # EnforcedStyle: always (default) + + # good + foo.save && return + if foo && bar + + # bad + foo.save and return + if foo and bar + +### Example: + + # EnforcedStyle: conditionals + + # good + foo.save && return + foo.save and return + if foo && bar + + # bad + if foo and bar \ No newline at end of file diff --git a/config/contents/style/auto_resource_cleanup.md b/config/contents/style/auto_resource_cleanup.md index 87d35ddc..55c8a90f 100644 --- a/config/contents/style/auto_resource_cleanup.md +++ b/config/contents/style/auto_resource_cleanup.md @@ -8,6 +8,6 @@ resource cleanup. f = File.open('file') # good - f = File.open('file') do + File.open('file') do |f| ... end \ No newline at end of file diff --git a/config/contents/style/braces_around_hash_parameters.md b/config/contents/style/braces_around_hash_parameters.md new file mode 100644 index 00000000..4d00cbe1 --- /dev/null +++ b/config/contents/style/braces_around_hash_parameters.md @@ -0,0 +1,36 @@ +This cop checks for braces around the last parameter in a method call +if the last parameter is a hash. +It supports 3 styles: + +* The `braces` style enforces braces around all method +parameters that are hashes. + +### Example: + # bad + some_method(x, y, a: 1, b: 2) + + # good + some_method(x, y, {a: 1, b: 2}) + +* The `no_braces` style checks that the last parameter doesn't +have braces around it. + +### Example: + # bad + some_method(x, y, {a: 1, b: 2}) + + # good + some_method(x, y, a: 1, b: 2) + +* The `context_dependent` style checks that the last parameter +doesn't have braces around it, but requires braces if the +second to last parameter is also a hash literal. + +### Example: + # bad + some_method(x, y, {a: 1, b: 2}) + some_method(x, y, {a: 1, b: 2}, a: 1, b: 2) + + # good + some_method(x, y, a: 1, b: 2) + some_method(x, y, {a: 1, b: 2}, {a: 1, b: 2}) \ No newline at end of file diff --git a/config/contents/style/copyright.md b/config/contents/style/copyright.md index aab17fcd..39d59b74 100644 --- a/config/contents/style/copyright.md +++ b/config/contents/style/copyright.md @@ -3,8 +3,8 @@ Check that a copyright notice was given in each source file. The default regexp for an acceptable copyright notice can be found in config/default.yml. The default can be changed as follows: -Style/Copyright: - Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc' + Style/Copyright: + Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc' This regex string is treated as an unanchored regex. For each file that RuboCop scans, a comment that matches this regex must be found or diff --git a/config/contents/style/dir.md b/config/contents/style/dir.md new file mode 100644 index 00000000..e6e6710d --- /dev/null +++ b/config/contents/style/dir.md @@ -0,0 +1,13 @@ +This cop checks for places where the `#__dir__` method can replace more +complex constructs to retrieve a canonicalized absolute path to the +current file. + +### Example: + # bad + path = File.expand_path(File.dirname(__FILE__)) + + # bad + path = File.dirname(File.realpath(__FILE__)) + + # good + path = __dir__ \ No newline at end of file diff --git a/config/contents/style/documentation_method.md b/config/contents/style/documentation_method.md index fc645d57..e76d4fac 100644 --- a/config/contents/style/documentation_method.md +++ b/config/contents/style/documentation_method.md @@ -38,7 +38,7 @@ non-public methods. end end - # Documenation + # Documentation def foo.bar puts baz end \ No newline at end of file diff --git a/config/contents/style/empty_method.md b/config/contents/style/empty_method.md index 1c85d81c..42b77f0c 100644 --- a/config/contents/style/empty_method.md +++ b/config/contents/style/empty_method.md @@ -1,30 +1,43 @@ This cop checks for the formatting of empty method definitions. By default it enforces empty method definitions to go on a single -line (compact style), but it cah be configured to enforce the `end` -to go on its own line (expanded style.) +line (compact style), but it can be configured to enforce the `end` +to go on its own line (expanded style). Note: A method definition is not considered empty if it contains comments. ### Example: - EnforcedStyle: compact (default) + # EnforcedStyle: compact (default) # bad def foo(bar) end + def self.foo(bar) + end + # good def foo(bar); end + def foo(bar) # baz end - EnforcedStyle: expanded + def self.foo(bar); end + +### Example: + + # EnforcedStyle: expanded # bad def foo(bar); end + def self.foo(bar); end + # good def foo(bar) + end + + def self.foo(bar) end \ No newline at end of file diff --git a/config/contents/style/format_string_token.md b/config/contents/style/format_string_token.md new file mode 100644 index 00000000..9102e9d9 --- /dev/null +++ b/config/contents/style/format_string_token.md @@ -0,0 +1,27 @@ +Use a consistent style for named format string tokens. + +### Example: + + EnforcedStyle: annotated + + # bad + + format('%{greeting}', greeting: 'Hello') + format('%s', 'Hello') + + # good + + format('%s', greeting: 'Hello') + +### Example: + + EnforcedStyle: template + + # bad + + format('%s', greeting: 'Hello') + format('%s', 'Hello') + + # good + + format('%{greeting}', greeting: 'Hello') \ No newline at end of file diff --git a/config/contents/style/hash_syntax.md b/config/contents/style/hash_syntax.md index c9759284..64e53d49 100644 --- a/config/contents/style/hash_syntax.md +++ b/config/contents/style/hash_syntax.md @@ -7,7 +7,7 @@ A separate offense is registered for each problematic pair. The supported styles are: -* ruby19 - forces use of the 1.9 syntax (e.g. {a: 1}) when hashes have +* ruby19 - forces use of the 1.9 syntax (e.g. `{a: 1}`) when hashes have all symbols for keys * hash_rockets - forces use of hash rockets for all hashes * no_mixed_keys - simply checks for hashes with mixed syntaxes diff --git a/config/contents/style/identical_conditional_branches.md b/config/contents/style/identical_conditional_branches.md index 5fe141c2..fd9e7907 100644 --- a/config/contents/style/identical_conditional_branches.md +++ b/config/contents/style/identical_conditional_branches.md @@ -1,5 +1,5 @@ -This cop checks for identical lines at the end of each branch of a -conditional statement. +This cop checks for identical lines at the beginning or end of +each branch of a conditional statement. ### Example: # bad @@ -17,4 +17,43 @@ conditional statement. else do_y end - do_z \ No newline at end of file + do_z + + # bad + if condition + do_z + do_x + else + do_z + do_y + end + + # good + do_z + if condition + do_x + else + do_y + end + + # bad + case foo + when 1 + do_x + when 2 + do_x + else + do_x + end + + # good + case foo + when 1 + do_x + do_y + when 2 + # nothing + else + do_x + do_z + end \ No newline at end of file diff --git a/config/contents/style/if_unless_modifier_of_if_unless.md b/config/contents/style/if_unless_modifier_of_if_unless.md index 4de471b4..eb1405e3 100644 --- a/config/contents/style/if_unless_modifier_of_if_unless.md +++ b/config/contents/style/if_unless_modifier_of_if_unless.md @@ -1,4 +1,4 @@ -Checks for if and unless statements used as modifers of other if or +Checks for if and unless statements used as modifiers of other if or unless statements. ### Example: diff --git a/config/contents/style/inverse_methods.md b/config/contents/style/inverse_methods.md new file mode 100644 index 00000000..db8fa0bc --- /dev/null +++ b/config/contents/style/inverse_methods.md @@ -0,0 +1,24 @@ +This cop check for usages of not (`not` or `!`) called on a method +when an inverse of that method can be used instead. +Methods that can be inverted by a not (`not` or `!`) should be defined +in `InverseMethods` +Methods that are inverted by inverting the return +of the block that is passed to the method should be defined in +`InverseBlocks` + +### Example: + # bad + !foo.none? + !foo.any? { |f| f.even? } + !foo.blank? + !(foo == bar) + foo.select { |f| !f.even? } + foo.reject { |f| f != 7 } + + # good + foo.none? + foo.blank? + foo.any? { |f| f.even? } + foo != bar + foo == bar + !!('foo' =~ /^\w+$/) \ No newline at end of file diff --git a/config/contents/style/method_call_with_args_parentheses.md b/config/contents/style/method_call_with_args_parentheses.md new file mode 100644 index 00000000..c156ac6f --- /dev/null +++ b/config/contents/style/method_call_with_args_parentheses.md @@ -0,0 +1,36 @@ +This cop checks presence of parentheses in method calls containing +parameters. By default, macro methods are ignored. Additional methods +can be added to the `IgnoredMethods` list. + +### Example: + + # bad + array.delete e + + # good + array.delete(e) + + # good + # Operators don't need parens + foo == bar + + # good + # Setter methods don't need parens + foo.bar = baz + + # okay with `puts` listed in `IgnoredMethods` + puts 'test' + + # IgnoreMacros: true (default) + + # good + class Foo + bar :baz + end + + # IgnoreMacros: false + + # bad + class Foo + bar :baz + end \ No newline at end of file diff --git a/config/contents/style/method_call_without_args_parentheses.md b/config/contents/style/method_call_without_args_parentheses.md new file mode 100644 index 00000000..e7babdb5 --- /dev/null +++ b/config/contents/style/method_call_without_args_parentheses.md @@ -0,0 +1,8 @@ +This cop checks for unwanted parentheses in parameterless method calls. + +### Example: + # bad + object.some_method() + + # good + object.some_method \ No newline at end of file diff --git a/config/contents/style/min_max.md b/config/contents/style/min_max.md new file mode 100644 index 00000000..eee27443 --- /dev/null +++ b/config/contents/style/min_max.md @@ -0,0 +1,11 @@ +This cop checks for potential uses of `Enumerable#minmax`. + +### Example: + + # bad + bar = [foo.min, foo.max] + return foo.min, foo.max + + # good + bar = foo.minmax + return foo.minmax \ No newline at end of file diff --git a/config/contents/style/mixin_grouping.md b/config/contents/style/mixin_grouping.md new file mode 100644 index 00000000..ee1e6dcf --- /dev/null +++ b/config/contents/style/mixin_grouping.md @@ -0,0 +1,31 @@ +This cop checks for grouping of mixins in `class` and `module` bodies. +By default it enforces mixins to be placed in separate declarations, +but it can be configured to enforce grouping them in one declaration. + +### Example: + + EnforcedStyle: separated (default) + + # bad + class Foo + include Bar, Qox + end + + # good + class Foo + include Qox + include Bar + end + + EnforcedStyle: grouped + + # bad + class Foo + extend Bar + extend Qox + end + + # good + class Foo + extend Qox, Bar + end \ No newline at end of file diff --git a/config/contents/style/multiline_memoization.md b/config/contents/style/multiline_memoization.md index 981c083a..198bdade 100644 --- a/config/contents/style/multiline_memoization.md +++ b/config/contents/style/multiline_memoization.md @@ -1,8 +1,9 @@ -This cop checks that multiline memoizations are wrapped in a `begin` -and `end` block. +This cop checks expressions wrapping styles for multiline memoization. ### Example: + # EnforcedStyle: keyword (default) + # bad foo ||= ( bar @@ -13,4 +14,20 @@ and `end` block. foo ||= begin bar baz - end \ No newline at end of file + end + +### Example: + + # EnforcedStyle: braces + + # bad + foo ||= begin + bar + baz + end + + # good + foo ||= ( + bar + baz + ) \ No newline at end of file diff --git a/config/contents/style/multiple_comparison.md b/config/contents/style/multiple_comparison.md new file mode 100644 index 00000000..d8ee73d5 --- /dev/null +++ b/config/contents/style/multiple_comparison.md @@ -0,0 +1,11 @@ +This cop checks against comparing a variable with multiple items, where +`Array#include?` could be used instead to avoid code repetition. + +### Example: + # bad + a = 'a' + foo if a == 'a' || a == 'b' || a == 'c' + + # good + a = 'a' + foo if ['a', 'b', 'c'].include?(a) \ No newline at end of file diff --git a/config/contents/style/negated_if.md b/config/contents/style/negated_if.md new file mode 100644 index 00000000..d6290393 --- /dev/null +++ b/config/contents/style/negated_if.md @@ -0,0 +1,71 @@ +Checks for uses of if with a negated condition. Only ifs +without else are considered. There are three different styles: + + - both + - prefix + - postfix + +### Example: + + # EnforcedStyle: both + # enforces `unless` for `prefix` and `postfix` conditionals + + # good + + unless foo + bar + end + + # bad + + if !foo + bar + end + + # good + + bar unless foo + + # bad + + bar if !foo + +### Example: + + # EnforcedStyle: prefix + # enforces `unless` for just `prefix` conditionals + + # good + + unless foo + bar + end + + # bad + + if !foo + bar + end + + # good + + bar if !foo + +### Example: + + # EnforcedStyle: postfix + # enforces `unless` for just `postfix` conditionals + + # good + + bar unless foo + + # bad + + bar if !foo + + # good + + if !foo + bar + end \ No newline at end of file diff --git a/config/contents/style/next.md b/config/contents/style/next.md index 860287c1..c6fc9a5a 100644 --- a/config/contents/style/next.md +++ b/config/contents/style/next.md @@ -3,7 +3,7 @@ Use `next` to skip iteration instead of a condition at the end. ### Example: # bad [1, 2].each do |a| - if a == 1 do + if a == 1 puts a end end diff --git a/config/contents/style/numeric_literals.md b/config/contents/style/numeric_literals.md new file mode 100644 index 00000000..09edbaa9 --- /dev/null +++ b/config/contents/style/numeric_literals.md @@ -0,0 +1,19 @@ +This cop checks for big numeric literals without _ between groups +of digits in them. + +### Example: + + # bad + + 1000000 + 1_00_000 + 1_0000 + + # good + + 1_000_000 + 1000 + + # good unless Strict is set + + 10_000_00 # typical representation of $10,000 in cents diff --git a/config/contents/style/numeric_predicate.md b/config/contents/style/numeric_predicate.md index 680e9849..ee7d7c5b 100644 --- a/config/contents/style/numeric_predicate.md +++ b/config/contents/style/numeric_predicate.md @@ -3,10 +3,14 @@ This cop checks for usage of comparison operators (`==`, These can be replaced by their respective predicate methods. The cop can also be configured to do the reverse. -The cop disregards `nonzero?` as it its value is truthy or falsey, +The cop disregards `#nonzero?` as it its value is truthy or falsey, but not `true` and `false`, and thus not always interchangeable with `!= 0`. +The cop ignores comparisons to global variables, since they are often +populated with objects which can be compared with integers, but are +not themselves `Interger` polymorphic. + ### Example: # EnforcedStyle: predicate (default) diff --git a/config/contents/style/or_assignment.md b/config/contents/style/or_assignment.md new file mode 100644 index 00000000..9b927191 --- /dev/null +++ b/config/contents/style/or_assignment.md @@ -0,0 +1,23 @@ +This cop checks for potential usage of the `||=` operator. + +### Example: + # bad + name = name ? name : 'Bozhidar' + + # bad + name = if name + name + else + 'Bozhidar' + end + + # bad + unless name + name = 'Bozhidar' + end + + # bad + name = 'Bozhidar' unless name + + # good - set name to 'Bozhidar', only if it's nil or false + name ||= 'Bozhidar' \ No newline at end of file diff --git a/config/contents/style/percent_literal_delimiters.md b/config/contents/style/percent_literal_delimiters.md new file mode 100644 index 00000000..a8cd10f1 --- /dev/null +++ b/config/contents/style/percent_literal_delimiters.md @@ -0,0 +1,20 @@ +This cop enforces the consistent usage of `%`-literal delimiters. + +Specify the 'default' key to set all preferred delimiters at once. You +can continue to specify individual preferred delimiters to override the +default. + +### Example: + # Style/PercentLiteralDelimiters: + # PreferredDelimiters: + # default: '[]' + # '%i': '()' + + # good + %w[alpha beta] + %i(gamma delta) + + # bad + %W(alpha #{beta}) + + # bad + %I(alpha beta) \ No newline at end of file diff --git a/config/contents/style/raise_args.md b/config/contents/style/raise_args.md index e66e2bc8..632ed0ee 100644 --- a/config/contents/style/raise_args.md +++ b/config/contents/style/raise_args.md @@ -18,7 +18,8 @@ passed multiple arguments. # good raise StandardError, "message" fail "message" - raise RuntimeError.new(arg1, arg2, arg3) + raise MyCustomError.new(arg1, arg2, arg3) + raise MyKwArgError.new(key1: val1, key2: val2) ### Example: @@ -30,5 +31,5 @@ passed multiple arguments. # good raise StandardError.new("message") - raise RuntimeError.new(arg1, arg2, arg3) + raise MyCustomError.new(arg1, arg2, arg3) fail "message" \ No newline at end of file diff --git a/config/contents/style/redundant_conditional.md b/config/contents/style/redundant_conditional.md new file mode 100644 index 00000000..450a75cf --- /dev/null +++ b/config/contents/style/redundant_conditional.md @@ -0,0 +1,21 @@ +This cop checks for redundant returning of true/false in conditionals. + +### Example: + # bad + x == y ? true : false + + # bad + if x == y + true + else + false + end + + # good + x == y + + # bad + x == y ? false : true + + # good + x != y \ No newline at end of file diff --git a/config/contents/style/redundant_self.md b/config/contents/style/redundant_self.md index 1af709cb..13a65ec5 100644 --- a/config/contents/style/redundant_self.md +++ b/config/contents/style/redundant_self.md @@ -25,6 +25,10 @@ This cop checks for redundant uses of `self`. self.bar # resolves name clash with local variable end + %w[x y z].select do |bar| + self.bar == bar # resolves name clash with argument of a block + end + * Calling an attribute writer to prevent an local variable assignment attr_writer :bar diff --git a/config/contents/style/return_nil.md b/config/contents/style/return_nil.md new file mode 100644 index 00000000..fa04fe9a --- /dev/null +++ b/config/contents/style/return_nil.md @@ -0,0 +1,29 @@ +This cop enforces consistency between 'return nil' and 'return'. + +Supported styles are: return, return_nil. + +### Example: + + # EnforcedStyle: return (default) + + # bad + def foo(arg) + return nil if arg + end + + # good + def foo(arg) + return if arg + end + + # EnforcedStyle: return_nil + + # bad + def foo(arg) + return if arg + end + + # good + def foo(arg) + return nil if arg + end \ No newline at end of file diff --git a/config/contents/style/string_literals_in_interpolation.md b/config/contents/style/string_literals_in_interpolation.md new file mode 100644 index 00000000..9a53e2db --- /dev/null +++ b/config/contents/style/string_literals_in_interpolation.md @@ -0,0 +1,22 @@ +This cop checks that quotes inside the string interpolation +match the configured preference. + +### Example: + + # EnforcedStyle: single_quotes + + # bad + result = "Tests #{success ? "PASS" : "FAIL"}" + + # good + result = "Tests #{success ? 'PASS' : 'FAIL'}" + +### Example: + + # EnforcedStyle: double_quotes + + # bad + result = "Tests #{success ? 'PASS' : 'FAIL'}" + + # good + result = "Tests #{success ? "PASS" : "FAIL"}" \ No newline at end of file diff --git a/config/contents/style/symbol_array.md b/config/contents/style/symbol_array.md index 57bdfe80..9d596916 100644 --- a/config/contents/style/symbol_array.md +++ b/config/contents/style/symbol_array.md @@ -3,4 +3,27 @@ using the %i() syntax. Alternatively, it checks for symbol arrays using the %i() syntax on projects which do not want to use that syntax, perhaps because they -support a version of Ruby lower than 2.0. \ No newline at end of file +support a version of Ruby lower than 2.0. + +Configuration option: MinSize +If set, arrays with fewer elements than this value will not trigger the +cop. For example, a `MinSize of `3` will not enforce a style on an array +of 2 or fewer elements. + +### Example: + EnforcedStyle: percent (default) + + # good + %i[foo bar baz] + + # bad + [:foo, :bar, :baz] + +### Example: + EnforcedStyle: brackets + + # good + [:foo, :bar, :baz] + + # bad + %i[foo bar baz] \ No newline at end of file diff --git a/config/contents/style/ternary_parentheses.md b/config/contents/style/ternary_parentheses.md index ceea225d..069ca30e 100644 --- a/config/contents/style/ternary_parentheses.md +++ b/config/contents/style/ternary_parentheses.md @@ -1,6 +1,7 @@ This cop checks for the presence of parentheses around ternary conditions. It is configurable to enforce inclusion or omission of -parentheses using `EnforcedStyle`. +parentheses using `EnforcedStyle`. Omission is only enforced when +removing the parentheses won't cause a different behavior. ### Example: @@ -8,7 +9,7 @@ parentheses using `EnforcedStyle`. # bad foo = (bar?) ? a : b - foo = (bar.baz) ? a : b + foo = (bar.baz?) ? a : b foo = (bar && baz) ? a : b # good @@ -27,7 +28,7 @@ parentheses using `EnforcedStyle`. # good foo = (bar?) ? a : b - foo = (bar.baz) ? a : b + foo = (bar.baz?) ? a : b foo = (bar && baz) ? a : b ### Example: @@ -41,5 +42,5 @@ parentheses using `EnforcedStyle`. # good foo = bar? ? a : b - foo = bar.baz ? a : b + foo = bar.baz? ? a : b foo = (bar && baz) ? a : b \ No newline at end of file diff --git a/config/contents/style/trailing_underscore_variable.md b/config/contents/style/trailing_underscore_variable.md index a8e4f831..eefcd19d 100644 --- a/config/contents/style/trailing_underscore_variable.md +++ b/config/contents/style/trailing_underscore_variable.md @@ -7,8 +7,11 @@ This cop checks for extra underscores in variable assignment. a, _, _ = foo() a, _, _, = foo() - #good + # good a, b, = foo() a, = foo() *a, b, _ = foo() => We need to know to not include 2 variables in a - a, *b, _ = foo() => The correction `a, *b, = foo()` is a syntax error \ No newline at end of file + a, *b, _ = foo() => The correction `a, *b, = foo()` is a syntax error + + # good if AllowNamedUnderscoreVariables is true + a, b, _something = foo() \ No newline at end of file diff --git a/config/contents/style/word_array.md b/config/contents/style/word_array.md index b6211840..50695689 100644 --- a/config/contents/style/word_array.md +++ b/config/contents/style/word_array.md @@ -2,4 +2,27 @@ This cop can check for array literals made up of word-like strings, that are not using the %w() syntax. Alternatively, it can check for uses of the %w() syntax, in projects -which do not want to include that syntax. \ No newline at end of file +which do not want to include that syntax. + +Configuration option: MinSize +If set, arrays with fewer elements than this value will not trigger the +cop. For example, a `MinSize of `3` will not enforce a style on an array +of 2 or fewer elements. + +### Example: + EnforcedStyle: percent (default) + + # good + %w[foo bar baz] + + # bad + ['foo', 'bar', 'baz'] + +### Example: + EnforcedStyle: brackets + + # good + ['foo', 'bar', 'baz'] + + # bad + %w[foo bar baz] \ No newline at end of file diff --git a/config/contents/style/yoda_condition.md b/config/contents/style/yoda_condition.md new file mode 100644 index 00000000..900d0fd8 --- /dev/null +++ b/config/contents/style/yoda_condition.md @@ -0,0 +1,31 @@ +This cop checks for Yoda conditions, i.e. comparison operations where +readability is reduced because the operands are not ordered the same +way as they would be ordered in spoken English. + +### Example: + + # EnforcedStyle: all_comparison_operators + + # bad + 99 == foo + "bar" != foo + 42 >= foo + 10 < bar + + # good + foo == 99 + foo == "bar" + foo <= 42 + bar > 10 + +### Example: + + # EnforcedStyle: equality_operators_only + + # bad + 99 == foo + "bar" != foo + + # good + 99 >= foo + 3 < a && a < 5 \ No newline at end of file diff --git a/config/contents/style/zero_length_predicate.md b/config/contents/style/zero_length_predicate.md index c939c5bc..0d0503f6 100644 --- a/config/contents/style/zero_length_predicate.md +++ b/config/contents/style/zero_length_predicate.md @@ -1,16 +1,23 @@ -This cop checks for receiver.length == 0 predicates and the -negated versions receiver.length > 0 and receiver.length != 0. -These can be replaced with receiver.empty? and -!receiver.empty? respectively. +This cop checks for numeric comparisons that can be replaced +by a predicate method, such as receiver.length == 0, +receiver.length > 0, receiver.length != 0, +receiver.length < 1 and receiver.size == 0 that can be +replaced by receiver.empty? and !receiver.empty. ### Example: # bad [1, 2, 3].length == 0 0 == "foobar".length + array.length < 1 + {a: 1, b: 2}.length != 0 + string.length > 0 hash.size > 0 # good [1, 2, 3].empty? "foobar".empty? + array.empty? + !{a: 1, b: 2}.empty? + !string.empty? !hash.empty? \ No newline at end of file diff --git a/spec/support/currently_undocumented_cops.txt b/spec/support/currently_undocumented_cops.txt index 45c7250e..ef9c4011 100644 --- a/spec/support/currently_undocumented_cops.txt +++ b/spec/support/currently_undocumented_cops.txt @@ -1,63 +1,115 @@ -RuboCop::Cop::Lint::AssignmentInCondition -RuboCop::Cop::Lint::Debugger -RuboCop::Cop::Lint::DeprecatedClassMethods -RuboCop::Cop::Lint::EmptyEnsure -RuboCop::Cop::Lint::EndInMethod -RuboCop::Cop::Lint::EnsureReturn -RuboCop::Cop::Lint::Eval -RuboCop::Cop::Lint::HandleExceptions -RuboCop::Cop::Lint::Loop -RuboCop::Cop::Lint::RescueException -RuboCop::Cop::Lint::UnderscorePrefixedVariableName -RuboCop::Cop::Lint::Void +RuboCop::Cop::Layout::AccessModifierIndentation +RuboCop::Cop::Layout::AlignArray +RuboCop::Cop::Layout::AlignHash +RuboCop::Cop::Layout::AlignParameters +RuboCop::Cop::Layout::BlockEndNewline +RuboCop::Cop::Layout::CaseIndentation +RuboCop::Cop::Layout::ClosingParenthesisIndentation +RuboCop::Cop::Layout::CommentIndentation +RuboCop::Cop::Layout::DotPosition +RuboCop::Cop::Layout::ElseAlignment +RuboCop::Cop::Layout::EmptyLineAfterMagicComment +RuboCop::Cop::Layout::EmptyLineBetweenDefs +RuboCop::Cop::Layout::EmptyLines +RuboCop::Cop::Layout::EmptyLinesAroundAccessModifier +RuboCop::Cop::Layout::EmptyLinesAroundBeginBody +RuboCop::Cop::Layout::EmptyLinesAroundBlockBody +RuboCop::Cop::Layout::EmptyLinesAroundClassBody +RuboCop::Cop::Layout::EmptyLinesAroundExceptionHandlingKeywords +RuboCop::Cop::Layout::EmptyLinesAroundMethodBody +RuboCop::Cop::Layout::EmptyLinesAroundModuleBody +RuboCop::Cop::Layout::EndOfLine +RuboCop::Cop::Layout::ExtraSpacing +RuboCop::Cop::Layout::FirstArrayElementLineBreak +RuboCop::Cop::Layout::FirstHashElementLineBreak +RuboCop::Cop::Layout::FirstMethodArgumentLineBreak +RuboCop::Cop::Layout::FirstMethodParameterLineBreak +RuboCop::Cop::Layout::FirstParameterIndentation +RuboCop::Cop::Layout::IndentArray +RuboCop::Cop::Layout::IndentAssignment +RuboCop::Cop::Layout::IndentHash +RuboCop::Cop::Layout::IndentHeredoc +RuboCop::Cop::Layout::IndentationConsistency +RuboCop::Cop::Layout::IndentationWidth +RuboCop::Cop::Layout::InitialIndentation +RuboCop::Cop::Layout::LeadingCommentSpace +RuboCop::Cop::Layout::MultilineArrayBraceLayout +RuboCop::Cop::Layout::MultilineAssignmentLayout +RuboCop::Cop::Layout::MultilineBlockLayout +RuboCop::Cop::Layout::MultilineHashBraceLayout +RuboCop::Cop::Layout::MultilineMethodCallBraceLayout +RuboCop::Cop::Layout::MultilineMethodCallIndentation +RuboCop::Cop::Layout::MultilineMethodDefinitionBraceLayout +RuboCop::Cop::Layout::MultilineOperationIndentation +RuboCop::Cop::Layout::RescueEnsureAlignment +RuboCop::Cop::Layout::SpaceAfterColon +RuboCop::Cop::Layout::SpaceAfterComma +RuboCop::Cop::Layout::SpaceAfterMethodName +RuboCop::Cop::Layout::SpaceAfterNot +RuboCop::Cop::Layout::SpaceAfterSemicolon +RuboCop::Cop::Layout::SpaceAroundBlockParameters +RuboCop::Cop::Layout::SpaceAroundEqualsInParameterDefault +RuboCop::Cop::Layout::SpaceAroundKeyword +RuboCop::Cop::Layout::SpaceAroundOperators +RuboCop::Cop::Layout::SpaceBeforeBlockBraces +RuboCop::Cop::Layout::SpaceBeforeComma +RuboCop::Cop::Layout::SpaceBeforeComment +RuboCop::Cop::Layout::SpaceBeforeFirstArg +RuboCop::Cop::Layout::SpaceBeforeSemicolon +RuboCop::Cop::Layout::SpaceInLambdaLiteral +RuboCop::Cop::Layout::SpaceInsideArrayPercentLiteral +RuboCop::Cop::Layout::SpaceInsideBlockBraces +RuboCop::Cop::Layout::SpaceInsideBrackets +RuboCop::Cop::Layout::SpaceInsideHashLiteralBraces +RuboCop::Cop::Layout::SpaceInsideParens +RuboCop::Cop::Layout::SpaceInsidePercentLiteralDelimiters +RuboCop::Cop::Layout::SpaceInsideRangeLiteral +RuboCop::Cop::Layout::SpaceInsideStringInterpolation +RuboCop::Cop::Layout::Tab +RuboCop::Cop::Layout::TrailingBlankLines +RuboCop::Cop::Layout::TrailingWhitespace +RuboCop::Cop::Lint::ScriptPermission +RuboCop::Cop::Lint::Syntax RuboCop::Cop::Metrics::LineLength +RuboCop::Cop::Naming::AccessorMethodName +RuboCop::Cop::Naming::AsciiIdentifiers +RuboCop::Cop::Naming::BinaryOperatorParameterName +RuboCop::Cop::Naming::ClassAndModuleCamelCase +RuboCop::Cop::Naming::ConstantName +RuboCop::Cop::Naming::FileName +RuboCop::Cop::Naming::HeredocDelimiterCase +RuboCop::Cop::Naming::HeredocDelimiterNaming +RuboCop::Cop::Naming::MethodName +RuboCop::Cop::Naming::PredicateName +RuboCop::Cop::Naming::VariableName +RuboCop::Cop::Naming::VariableNumber RuboCop::Cop::Performance::FixedSize RuboCop::Cop::Rails::HasAndBelongsToMany RuboCop::Cop::Rails::Output -RuboCop::Cop::Rails::RequestReferer RuboCop::Cop::Rails::Validation -RuboCop::Cop::Style::AccessModifierIndentation -RuboCop::Cop::Style::AlignArray -RuboCop::Cop::Style::AlignHash -RuboCop::Cop::Style::AlignParameters -RuboCop::Cop::Style::AndOr RuboCop::Cop::Style::AsciiComments -RuboCop::Cop::Style::AsciiIdentifiers RuboCop::Cop::Style::Attr RuboCop::Cop::Style::BarePercentLiterals RuboCop::Cop::Style::BeginBlock RuboCop::Cop::Style::BlockComments RuboCop::Cop::Style::BlockDelimiters -RuboCop::Cop::Style::BracesAroundHashParameters RuboCop::Cop::Style::CaseEquality RuboCop::Cop::Style::CharacterLiteral -RuboCop::Cop::Style::ClassAndModuleCamelCase RuboCop::Cop::Style::ClassCheck RuboCop::Cop::Style::ColonMethodCall RuboCop::Cop::Style::CommentAnnotation -RuboCop::Cop::Style::CommentIndentation RuboCop::Cop::Style::ConditionalAssignment -RuboCop::Cop::Style::DotPosition -RuboCop::Cop::Style::EmptyLineBetweenDefs -RuboCop::Cop::Style::EmptyLines -RuboCop::Cop::Style::EmptyLinesAroundAccessModifier RuboCop::Cop::Style::EmptyLiteral RuboCop::Cop::Style::EndBlock -RuboCop::Cop::Style::EndOfLine RuboCop::Cop::Style::FlipFlop RuboCop::Cop::Style::IfWithSemicolon -RuboCop::Cop::Style::InitialIndentation -RuboCop::Cop::Style::MethodCallParentheses RuboCop::Cop::Style::MethodDefParentheses RuboCop::Cop::Style::MultilineTernaryOperator -RuboCop::Cop::Style::NegatedIf RuboCop::Cop::Style::NegatedWhile RuboCop::Cop::Style::NestedTernaryOperator RuboCop::Cop::Style::Not -RuboCop::Cop::Style::NumericLiterals RuboCop::Cop::Style::OneLineConditional RuboCop::Cop::Style::ParenthesesAroundCondition -RuboCop::Cop::Style::PercentLiteralDelimiters RuboCop::Cop::Style::PercentQLiterals RuboCop::Cop::Style::PerlBackrefs RuboCop::Cop::Style::Proc @@ -66,29 +118,13 @@ RuboCop::Cop::Style::Semicolon RuboCop::Cop::Style::Send RuboCop::Cop::Style::SignalException RuboCop::Cop::Style::SingleLineMethods -RuboCop::Cop::Style::SpaceAfterComma -RuboCop::Cop::Style::SpaceAfterSemicolon -RuboCop::Cop::Style::SpaceAroundEqualsInParameterDefault -RuboCop::Cop::Style::SpaceAroundOperators -RuboCop::Cop::Style::SpaceBeforeBlockBraces -RuboCop::Cop::Style::SpaceBeforeComma -RuboCop::Cop::Style::SpaceBeforeComment -RuboCop::Cop::Style::SpaceBeforeSemicolon -RuboCop::Cop::Style::SpaceInsideBrackets -RuboCop::Cop::Style::SpaceInsideHashLiteralBraces -RuboCop::Cop::Style::SpaceInsideParens RuboCop::Cop::Style::SpecialGlobalVars RuboCop::Cop::Style::StringLiterals -RuboCop::Cop::Style::StringLiteralsInInterpolation RuboCop::Cop::Style::StringMethods -RuboCop::Cop::Style::Tab -RuboCop::Cop::Style::TrailingBlankLines -RuboCop::Cop::Style::TrailingWhitespace RuboCop::Cop::Style::TrivialAccessors RuboCop::Cop::Style::UnlessElse RuboCop::Cop::Style::UnneededCapitalW RuboCop::Cop::Style::UnneededPercentQ RuboCop::Cop::Style::VariableInterpolation -RuboCop::Cop::Style::VariableName RuboCop::Cop::Style::WhenThen RuboCop::Cop::Style::WhileUntilDo From e070994b258f3cece7535d1bde23d6158a24a444 Mon Sep 17 00:00:00 2001 From: Alexander Mankuta Date: Wed, 4 Oct 2017 16:50:25 +0300 Subject: [PATCH 4/4] Updated Dickerfile * Bumped Ruby to 2.4.2 * Shrank image 2.4x * Removed git that is only used for docs * Removed test gems --- Dockerfile | 18 +++++++++--------- Makefile | 4 ++-- Rakefile | 12 ++++++++---- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 24ab906e..296933b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,18 @@ -FROM ruby:2.3-alpine +FROM ruby:2.4-alpine WORKDIR /usr/src/app -COPY Gemfile /usr/src/app/ -COPY Gemfile.lock /usr/src/app/ -RUN gem install bundler && \ - bundle install -j 4 && \ - rm -fr /usr/share/ri +RUN adduser -u 9000 -D app -RUN apk --update add git +COPY Gemfile Gemfile.lock /usr/src/app/ + +RUN gem install bundler && \ + bundle install -j 4 --without=test && \ + chown -R app:app /usr/local/bundle && \ + rm -fr ~/.gem ~/.bundle ~/.wh..gem -RUN adduser -u 9000 -D app COPY . /usr/src/app -RUN chown -R app:app /usr/src/app +RUN chown -R app:app . USER app diff --git a/Makefile b/Makefile index 3071b349..c6dfc828 100644 --- a/Makefile +++ b/Makefile @@ -6,11 +6,11 @@ image: docker build --rm -t $(IMAGE_NAME) . test: image - docker run --rm $(IMAGE_NAME) sh -c "cd /usr/src/app && bundle exec rake" + docker run --rm $(IMAGE_NAME) sh -c "cd /usr/src/app && bundle install --with=test && bundle exec rake" docs: image docker run --rm \ --user root \ --workdir /usr/src/app \ --volume $(PWD):/usr/src/app \ - $(IMAGE_NAME) sh -c "bundle exec rake docs:scrape" + $(IMAGE_NAME) sh -c "apk --update add git && bundle exec rake docs:scrape" diff --git a/Rakefile b/Rakefile index 88e1fa2b..d7dc9f91 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,11 @@ # frozen_string_literal: true -require "rspec/core/rake_task" - Rake.add_rakelib "lib/tasks" -RSpec::Core::RakeTask.new(:spec) -task default: :spec + +begin + require "rspec/core/rake_task" + + RSpec::Core::RakeTask.new(:spec) + task default: :spec +rescue LoadError +end