rubocop 0.47.1 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +28 -16
- data/config/default.yml +203 -115
- data/config/disabled.yml +0 -5
- data/config/enabled.yml +92 -8
- data/lib/rubocop.rb +24 -1
- data/lib/rubocop/ast/builder.rb +7 -2
- data/lib/rubocop/ast/node.rb +23 -20
- data/lib/rubocop/ast/node/and_node.rb +37 -0
- data/lib/rubocop/ast/node/array_node.rb +4 -1
- data/lib/rubocop/ast/node/case_node.rb +1 -0
- data/lib/rubocop/ast/node/ensure_node.rb +25 -0
- data/lib/rubocop/ast/node/hash_node.rb +10 -3
- data/lib/rubocop/ast/node/if_node.rb +2 -0
- data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +23 -0
- data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +35 -0
- data/lib/rubocop/ast/node/or_node.rb +37 -0
- data/lib/rubocop/ast/node/resbody_node.rb +25 -0
- data/lib/rubocop/ast/node/send_node.rb +190 -0
- data/lib/rubocop/ast/node/when_node.rb +1 -1
- data/lib/rubocop/ast/traversal.rb +15 -15
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +39 -15
- data/lib/rubocop/config_loader.rb +34 -13
- data/lib/rubocop/cop/bundler/ordered_gems.rb +23 -4
- data/lib/rubocop/cop/commissioner.rb +4 -0
- data/lib/rubocop/cop/cop.rb +5 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +53 -0
- data/lib/rubocop/cop/lint/debugger.rb +8 -1
- data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -4
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -1
- data/lib/rubocop/cop/lint/empty_ensure.rb +6 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +20 -18
- data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -3
- data/lib/rubocop/cop/lint/literal_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/multiple_compare.rb +5 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +26 -18
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -8
- data/lib/rubocop/cop/lint/require_parentheses.rb +7 -13
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -3
- data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -6
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -8
- data/lib/rubocop/cop/lint/unneeded_disable.rb +35 -11
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +5 -2
- data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -6
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
- data/lib/rubocop/cop/lint/useless_comparison.rb +5 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +4 -4
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -2
- data/lib/rubocop/cop/metrics/line_length.rb +2 -9
- data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -3
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -2
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
- data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +6 -6
- data/lib/rubocop/cop/mixin/duplication.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/ignored_pattern.rb +27 -0
- data/lib/rubocop/cop/mixin/method_preference.rb +2 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +17 -29
- data/lib/rubocop/cop/mixin/on_method_def.rb +3 -3
- data/lib/rubocop/cop/mixin/percent_literal.rb +27 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +21 -0
- data/lib/rubocop/cop/mixin/safe_mode.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -1
- data/lib/rubocop/cop/mixin/target_rails_version.rb +16 -0
- data/lib/rubocop/cop/mixin/unused_argument.rb +1 -1
- data/lib/rubocop/cop/offense.rb +3 -3
- data/lib/rubocop/cop/performance/casecmp.rb +1 -1
- data/lib/rubocop/cop/performance/detect.rb +2 -1
- data/lib/rubocop/cop/performance/double_start_end_with.rb +35 -1
- data/lib/rubocop/cop/performance/end_with.rb +3 -1
- data/lib/rubocop/cop/performance/flat_map.rb +6 -6
- data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
- data/lib/rubocop/cop/performance/range_include.rb +3 -1
- data/lib/rubocop/cop/performance/redundant_match.rb +6 -5
- data/lib/rubocop/cop/performance/regexp_match.rb +10 -3
- data/lib/rubocop/cop/performance/reverse_each.rb +2 -1
- data/lib/rubocop/cop/performance/size.rb +6 -11
- data/lib/rubocop/cop/performance/start_with.rb +3 -1
- data/lib/rubocop/cop/performance/string_replacement.rb +13 -18
- data/lib/rubocop/cop/performance/times_map.rb +4 -4
- data/lib/rubocop/cop/rails/action_filter.rb +42 -42
- data/lib/rubocop/cop/rails/active_support_aliases.rb +68 -0
- data/lib/rubocop/cop/rails/blank.rb +131 -0
- data/lib/rubocop/cop/rails/date.rb +25 -28
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +5 -7
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +7 -3
- data/lib/rubocop/cop/rails/exit.rb +9 -9
- data/lib/rubocop/cop/rails/file_path.rb +5 -14
- data/lib/rubocop/cop/rails/find_by.rb +8 -10
- data/lib/rubocop/cop/rails/find_each.rb +6 -9
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +15 -7
- data/lib/rubocop/cop/rails/output.rb +3 -5
- data/lib/rubocop/cop/rails/output_safety.rb +4 -8
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +25 -24
- data/lib/rubocop/cop/rails/present.rb +137 -0
- data/lib/rubocop/cop/rails/read_write_attribute.rb +9 -18
- data/lib/rubocop/cop/rails/relative_date_constant.rb +53 -0
- data/lib/rubocop/cop/rails/request_referer.rb +7 -4
- data/lib/rubocop/cop/rails/reversible_migration.rb +1 -2
- data/lib/rubocop/cop/rails/safe_navigation.rb +2 -1
- data/lib/rubocop/cop/rails/save_bang.rb +10 -10
- data/lib/rubocop/cop/rails/skips_model_validations.rb +23 -6
- data/lib/rubocop/cop/rails/time_zone.rb +20 -18
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -2
- data/lib/rubocop/cop/rails/validation.rb +8 -11
- data/lib/rubocop/cop/registry.rb +3 -3
- data/lib/rubocop/cop/security/json_load.rb +1 -1
- data/lib/rubocop/cop/security/marshal_load.rb +5 -1
- data/lib/rubocop/cop/security/yaml_load.rb +3 -3
- data/lib/rubocop/cop/severity.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +5 -5
- data/lib/rubocop/cop/style/align_hash.rb +1 -1
- data/lib/rubocop/cop/style/align_parameters.rb +5 -5
- data/lib/rubocop/cop/style/and_or.rb +16 -31
- data/lib/rubocop/cop/style/attr.rb +14 -8
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +8 -11
- data/lib/rubocop/cop/style/block_delimiters.rb +11 -13
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -23
- data/lib/rubocop/cop/style/case_indentation.rb +2 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_check.rb +5 -7
- data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +5 -4
- data/lib/rubocop/cop/style/collection_methods.rb +8 -8
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -9
- data/lib/rubocop/cop/style/conditional_assignment.rb +38 -45
- data/lib/rubocop/cop/style/constant_name.rb +1 -1
- data/lib/rubocop/cop/style/documentation_method.rb +1 -0
- data/lib/rubocop/cop/style/dot_position.rb +3 -7
- data/lib/rubocop/cop/style/double_negation.rb +2 -1
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_else.rb +2 -2
- data/lib/rubocop/cop/style/empty_line_after_magic_comment.rb +63 -0
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +74 -4
- data/lib/rubocop/cop/style/empty_lines_around_begin_body.rb +42 -0
- data/lib/rubocop/cop/style/empty_lines_around_exception_handling_keywords.rb +127 -0
- data/lib/rubocop/cop/style/empty_literal.rb +17 -9
- data/lib/rubocop/cop/style/end_of_line.rb +25 -3
- data/lib/rubocop/cop/style/file_name.rb +1 -1
- data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
- data/lib/rubocop/cop/style/first_parameter_indentation.rb +17 -19
- data/lib/rubocop/cop/style/for.rb +2 -4
- data/lib/rubocop/cop/style/format_string.rb +5 -4
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +27 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
- data/lib/rubocop/cop/style/indent_assignment.rb +2 -2
- data/lib/rubocop/cop/style/indent_hash.rb +2 -1
- data/lib/rubocop/cop/style/indent_heredoc.rb +173 -0
- data/lib/rubocop/cop/style/indentation_width.rb +61 -29
- data/lib/rubocop/cop/style/inverse_methods.rb +130 -0
- data/lib/rubocop/cop/style/lambda_call.rb +15 -11
- data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +26 -14
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -16
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
- data/lib/rubocop/cop/style/missing_else.rb +4 -3
- data/lib/rubocop/cop/style/mixin_grouping.rb +97 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +38 -5
- data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +2 -3
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +38 -19
- data/lib/rubocop/cop/style/mutable_constant.rb +5 -1
- data/lib/rubocop/cop/style/negated_if.rb +73 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +21 -19
- data/lib/rubocop/cop/style/next.rb +5 -5
- data/lib/rubocop/cop/style/non_nil_check.rb +7 -10
- data/lib/rubocop/cop/style/not.rb +3 -4
- data/lib/rubocop/cop/style/numeric_literals.rb +25 -3
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
- data/lib/rubocop/cop/style/op_method.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +6 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +52 -6
- data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -9
- data/lib/rubocop/cop/style/raise_args.rb +28 -24
- data/lib/rubocop/cop/style/redundant_freeze.rb +5 -7
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self.rb +17 -35
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -14
- data/lib/rubocop/cop/style/self_assignment.rb +3 -3
- data/lib/rubocop/cop/style/send.rb +4 -5
- data/lib/rubocop/cop/style/space_after_not.rb +7 -8
- data/lib/rubocop/cop/style/space_around_keyword.rb +8 -9
- data/lib/rubocop/cop/style/space_around_operators.rb +19 -15
- data/lib/rubocop/cop/style/space_before_first_arg.rb +17 -14
- data/lib/rubocop/cop/style/space_inside_brackets.rb +1 -1
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +3 -3
- data/lib/rubocop/cop/style/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +14 -14
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +10 -5
- data/lib/rubocop/cop/style/struct_inheritance.rb +4 -15
- data/lib/rubocop/cop/style/symbol_array.rb +31 -35
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
- data/lib/rubocop/cop/style/ternary_parentheses.rb +41 -13
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +6 -9
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -2
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +12 -34
- data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -4
- data/lib/rubocop/cop/team.rb +4 -1
- data/lib/rubocop/cop/util.rb +33 -26
- data/lib/rubocop/cop/variable_force.rb +13 -13
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -8
- data/lib/rubocop/cop/variable_force/branch.rb +318 -0
- data/lib/rubocop/cop/variable_force/branchable.rb +21 -0
- data/lib/rubocop/cop/variable_force/reference.rb +1 -3
- data/lib/rubocop/cop/variable_force/scope.rb +36 -20
- data/lib/rubocop/cop/variable_force/variable.rb +9 -8
- data/lib/rubocop/formatter/colorizable.rb +10 -10
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +2 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -2
- data/lib/rubocop/magic_comment.rb +20 -6
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/platform.rb +11 -0
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/remote_config.rb +18 -6
- data/lib/rubocop/result_cache.rb +8 -8
- data/lib/rubocop/rspec/cop_helper.rb +2 -0
- data/lib/rubocop/rspec/shared_contexts.rb +20 -0
- data/lib/rubocop/rspec/shared_examples.rb +1 -1
- data/lib/rubocop/runner.rb +2 -2
- data/lib/rubocop/target_finder.rb +64 -6
- data/lib/rubocop/version.rb +2 -4
- metadata +27 -4
- data/lib/rubocop/cop/variable_force/locatable.rb +0 -200
@@ -30,19 +30,23 @@ module RuboCop
|
|
30
30
|
METHOD_PATTERN = /^find_by_(.+?)(!)?$/
|
31
31
|
|
32
32
|
def on_send(node)
|
33
|
-
|
34
|
-
|
33
|
+
method_name = node.method_name.to_s
|
34
|
+
|
35
35
|
return if whitelist.include?(method_name)
|
36
|
+
|
36
37
|
static_name = static_method_name(method_name)
|
38
|
+
|
37
39
|
return unless static_name
|
38
40
|
|
39
|
-
add_offense(node, :expression,
|
41
|
+
add_offense(node, :expression,
|
42
|
+
format(MSG, static_name, node.method_name))
|
40
43
|
end
|
41
44
|
|
42
45
|
def autocorrect(node)
|
43
46
|
_receiver, method, *args = *node
|
44
47
|
static_name = static_method_name(method.to_s)
|
45
48
|
keywords = column_keywords(method)
|
49
|
+
|
46
50
|
return if keywords.size != args.size
|
47
51
|
|
48
52
|
lambda do |corrector|
|
@@ -20,8 +20,8 @@ module RuboCop
|
|
20
20
|
include ConfigurableEnforcedStyle
|
21
21
|
|
22
22
|
MSG = 'Do not use `exit` in Rails applications.'.freeze
|
23
|
-
TARGET_METHODS =
|
24
|
-
EXPLICIT_RECEIVERS =
|
23
|
+
TARGET_METHODS = %i(exit exit!).freeze
|
24
|
+
EXPLICIT_RECEIVERS = %i(Kernel Process).freeze
|
25
25
|
|
26
26
|
def on_send(node)
|
27
27
|
add_offense(node, :selector) if offending_node?(node)
|
@@ -30,11 +30,9 @@ module RuboCop
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def offending_node?(node)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
right_argument_count?(arg_nodes) &&
|
37
|
-
right_receiver?(receiver_node)
|
33
|
+
right_method_name?(node.method_name) &&
|
34
|
+
right_argument_count?(node.arguments) &&
|
35
|
+
right_receiver?(node.receiver)
|
38
36
|
end
|
39
37
|
|
40
38
|
def right_method_name?(method_name)
|
@@ -44,15 +42,17 @@ module RuboCop
|
|
44
42
|
# More than 1 argument likely means it is a different
|
45
43
|
# `exit` implementation than the one we are preventing.
|
46
44
|
def right_argument_count?(arg_nodes)
|
47
|
-
arg_nodes.
|
45
|
+
arg_nodes.size <= 1
|
48
46
|
end
|
49
47
|
|
50
48
|
# Only register if exit is being called explicitly on
|
51
49
|
# Kernel or Process or if receiver node is nil for plain
|
52
50
|
# `exit` calls.
|
53
51
|
def right_receiver?(receiver_node)
|
54
|
-
return true
|
52
|
+
return true unless receiver_node
|
53
|
+
|
55
54
|
_a, receiver_node_class, _c = *receiver_node
|
55
|
+
|
56
56
|
EXPLICIT_RECEIVERS.include?(receiver_node_class)
|
57
57
|
end
|
58
58
|
end
|
@@ -17,11 +17,7 @@ module RuboCop
|
|
17
17
|
class FilePath < Cop
|
18
18
|
MSG = 'Please use `Rails.root.join(\'path\', \'to\')` instead.'.freeze
|
19
19
|
|
20
|
-
|
21
|
-
(send (const nil :File) :join ...)
|
22
|
-
PATTERN
|
23
|
-
|
24
|
-
def_node_search :file_join_nodes?, <<-PATTERN
|
20
|
+
def_node_matcher :file_join_nodes?, <<-PATTERN
|
25
21
|
(send (const nil :File) :join ...)
|
26
22
|
PATTERN
|
27
23
|
|
@@ -29,7 +25,7 @@ module RuboCop
|
|
29
25
|
(send (const nil :Rails) :root)
|
30
26
|
PATTERN
|
31
27
|
|
32
|
-
|
28
|
+
def_node_matcher :rails_root_join_nodes?, <<-PATTERN
|
33
29
|
(send (send (const nil :Rails) :root) :join ...)
|
34
30
|
PATTERN
|
35
31
|
|
@@ -47,20 +43,15 @@ module RuboCop
|
|
47
43
|
|
48
44
|
def check_for_file_join_with_rails_root(node)
|
49
45
|
return unless file_join_nodes?(node)
|
50
|
-
return unless
|
51
|
-
.flatten
|
52
|
-
.any? { |e| rails_root_nodes?(e) }
|
46
|
+
return unless node.method_args.any? { |e| rails_root_nodes?(e) }
|
53
47
|
|
54
48
|
register_offense(node)
|
55
49
|
end
|
56
50
|
|
57
51
|
def check_for_rails_root_join_with_slash_separated_path(node)
|
58
52
|
return unless rails_root_nodes?(node)
|
59
|
-
return unless rails_root_join_nodes(node)
|
60
|
-
|
61
|
-
.any? do |arg|
|
62
|
-
arg.source =~ %r{/}
|
63
|
-
end
|
53
|
+
return unless rails_root_join_nodes?(node)
|
54
|
+
return unless node.method_args.any? { |arg| arg.source =~ %r{/} }
|
64
55
|
|
65
56
|
register_offense(node)
|
66
57
|
end
|
@@ -15,30 +15,28 @@ module RuboCop
|
|
15
15
|
# User.find_by(name: 'Bruce')
|
16
16
|
class FindBy < Cop
|
17
17
|
MSG = 'Use `find_by` instead of `where.%s`.'.freeze
|
18
|
-
TARGET_SELECTORS =
|
18
|
+
TARGET_SELECTORS = %i(first take).freeze
|
19
19
|
|
20
|
-
def_node_matcher :where_first
|
21
|
-
(send
|
20
|
+
def_node_matcher :where_first?, <<-PATTERN
|
21
|
+
(send (send _ :where ...) {:first :take})
|
22
22
|
PATTERN
|
23
23
|
|
24
24
|
def on_send(node)
|
25
|
-
return unless
|
26
|
-
receiver, second_method = *recv_and_method
|
25
|
+
return unless where_first?(node)
|
27
26
|
|
28
|
-
range = range_between(receiver.loc.selector.begin_pos,
|
27
|
+
range = range_between(node.receiver.loc.selector.begin_pos,
|
29
28
|
node.loc.selector.end_pos)
|
30
29
|
|
31
|
-
add_offense(node, range, format(MSG,
|
30
|
+
add_offense(node, range, format(MSG, node.method_name))
|
32
31
|
end
|
33
32
|
|
34
33
|
def autocorrect(node)
|
35
|
-
receiver, second_method = where_first(node)
|
36
34
|
# Don't autocorrect where(...).first, because it can return different
|
37
35
|
# results from find_by. (They order records differently, so the
|
38
36
|
# 'first' record can be different.)
|
39
|
-
return if
|
37
|
+
return if node.method?(:first)
|
40
38
|
|
41
|
-
where_loc = receiver.loc.selector
|
39
|
+
where_loc = node.receiver.loc.selector
|
42
40
|
first_loc = range_between(node.loc.dot.begin_pos,
|
43
41
|
node.loc.selector.end_pos)
|
44
42
|
|
@@ -15,23 +15,20 @@ module RuboCop
|
|
15
15
|
class FindEach < Cop
|
16
16
|
MSG = 'Use `find_each` instead of `each`.'.freeze
|
17
17
|
|
18
|
-
SCOPE_METHODS =
|
18
|
+
SCOPE_METHODS = %i(all where not).freeze
|
19
|
+
IGNORED_METHODS = %i(order limit select).freeze
|
19
20
|
|
20
21
|
def on_send(node)
|
21
|
-
|
22
|
-
return unless receiver && method == :each
|
22
|
+
return unless node.receiver && node.method?(:each)
|
23
23
|
|
24
|
-
|
25
|
-
return unless SCOPE_METHODS.include?(preceding_method)
|
24
|
+
return unless SCOPE_METHODS.include?(node.receiver.method_name)
|
26
25
|
return if method_chain(node).any? { |m| ignored_by_find_each?(m) }
|
27
26
|
|
28
27
|
add_offense(node, node.loc.selector, MSG)
|
29
28
|
end
|
30
29
|
|
31
30
|
def autocorrect(node)
|
32
|
-
|
33
|
-
|
34
|
-
->(corrector) { corrector.replace(each_loc, 'find_each') }
|
31
|
+
->(corrector) { corrector.replace(node.loc.selector, 'find_each') }
|
35
32
|
end
|
36
33
|
|
37
34
|
private
|
@@ -42,7 +39,7 @@ module RuboCop
|
|
42
39
|
|
43
40
|
def ignored_by_find_each?(relation_method)
|
44
41
|
# Active Record's #find_each ignores various extra parameters
|
45
|
-
|
42
|
+
IGNORED_METHODS.include?(relation_method)
|
46
43
|
end
|
47
44
|
end
|
48
45
|
end
|
@@ -5,7 +5,10 @@ module RuboCop
|
|
5
5
|
module Rails
|
6
6
|
# This cop is used to identify usages of http methods like `get`, `post`,
|
7
7
|
# `put`, `patch` without the usage of keyword arguments in your tests and
|
8
|
-
# change them to use keyword
|
8
|
+
# change them to use keyword args. This cop only applies to Rails >= 5 .
|
9
|
+
# If you are not running Rails < 5 you should disable # the
|
10
|
+
# Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your
|
11
|
+
# .rubocop.yml file to 4.0, etc.
|
9
12
|
#
|
10
13
|
# @example
|
11
14
|
# # bad
|
@@ -14,12 +17,16 @@ module RuboCop
|
|
14
17
|
# # good
|
15
18
|
# get :new, params: { user_id: 1 }
|
16
19
|
class HttpPositionalArguments < Cop
|
20
|
+
extend TargetRailsVersion
|
21
|
+
|
17
22
|
MSG = 'Use keyword arguments instead of ' \
|
18
23
|
'positional arguments for http call: `%s`.'.freeze
|
19
|
-
KEYWORD_ARGS =
|
20
|
-
|
21
|
-
|
22
|
-
HTTP_METHODS =
|
24
|
+
KEYWORD_ARGS = %i(
|
25
|
+
headers env params body flash as xhr session method
|
26
|
+
).freeze
|
27
|
+
HTTP_METHODS = %i(get post put patch delete head).freeze
|
28
|
+
|
29
|
+
minimum_target_rails_version 5.0
|
23
30
|
|
24
31
|
def_node_matcher :http_request?, <<-END
|
25
32
|
(send nil {#{HTTP_METHODS.map(&:inspect).join(' ')}} !nil $_data ...)
|
@@ -80,7 +87,8 @@ module RuboCop
|
|
80
87
|
# the data is the http parameters and environment sent in
|
81
88
|
# the Rails 5 http call
|
82
89
|
def autocorrect(node)
|
83
|
-
|
90
|
+
http_path, *data = *node.arguments
|
91
|
+
|
84
92
|
controller_action = http_path.source
|
85
93
|
params = convert_hash_data(data.first, 'params')
|
86
94
|
headers = convert_hash_data(data.last, 'headers') if data.size > 1
|
@@ -88,7 +96,7 @@ module RuboCop
|
|
88
96
|
code_to_replace = node.loc.expression
|
89
97
|
# what to replace with
|
90
98
|
format = parentheses?(node) ? '%s(%s%s%s)' : '%s %s%s%s'
|
91
|
-
new_code = format(format,
|
99
|
+
new_code = format(format, node.method_name, controller_action,
|
92
100
|
params, headers)
|
93
101
|
->(corrector) { corrector.replace(code_to_replace, new_code) }
|
94
102
|
end
|
@@ -9,15 +9,13 @@ module RuboCop
|
|
9
9
|
"Use Rails's logger if you want to log.".freeze
|
10
10
|
|
11
11
|
def_node_matcher :output?, <<-PATTERN
|
12
|
-
(send nil {:ap :p :pp :pretty_print :print :puts}
|
12
|
+
(send nil {:ap :p :pp :pretty_print :print :puts} ...)
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def on_send(node)
|
16
|
-
output?(node)
|
17
|
-
return if args.empty?
|
16
|
+
return unless output?(node) && node.arguments?
|
18
17
|
|
19
|
-
|
20
|
-
end
|
18
|
+
add_offense(node, :selector)
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
@@ -30,8 +30,8 @@ module RuboCop
|
|
30
30
|
'prefer `safe_join` or other Rails tag helpers instead.'.freeze
|
31
31
|
|
32
32
|
def on_send(node)
|
33
|
-
|
34
|
-
|
33
|
+
ignore_node(node) if node.method?(:safe_join)
|
34
|
+
|
35
35
|
return unless !part_of_ignored_node?(node) &&
|
36
36
|
(looks_like_rails_html_safe?(node) ||
|
37
37
|
looks_like_rails_raw?(node))
|
@@ -42,15 +42,11 @@ module RuboCop
|
|
42
42
|
private
|
43
43
|
|
44
44
|
def looks_like_rails_html_safe?(node)
|
45
|
-
receiver
|
46
|
-
|
47
|
-
receiver && method_name == :html_safe && args.empty?
|
45
|
+
node.receiver && node.method?(:html_safe) && !node.arguments?
|
48
46
|
end
|
49
47
|
|
50
48
|
def looks_like_rails_raw?(node)
|
51
|
-
|
52
|
-
|
53
|
-
receiver.nil? && method_name == :raw && args.one?
|
49
|
+
node.command?(:raw) && node.arguments.one?
|
54
50
|
end
|
55
51
|
end
|
56
52
|
end
|
@@ -29,42 +29,43 @@ module RuboCop
|
|
29
29
|
MSG = 'Prefer `%s.%s`.'.freeze
|
30
30
|
|
31
31
|
def on_send(node)
|
32
|
-
|
33
|
-
return unless
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
add_offense(node,
|
39
|
-
:expression,
|
40
|
-
format(MSG, number, singularize(method_name)))
|
41
|
-
elsif expect_plural_method?(number, method_name)
|
42
|
-
add_offense(node,
|
43
|
-
:expression,
|
44
|
-
format(MSG, number, pluralize(method_name)))
|
45
|
-
end
|
32
|
+
return unless duration_method?(node.method_name)
|
33
|
+
return unless literal_number?(node.receiver)
|
34
|
+
|
35
|
+
return unless offense?(node)
|
36
|
+
|
37
|
+
add_offense(node, :expression)
|
46
38
|
end
|
47
39
|
|
48
40
|
private
|
49
41
|
|
42
|
+
def message(node)
|
43
|
+
number, = *node.receiver
|
44
|
+
|
45
|
+
format(MSG, number, correct_method(node.method_name.to_s))
|
46
|
+
end
|
47
|
+
|
50
48
|
def autocorrect(node)
|
51
49
|
lambda do |corrector|
|
52
50
|
method_name = node.loc.selector.source
|
53
|
-
|
54
|
-
|
55
|
-
else
|
56
|
-
pluralize(method_name)
|
57
|
-
end
|
58
|
-
corrector.replace(node.loc.selector, replacement)
|
51
|
+
|
52
|
+
corrector.replace(node.loc.selector, correct_method(method_name))
|
59
53
|
end
|
60
54
|
end
|
61
55
|
|
62
|
-
def
|
63
|
-
|
56
|
+
def correct_method(method_name)
|
57
|
+
if plural_method?(method_name)
|
58
|
+
singularize(method_name)
|
59
|
+
else
|
60
|
+
pluralize(method_name)
|
61
|
+
end
|
64
62
|
end
|
65
63
|
|
66
|
-
def
|
67
|
-
|
64
|
+
def offense?(node)
|
65
|
+
number, = *node.receiver
|
66
|
+
|
67
|
+
singular_receiver?(number) && plural_method?(node.method_name) ||
|
68
|
+
plural_receiver?(number) && singular_method?(node.method_name)
|
68
69
|
end
|
69
70
|
|
70
71
|
def plural_method?(method_name)
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# This cops checks for code that can be changed to `blank?`.
|
7
|
+
# Settings:
|
8
|
+
# NotNilAndNotEmpty: Convert checks for not `nil` and `not empty?`
|
9
|
+
# to `present?`
|
10
|
+
# NotBlank: Convert usages of not `blank?` to `present?`
|
11
|
+
# UnlessBlank: Convert usages of `unless` `blank?` to `if` `present?`
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # NotNilAndNotEmpty: true
|
15
|
+
# # bad
|
16
|
+
# !foo.nil? && !foo.empty?
|
17
|
+
# foo != nil && !foo.empty?
|
18
|
+
# !foo.blank?
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# foo.present?
|
22
|
+
#
|
23
|
+
# # NotBlank: true
|
24
|
+
# # bad
|
25
|
+
# !foo.blank?
|
26
|
+
# not foo.blank?
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# foo.present?
|
30
|
+
#
|
31
|
+
# # UnlessBlank: true
|
32
|
+
# # bad
|
33
|
+
# something unless foo.blank?
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# something if foo.present?
|
37
|
+
class Present < Cop
|
38
|
+
MSG_NOT_BLANK = 'Use `%s.present?` instead of `%s`.'.freeze
|
39
|
+
MSG_EXISTS_AND_NOT_EMPTY = 'Use `%s.present?` instead of `%s`.'.freeze
|
40
|
+
MSG_UNLESS_BLANK = 'Use `if %s.present?` instead of `%s`.'.freeze
|
41
|
+
|
42
|
+
def_node_matcher :exists_and_not_empty?, <<-PATTERN
|
43
|
+
(and
|
44
|
+
{
|
45
|
+
(send (send $_ :nil?) :!)
|
46
|
+
(send (send $_ :!) :!)
|
47
|
+
(send $_ :!= (:nil))
|
48
|
+
$_
|
49
|
+
}
|
50
|
+
{
|
51
|
+
(send (send $_ :empty?) :!)
|
52
|
+
}
|
53
|
+
)
|
54
|
+
PATTERN
|
55
|
+
|
56
|
+
def_node_matcher :not_blank?, '(send (send $_ :blank?) :!)'
|
57
|
+
|
58
|
+
def_node_matcher :unless_blank?, <<-PATTERN
|
59
|
+
(:if $(send $_ :blank?) {nil (...)} ...)
|
60
|
+
PATTERN
|
61
|
+
|
62
|
+
def on_send(node)
|
63
|
+
return unless cop_config['NotBlank']
|
64
|
+
|
65
|
+
not_blank?(node) do |receiver|
|
66
|
+
add_offense(node,
|
67
|
+
:expression,
|
68
|
+
format(MSG_NOT_BLANK, receiver.source, node.source))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def on_and(node)
|
73
|
+
return unless cop_config['NotNilAndNotEmpty']
|
74
|
+
|
75
|
+
exists_and_not_empty?(node) do |variable1, variable2|
|
76
|
+
return unless variable1 == variable2
|
77
|
+
|
78
|
+
add_offense(node,
|
79
|
+
:expression,
|
80
|
+
format(MSG_EXISTS_AND_NOT_EMPTY,
|
81
|
+
variable1.source,
|
82
|
+
node.source))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def on_or(node)
|
87
|
+
return unless cop_config['NilOrEmpty']
|
88
|
+
|
89
|
+
exists_and_not_empty?(node) do |variable1, variable2|
|
90
|
+
return unless variable1 == variable2
|
91
|
+
|
92
|
+
add_offense(node, :expression, MSG_EXISTS_AND_NOT_EMPTY)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def on_if(node)
|
97
|
+
return unless cop_config['UnlessBlank']
|
98
|
+
return unless node.unless?
|
99
|
+
|
100
|
+
unless_blank?(node) do |method_call, receiver|
|
101
|
+
range = unless_condition(node, method_call)
|
102
|
+
add_offense(node,
|
103
|
+
range,
|
104
|
+
format(MSG_UNLESS_BLANK, receiver.source, range.source))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def autocorrect(node)
|
109
|
+
lambda do |corrector|
|
110
|
+
method_call, variable1 = unless_blank?(node)
|
111
|
+
|
112
|
+
if method_call && variable1
|
113
|
+
corrector.replace(node.loc.keyword, 'if')
|
114
|
+
range = method_call.loc.expression
|
115
|
+
else
|
116
|
+
variable1, _variable2 =
|
117
|
+
exists_and_not_empty?(node) || not_blank?(node)
|
118
|
+
range = node.loc.expression
|
119
|
+
end
|
120
|
+
|
121
|
+
corrector.replace(range, "#{variable1.source}.present?")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def unless_condition(node, method_call)
|
128
|
+
if node.modifier_form?
|
129
|
+
node.loc.keyword.join(node.loc.expression.end)
|
130
|
+
else
|
131
|
+
node.loc.expression.begin.join(method_call.loc.expression)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|