rubocop 0.70.0 → 0.72.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.
- checksums.yaml +4 -4
- data/README.md +5 -10
- data/config/default.yml +50 -491
- 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 +35 -6
- data/lib/rubocop/config_loader.rb +2 -2
- data/lib/rubocop/config_loader_resolver.rb +0 -6
- 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/empty_lines_around_block_body.rb +3 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -0
- 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/layout/multiline_method_argument_line_breaks.rb +2 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment.rb +4 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +20 -22
- 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/trailing_comma_in_arguments.rb +4 -0
- data/lib/rubocop/cop/style/word_array.rb +2 -2
- data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
- data/lib/rubocop/node_pattern.rb +84 -5
- data/lib/rubocop/options.rb +0 -2
- data/lib/rubocop/processed_source.rb +5 -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 +6 -7
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +8 -2
- metadata +7 -69
- 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
|