rubocop 0.71.0 → 0.72.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -8
- data/config/default.yml +42 -484
- data/lib/rubocop.rb +5 -53
- data/lib/rubocop/ast/builder.rb +2 -0
- data/lib/rubocop/ast/node.rb +1 -1
- data/lib/rubocop/ast/node/float_node.rb +12 -0
- data/lib/rubocop/ast/node/int_node.rb +12 -0
- data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
- data/lib/rubocop/ast/node/resbody_node.rb +1 -6
- data/lib/rubocop/cached_data.rb +1 -1
- data/lib/rubocop/config.rb +34 -5
- data/lib/rubocop/config_loader.rb +2 -6
- data/lib/rubocop/config_loader_resolver.rb +0 -14
- data/lib/rubocop/cop/cop.rb +0 -4
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +55 -0
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/indent_first_argument.rb +6 -2
- data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
- data/lib/rubocop/cop/layout/indent_heredoc.rb +0 -1
- data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
- data/lib/rubocop/cop/layout/indentation_width.rb +8 -4
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -20
- data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -1
- data/lib/rubocop/cop/style/float_division.rb +94 -0
- data/lib/rubocop/cop/style/format_string.rb +7 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +12 -2
- data/lib/rubocop/cop/style/word_array.rb +2 -2
- data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
- data/lib/rubocop/options.rb +0 -2
- data/lib/rubocop/processed_source.rb +2 -1
- data/lib/rubocop/rspec/cop_helper.rb +0 -1
- data/lib/rubocop/rspec/shared_contexts.rb +0 -17
- data/lib/rubocop/rspec/support.rb +0 -1
- data/lib/rubocop/runner.rb +0 -17
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +8 -2
- metadata +8 -91
- data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
- data/lib/rubocop/cop/rails/action_filter.rb +0 -117
- data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
- data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
- data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
- data/lib/rubocop/cop/rails/application_job.rb +0 -40
- data/lib/rubocop/cop/rails/application_record.rb +0 -40
- data/lib/rubocop/cop/rails/assert_not.rb +0 -44
- data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
- data/lib/rubocop/cop/rails/blank.rb +0 -164
- data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
- data/lib/rubocop/cop/rails/date.rb +0 -161
- data/lib/rubocop/cop/rails/delegate.rb +0 -132
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
- data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
- data/lib/rubocop/cop/rails/exit.rb +0 -67
- data/lib/rubocop/cop/rails/file_path.rb +0 -108
- data/lib/rubocop/cop/rails/find_by.rb +0 -55
- data/lib/rubocop/cop/rails/find_each.rb +0 -51
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
- data/lib/rubocop/cop/rails/http_status.rb +0 -179
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
- data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
- data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
- data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
- data/lib/rubocop/cop/rails/output.rb +0 -49
- data/lib/rubocop/cop/rails/output_safety.rb +0 -99
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
- data/lib/rubocop/cop/rails/presence.rb +0 -124
- data/lib/rubocop/cop/rails/present.rb +0 -153
- data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
- data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
- data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
- data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
- data/lib/rubocop/cop/rails/request_referer.rb +0 -56
- data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
- data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
- data/lib/rubocop/cop/rails/save_bang.rb +0 -316
- data/lib/rubocop/cop/rails/scope_args.rb +0 -29
- data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
- data/lib/rubocop/cop/rails/time_zone.rb +0 -238
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
- data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
- data/lib/rubocop/cop/rails/validation.rb +0 -109
- data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -1,132 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop looks for delegations that could have been created
|
7
|
-
# automatically with the `delegate` method.
|
8
|
-
#
|
9
|
-
# Safe navigation `&.` is ignored because Rails' `allow_nil`
|
10
|
-
# option checks not just for nil but also delegates if nil
|
11
|
-
# responds to the delegated method.
|
12
|
-
#
|
13
|
-
# The `EnforceForPrefixed` option (defaulted to `true`) means that
|
14
|
-
# using the target object as a prefix of the method name
|
15
|
-
# without using the `delegate` method will be a violation.
|
16
|
-
# When set to `false`, this case is legal.
|
17
|
-
#
|
18
|
-
# @example
|
19
|
-
# # bad
|
20
|
-
# def bar
|
21
|
-
# foo.bar
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# # good
|
25
|
-
# delegate :bar, to: :foo
|
26
|
-
#
|
27
|
-
# # good
|
28
|
-
# def bar
|
29
|
-
# foo&.bar
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# # good
|
33
|
-
# private
|
34
|
-
# def bar
|
35
|
-
# foo.bar
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# @example EnforceForPrefixed: true (default)
|
39
|
-
# # bad
|
40
|
-
# def foo_bar
|
41
|
-
# foo.bar
|
42
|
-
# end
|
43
|
-
#
|
44
|
-
# # good
|
45
|
-
# delegate :bar, to: :foo, prefix: true
|
46
|
-
#
|
47
|
-
# @example EnforceForPrefixed: false
|
48
|
-
# # good
|
49
|
-
# def foo_bar
|
50
|
-
# foo.bar
|
51
|
-
# end
|
52
|
-
#
|
53
|
-
# # good
|
54
|
-
# delegate :bar, to: :foo, prefix: true
|
55
|
-
class Delegate < Cop
|
56
|
-
MSG = 'Use `delegate` to define delegations.'
|
57
|
-
|
58
|
-
def_node_matcher :delegate?, <<-PATTERN
|
59
|
-
(def _method_name _args
|
60
|
-
(send (send nil? _) _ ...))
|
61
|
-
PATTERN
|
62
|
-
|
63
|
-
def on_def(node)
|
64
|
-
return unless trivial_delegate?(node)
|
65
|
-
return if private_or_protected_delegation(node)
|
66
|
-
|
67
|
-
add_offense(node, location: :keyword)
|
68
|
-
end
|
69
|
-
|
70
|
-
def autocorrect(node)
|
71
|
-
delegation = ["delegate :#{node.body.method_name}",
|
72
|
-
"to: :#{node.body.receiver.method_name}"]
|
73
|
-
|
74
|
-
if node.method_name == prefixed_method_name(node.body)
|
75
|
-
delegation << ['prefix: true']
|
76
|
-
end
|
77
|
-
|
78
|
-
lambda do |corrector|
|
79
|
-
corrector.replace(node.source_range, delegation.join(', '))
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def trivial_delegate?(def_node)
|
86
|
-
delegate?(def_node) &&
|
87
|
-
method_name_matches?(def_node.method_name, def_node.body) &&
|
88
|
-
arguments_match?(def_node.arguments, def_node.body)
|
89
|
-
end
|
90
|
-
|
91
|
-
def arguments_match?(arg_array, body)
|
92
|
-
argument_array = body.arguments
|
93
|
-
|
94
|
-
return false if arg_array.size != argument_array.size
|
95
|
-
|
96
|
-
arg_array.zip(argument_array).all? do |arg, argument|
|
97
|
-
arg.arg_type? &&
|
98
|
-
argument.lvar_type? &&
|
99
|
-
arg.children == argument.children
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def method_name_matches?(method_name, body)
|
104
|
-
method_name == body.method_name ||
|
105
|
-
include_prefix_case? && method_name == prefixed_method_name(body)
|
106
|
-
end
|
107
|
-
|
108
|
-
def include_prefix_case?
|
109
|
-
cop_config['EnforceForPrefixed']
|
110
|
-
end
|
111
|
-
|
112
|
-
def prefixed_method_name(body)
|
113
|
-
[body.receiver.method_name, body.method_name].join('_').to_sym
|
114
|
-
end
|
115
|
-
|
116
|
-
def private_or_protected_delegation(node)
|
117
|
-
line = node.first_line
|
118
|
-
private_or_protected_before(line) ||
|
119
|
-
private_or_protected_inline(line)
|
120
|
-
end
|
121
|
-
|
122
|
-
def private_or_protected_before(line)
|
123
|
-
(processed_source[0..line].map(&:strip) & %w[private protected]).any?
|
124
|
-
end
|
125
|
-
|
126
|
-
def private_or_protected_inline(line)
|
127
|
-
processed_source[line - 1].strip =~ /\A(private )|(protected )/
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop looks for delegations that pass :allow_blank as an option
|
7
|
-
# instead of :allow_nil. :allow_blank is not a valid option to pass
|
8
|
-
# to ActiveSupport#delegate.
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# delegate :foo, to: :bar, allow_blank: true
|
13
|
-
#
|
14
|
-
# # good
|
15
|
-
# delegate :foo, to: :bar, allow_nil: true
|
16
|
-
class DelegateAllowBlank < Cop
|
17
|
-
MSG = '`allow_blank` is not a valid option, use `allow_nil`.'
|
18
|
-
|
19
|
-
def_node_matcher :allow_blank_option, <<-PATTERN
|
20
|
-
(send nil? :delegate _ (hash <$(pair (sym :allow_blank) true) ...>))
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def on_send(node)
|
24
|
-
allow_blank_option(node) do |offending_node|
|
25
|
-
add_offense(offending_node)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def autocorrect(pair_node)
|
30
|
-
lambda do |corrector|
|
31
|
-
corrector.replace(pair_node.key.source_range, 'allow_nil')
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop checks dynamic `find_by_*` methods.
|
7
|
-
# Use `find_by` instead of dynamic method.
|
8
|
-
# See. https://github.com/rubocop-hq/rails-style-guide#find_by
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# User.find_by_name(name)
|
13
|
-
#
|
14
|
-
# # bad
|
15
|
-
# User.find_by_name_and_email(name)
|
16
|
-
#
|
17
|
-
# # bad
|
18
|
-
# User.find_by_email!(name)
|
19
|
-
#
|
20
|
-
# # good
|
21
|
-
# User.find_by(name: name)
|
22
|
-
#
|
23
|
-
# # good
|
24
|
-
# User.find_by(name: name, email: email)
|
25
|
-
#
|
26
|
-
# # good
|
27
|
-
# User.find_by!(email: email)
|
28
|
-
class DynamicFindBy < Cop
|
29
|
-
MSG = 'Use `%<static_name>s` instead of dynamic `%<method>s`.'
|
30
|
-
METHOD_PATTERN = /^find_by_(.+?)(!)?$/.freeze
|
31
|
-
|
32
|
-
def on_send(node)
|
33
|
-
method_name = node.method_name.to_s
|
34
|
-
|
35
|
-
return if whitelist.include?(method_name)
|
36
|
-
|
37
|
-
static_name = static_method_name(method_name)
|
38
|
-
|
39
|
-
return unless static_name
|
40
|
-
|
41
|
-
add_offense(node,
|
42
|
-
message: format(MSG, static_name: static_name,
|
43
|
-
method: node.method_name))
|
44
|
-
end
|
45
|
-
alias on_csend on_send
|
46
|
-
|
47
|
-
def autocorrect(node)
|
48
|
-
keywords = column_keywords(node.method_name)
|
49
|
-
|
50
|
-
return if keywords.size != node.arguments.size
|
51
|
-
|
52
|
-
lambda do |corrector|
|
53
|
-
autocorrect_method_name(corrector, node)
|
54
|
-
autocorrect_argument_keywords(corrector, node, keywords)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def autocorrect_method_name(corrector, node)
|
61
|
-
corrector.replace(node.loc.selector,
|
62
|
-
static_method_name(node.method_name.to_s))
|
63
|
-
end
|
64
|
-
|
65
|
-
def autocorrect_argument_keywords(corrector, node, keywords)
|
66
|
-
keywords.each.with_index do |keyword, idx|
|
67
|
-
corrector.insert_before(node.arguments[idx].loc.expression, keyword)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def whitelist
|
72
|
-
cop_config['Whitelist']
|
73
|
-
end
|
74
|
-
|
75
|
-
def column_keywords(method)
|
76
|
-
keyword_string = method.to_s[METHOD_PATTERN, 1]
|
77
|
-
keyword_string.split('_and_').map { |keyword| "#{keyword}: " }
|
78
|
-
end
|
79
|
-
|
80
|
-
# Returns static method name.
|
81
|
-
# If code isn't wrong, returns nil
|
82
|
-
def static_method_name(method_name)
|
83
|
-
match = METHOD_PATTERN.match(method_name)
|
84
|
-
return nil unless match
|
85
|
-
|
86
|
-
match[2] ? 'find_by!' : 'find_by'
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop looks for duplicate values in enum declarations.
|
7
|
-
#
|
8
|
-
# @example
|
9
|
-
# # bad
|
10
|
-
# enum status: { active: 0, archived: 0 }
|
11
|
-
#
|
12
|
-
# # good
|
13
|
-
# enum status: { active: 0, archived: 1 }
|
14
|
-
#
|
15
|
-
# # bad
|
16
|
-
# enum status: [:active, :archived, :active]
|
17
|
-
#
|
18
|
-
# # good
|
19
|
-
# enum status: [:active, :archived]
|
20
|
-
class EnumUniqueness < Cop
|
21
|
-
include Duplication
|
22
|
-
|
23
|
-
MSG = 'Duplicate value `%<value>s` found in `%<enum>s` ' \
|
24
|
-
'enum declaration.'
|
25
|
-
|
26
|
-
def_node_matcher :enum_declaration, <<-PATTERN
|
27
|
-
(send nil? :enum (hash (pair (_ $_) ${array hash})))
|
28
|
-
PATTERN
|
29
|
-
|
30
|
-
def on_send(node)
|
31
|
-
enum_declaration(node) do |name, args|
|
32
|
-
items = args.values
|
33
|
-
|
34
|
-
return unless duplicates?(items)
|
35
|
-
|
36
|
-
consecutive_duplicates(items).each do |item|
|
37
|
-
add_offense(item, message: format(MSG, value: item.source,
|
38
|
-
enum: name))
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop checks that Rails.env is compared using `.production?`-like
|
7
|
-
# methods instead of equality against a string or symbol.
|
8
|
-
#
|
9
|
-
# @example
|
10
|
-
# # bad
|
11
|
-
# Rails.env == 'production'
|
12
|
-
#
|
13
|
-
# # bad, always returns false
|
14
|
-
# Rails.env == :test
|
15
|
-
#
|
16
|
-
# # good
|
17
|
-
# Rails.env.production?
|
18
|
-
class EnvironmentComparison < Cop
|
19
|
-
MSG = "Favor `Rails.env.%<env>s?` over `Rails.env == '%<env>s'`."
|
20
|
-
|
21
|
-
SYM_MSG = 'Do not compare `Rails.env` with a symbol, it will always ' \
|
22
|
-
'evaluate to `false`.'
|
23
|
-
|
24
|
-
def_node_matcher :environment_str_comparison?, <<-PATTERN
|
25
|
-
(send
|
26
|
-
(send (const {nil? cbase} :Rails) :env)
|
27
|
-
:==
|
28
|
-
$str
|
29
|
-
)
|
30
|
-
PATTERN
|
31
|
-
|
32
|
-
def_node_matcher :environment_sym_comparison?, <<-PATTERN
|
33
|
-
(send
|
34
|
-
(send (const {nil? cbase} :Rails) :env)
|
35
|
-
:==
|
36
|
-
$sym
|
37
|
-
)
|
38
|
-
PATTERN
|
39
|
-
|
40
|
-
def on_send(node)
|
41
|
-
environment_str_comparison?(node) do |env_node|
|
42
|
-
env, = *env_node
|
43
|
-
add_offense(node, message: format(MSG, env: env))
|
44
|
-
end
|
45
|
-
environment_sym_comparison?(node) do |_|
|
46
|
-
add_offense(node, message: SYM_MSG)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def autocorrect(node)
|
51
|
-
lambda do |corrector|
|
52
|
-
corrector.replace(node.source_range, replacement(node))
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def replacement(node)
|
59
|
-
"#{node.receiver.source}.#{content(node.first_argument)}?"
|
60
|
-
end
|
61
|
-
|
62
|
-
def_node_matcher :content, <<-PATTERN
|
63
|
-
({str sym} $_)
|
64
|
-
PATTERN
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop enforces that `exit` calls are not used within a rails app.
|
7
|
-
# Valid options are instead to raise an error, break, return, or some
|
8
|
-
# other form of stopping execution of current request.
|
9
|
-
#
|
10
|
-
# There are two obvious cases where `exit` is particularly harmful:
|
11
|
-
#
|
12
|
-
# - Usage in library code for your application. Even though Rails will
|
13
|
-
# rescue from a `SystemExit` and continue on, unit testing that library
|
14
|
-
# code will result in specs exiting (potentially silently if `exit(0)`
|
15
|
-
# is used.)
|
16
|
-
# - Usage in application code outside of the web process could result in
|
17
|
-
# the program exiting, which could result in the code failing to run and
|
18
|
-
# do its job.
|
19
|
-
#
|
20
|
-
# @example
|
21
|
-
# # bad
|
22
|
-
# exit(0)
|
23
|
-
#
|
24
|
-
# # good
|
25
|
-
# raise 'a bad error has happened'
|
26
|
-
class Exit < Cop
|
27
|
-
include ConfigurableEnforcedStyle
|
28
|
-
|
29
|
-
MSG = 'Do not use `exit` in Rails applications.'
|
30
|
-
TARGET_METHODS = %i[exit exit!].freeze
|
31
|
-
EXPLICIT_RECEIVERS = %i[Kernel Process].freeze
|
32
|
-
|
33
|
-
def on_send(node)
|
34
|
-
add_offense(node, location: :selector) if offending_node?(node)
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def offending_node?(node)
|
40
|
-
right_method_name?(node.method_name) &&
|
41
|
-
right_argument_count?(node.arguments) &&
|
42
|
-
right_receiver?(node.receiver)
|
43
|
-
end
|
44
|
-
|
45
|
-
def right_method_name?(method_name)
|
46
|
-
TARGET_METHODS.include?(method_name)
|
47
|
-
end
|
48
|
-
|
49
|
-
# More than 1 argument likely means it is a different
|
50
|
-
# `exit` implementation than the one we are preventing.
|
51
|
-
def right_argument_count?(arg_nodes)
|
52
|
-
arg_nodes.size <= 1
|
53
|
-
end
|
54
|
-
|
55
|
-
# Only register if exit is being called explicitly on `Kernel`,
|
56
|
-
# `Process`, or if receiver node is nil for plain `exit` calls.
|
57
|
-
def right_receiver?(receiver_node)
|
58
|
-
return true unless receiver_node
|
59
|
-
|
60
|
-
_a, receiver_node_class, _c = *receiver_node
|
61
|
-
|
62
|
-
EXPLICIT_RECEIVERS.include?(receiver_node_class)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Rails
|
6
|
-
# This cop is used to identify usages of file path joining process
|
7
|
-
# to use `Rails.root.join` clause. It is used to add uniformity when
|
8
|
-
# joining paths.
|
9
|
-
#
|
10
|
-
# @example EnforcedStyle: arguments (default)
|
11
|
-
# # bad
|
12
|
-
# Rails.root.join('app/models/goober')
|
13
|
-
# File.join(Rails.root, 'app/models/goober')
|
14
|
-
# "#{Rails.root}/app/models/goober"
|
15
|
-
#
|
16
|
-
# # good
|
17
|
-
# Rails.root.join('app', 'models', 'goober')
|
18
|
-
#
|
19
|
-
# @example EnforcedStyle: slashes
|
20
|
-
# # bad
|
21
|
-
# Rails.root.join('app', 'models', 'goober')
|
22
|
-
# File.join(Rails.root, 'app/models/goober')
|
23
|
-
# "#{Rails.root}/app/models/goober"
|
24
|
-
#
|
25
|
-
# # good
|
26
|
-
# Rails.root.join('app/models/goober')
|
27
|
-
#
|
28
|
-
class FilePath < Cop
|
29
|
-
include ConfigurableEnforcedStyle
|
30
|
-
include RangeHelp
|
31
|
-
|
32
|
-
MSG_SLASHES = 'Please use `Rails.root.join(\'path/to\')` ' \
|
33
|
-
'instead.'
|
34
|
-
MSG_ARGUMENTS = 'Please use `Rails.root.join(\'path\', \'to\')` ' \
|
35
|
-
'instead.'
|
36
|
-
|
37
|
-
def_node_matcher :file_join_nodes?, <<-PATTERN
|
38
|
-
(send (const nil? :File) :join ...)
|
39
|
-
PATTERN
|
40
|
-
|
41
|
-
def_node_search :rails_root_nodes?, <<-PATTERN
|
42
|
-
(send (const nil? :Rails) :root)
|
43
|
-
PATTERN
|
44
|
-
|
45
|
-
def_node_matcher :rails_root_join_nodes?, <<-PATTERN
|
46
|
-
(send (send (const nil? :Rails) :root) :join ...)
|
47
|
-
PATTERN
|
48
|
-
|
49
|
-
def on_dstr(node)
|
50
|
-
return unless rails_root_nodes?(node)
|
51
|
-
return unless node.children.last.source.start_with?('.') ||
|
52
|
-
node.children.last.source.include?(File::SEPARATOR)
|
53
|
-
|
54
|
-
register_offense(node)
|
55
|
-
end
|
56
|
-
|
57
|
-
def on_send(node)
|
58
|
-
check_for_file_join_with_rails_root(node)
|
59
|
-
check_for_rails_root_join_with_slash_separated_path(node)
|
60
|
-
check_for_rails_root_join_with_string_arguments(node)
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def check_for_file_join_with_rails_root(node)
|
66
|
-
return unless file_join_nodes?(node)
|
67
|
-
return unless node.arguments.any? { |e| rails_root_nodes?(e) }
|
68
|
-
|
69
|
-
register_offense(node)
|
70
|
-
end
|
71
|
-
|
72
|
-
def check_for_rails_root_join_with_string_arguments(node)
|
73
|
-
return unless style == :slashes
|
74
|
-
return unless rails_root_nodes?(node)
|
75
|
-
return unless rails_root_join_nodes?(node)
|
76
|
-
return unless node.arguments.size > 1
|
77
|
-
return unless node.arguments.all?(&:str_type?)
|
78
|
-
|
79
|
-
register_offense(node)
|
80
|
-
end
|
81
|
-
|
82
|
-
def check_for_rails_root_join_with_slash_separated_path(node)
|
83
|
-
return unless style == :arguments
|
84
|
-
return unless rails_root_nodes?(node)
|
85
|
-
return unless rails_root_join_nodes?(node)
|
86
|
-
return unless node.arguments.any? { |arg| string_with_slash?(arg) }
|
87
|
-
|
88
|
-
register_offense(node)
|
89
|
-
end
|
90
|
-
|
91
|
-
def string_with_slash?(node)
|
92
|
-
node.str_type? && node.source =~ %r{/}
|
93
|
-
end
|
94
|
-
|
95
|
-
def register_offense(node)
|
96
|
-
line_range = node.loc.column...node.loc.last_column
|
97
|
-
source_range = source_range(processed_source.buffer, node.first_line,
|
98
|
-
line_range)
|
99
|
-
add_offense(node, location: source_range)
|
100
|
-
end
|
101
|
-
|
102
|
-
def message(_node)
|
103
|
-
format(style == :arguments ? MSG_ARGUMENTS : MSG_SLASHES)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|