rubocop 1.19.0 → 1.23.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 +1 -1
- data/config/default.yml +129 -21
- data/lib/rubocop/config.rb +5 -0
- data/lib/rubocop/config_loader.rb +5 -3
- data/lib/rubocop/config_validator.rb +9 -1
- data/lib/rubocop/cop/base.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_filename.rb +103 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +45 -21
- data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +11 -10
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/date_assignment.rb +2 -10
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -10
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
- data/lib/rubocop/cop/gemspec/require_mfa.rb +146 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +31 -24
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -10
- data/lib/rubocop/cop/generator.rb +14 -8
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +60 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/assignment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +2 -1
- data/lib/rubocop/cop/layout/dot_position.rb +34 -5
- data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +7 -4
- data/lib/rubocop/cop/layout/end_alignment.rb +2 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +9 -7
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -3
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +3 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +15 -4
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_comment.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +11 -5
- data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -28
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +111 -0
- data/lib/rubocop/cop/lint/ambiguous_range.rb +11 -11
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -5
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +18 -5
- data/lib/rubocop/cop/lint/boolean_symbol.rb +5 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -4
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/deprecated_constants.rb +3 -2
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
- data/lib/rubocop/cop/lint/else_layout.rb +10 -6
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +67 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +5 -0
- data/lib/rubocop/cop/lint/loop.rb +4 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +16 -2
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +4 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +10 -0
- data/lib/rubocop/cop/lint/raise_exception.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +5 -4
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +50 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/triple_quotes.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +8 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -3
- data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +117 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/useless_times.rb +4 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
- data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +57 -34
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +5 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +30 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +11 -3
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +9 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_body.rb +1 -1
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +0 -3
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +37 -4
- data/lib/rubocop/cop/naming/inclusive_language.rb +9 -9
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +5 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +7 -0
- data/lib/rubocop/cop/security/io_methods.rb +49 -0
- data/lib/rubocop/cop/security/json_load.rb +8 -7
- data/lib/rubocop/cop/security/open.rb +4 -0
- data/lib/rubocop/cop/security/yaml_load.rb +4 -0
- data/lib/rubocop/cop/style/accessor_grouping.rb +2 -2
- data/lib/rubocop/cop/style/and_or.rb +5 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +13 -2
- data/lib/rubocop/cop/style/array_coercion.rb +21 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +0 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +23 -6
- data/lib/rubocop/cop/style/case_equality.rb +6 -9
- data/lib/rubocop/cop/style/case_like_if.rb +5 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +9 -0
- data/lib/rubocop/cop/style/collection_compact.rb +7 -5
- data/lib/rubocop/cop/style/collection_methods.rb +8 -6
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/comment_annotation.rb +25 -39
- data/lib/rubocop/cop/style/commented_keyword.rb +9 -4
- data/lib/rubocop/cop/style/date_time.rb +5 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +23 -8
- data/lib/rubocop/cop/style/double_negation.rb +27 -6
- data/lib/rubocop/cop/style/empty_method.rb +2 -2
- data/lib/rubocop/cop/style/encoding.rb +26 -15
- data/lib/rubocop/cop/style/explicit_block_argument.rb +21 -11
- data/lib/rubocop/cop/style/float_division.rb +10 -2
- data/lib/rubocop/cop/style/format_string_token.rb +2 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +7 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +4 -0
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +11 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +5 -0
- data/lib/rubocop/cop/style/hash_except.rb +4 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -6
- data/lib/rubocop/cop/style/hash_transform_values.rb +4 -6
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -16
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +18 -4
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -2
- data/lib/rubocop/cop/style/lambda_call.rb +1 -1
- data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -6
- data/lib/rubocop/cop/style/module_function.rb +8 -9
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +73 -6
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_unless.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -2
- data/lib/rubocop/cop/style/not.rb +2 -2
- data/lib/rubocop/cop/style/numbered_parameters.rb +46 -0
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +50 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
- data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
- data/lib/rubocop/cop/style/open_struct_use.rb +69 -0
- data/lib/rubocop/cop/style/optional_arguments.rb +4 -0
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +14 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -2
- data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
- data/lib/rubocop/cop/style/quoted_symbols.rb +21 -7
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +19 -9
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +12 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self.rb +10 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +23 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +51 -18
- data/lib/rubocop/cop/style/regexp_literal.rb +3 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +139 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +5 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +13 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -0
- data/lib/rubocop/cop/style/static_class.rb +5 -5
- data/lib/rubocop/cop/style/string_chars.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +5 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +4 -0
- data/lib/rubocop/cop/style/swap_values.rb +4 -2
- data/lib/rubocop/cop/style/symbol_array.rb +3 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +26 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +19 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +3 -3
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -7
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
- data/lib/rubocop/cop/util.rb +15 -4
- data/lib/rubocop/cops_documentation_generator.rb +17 -5
- data/lib/rubocop/formatter/html_formatter.rb +5 -2
- data/lib/rubocop/formatter/json_formatter.rb +4 -1
- data/lib/rubocop/magic_comment.rb +44 -15
- data/lib/rubocop/options.rb +126 -112
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +1 -1
- data/lib/rubocop/result_cache.rb +3 -3
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/parallel_formatter.rb +90 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +2 -3
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -1
- data/lib/rubocop.rb +14 -2
- metadata +20 -5
@@ -3,18 +3,21 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Bundler
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# 'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
|
6
|
+
# Passing symbol arguments to `source` (e.g. `source :rubygems`) is
|
7
|
+
# deprecated because they default to using HTTP requests. Instead, specify
|
8
|
+
# `'https://rubygems.org'` if possible, or `'http://rubygems.org'` if not.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# most use cases HTTPS will be fine.
|
10
|
+
# When autocorrecting, this cop will replace symbol arguments with
|
11
|
+
# `'https://rubygems.org'`.
|
13
12
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
13
|
+
# This cop will not replace existing sources that use `http://`. This may
|
14
|
+
# be necessary where HTTPS is not available. For example, where using an
|
15
|
+
# internal gem server via an intranet, or where HTTPS is prohibited.
|
16
|
+
# However, you should strongly prefer `https://` where possible, as it is
|
17
|
+
# more secure.
|
18
|
+
#
|
19
|
+
# If you don't allow `http://`, please set `false` to `AllowHttpProtocol`.
|
20
|
+
# This option is `true` by default for safe autocorrection.
|
18
21
|
#
|
19
22
|
# @example
|
20
23
|
# # bad
|
@@ -24,7 +27,17 @@ module RuboCop
|
|
24
27
|
#
|
25
28
|
# # good
|
26
29
|
# source 'https://rubygems.org' # strongly recommended
|
30
|
+
#
|
31
|
+
# @example AllowHttpProtocol: true (default)
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# source 'http://rubygems.org' # use only if HTTPS is unavailable
|
35
|
+
#
|
36
|
+
# @example AllowHttpProtocol: false
|
37
|
+
#
|
38
|
+
# # bad
|
27
39
|
# source 'http://rubygems.org'
|
40
|
+
#
|
28
41
|
class InsecureProtocolSource < Base
|
29
42
|
include RangeHelp
|
30
43
|
extend AutoCorrector
|
@@ -33,29 +46,40 @@ module RuboCop
|
|
33
46
|
'are insecure. ' \
|
34
47
|
"Please change your source to 'https://rubygems.org' " \
|
35
48
|
"if possible, or 'http://rubygems.org' if not."
|
49
|
+
MSG_HTTP_PROTOCOL = 'Use `https://rubygems.org` instead of `http://rubygems.org`.'
|
36
50
|
|
37
51
|
RESTRICT_ON_SEND = %i[source].freeze
|
38
52
|
|
39
53
|
# @!method insecure_protocol_source?(node)
|
40
54
|
def_node_matcher :insecure_protocol_source?, <<~PATTERN
|
41
55
|
(send nil? :source
|
42
|
-
$(sym
|
56
|
+
${(sym :gemcutter) (sym :rubygems) (sym :rubyforge) (:str "http://rubygems.org")})
|
43
57
|
PATTERN
|
44
58
|
|
45
59
|
def on_send(node)
|
46
|
-
insecure_protocol_source?(node) do |source_node
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
insecure_protocol_source?(node) do |source_node|
|
61
|
+
source = source_node.value
|
62
|
+
use_http_protocol = source == 'http://rubygems.org'
|
63
|
+
|
64
|
+
return if allow_http_protocol? && use_http_protocol
|
65
|
+
|
66
|
+
message = if use_http_protocol
|
67
|
+
MSG_HTTP_PROTOCOL
|
68
|
+
else
|
69
|
+
format(MSG, source: source)
|
70
|
+
end
|
71
|
+
|
72
|
+
add_offense(source_node, message: message) do |corrector|
|
73
|
+
corrector.replace(source_node, "'https://rubygems.org'")
|
56
74
|
end
|
57
75
|
end
|
58
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def allow_http_protocol?
|
81
|
+
cop_config.fetch('AllowHttpProtocol', true)
|
82
|
+
end
|
59
83
|
end
|
60
84
|
end
|
61
85
|
end
|
@@ -24,15 +24,15 @@ module RuboCop
|
|
24
24
|
# gem 'rubocop'
|
25
25
|
# # For tests
|
26
26
|
# gem 'rspec'
|
27
|
-
class OrderedGems <
|
28
|
-
|
27
|
+
class OrderedGems < Base
|
28
|
+
extend AutoCorrector
|
29
29
|
include OrderedGemNode
|
30
30
|
|
31
31
|
MSG = 'Gems should be sorted in an alphabetical order within their '\
|
32
32
|
'section of the Gemfile. '\
|
33
33
|
'Gem `%<previous>s` should appear before `%<current>s`.'
|
34
34
|
|
35
|
-
def
|
35
|
+
def on_new_investigation
|
36
36
|
return if processed_source.blank?
|
37
37
|
|
38
38
|
gem_declarations(processed_source.ast)
|
@@ -44,15 +44,6 @@ module RuboCop
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def autocorrect(node)
|
48
|
-
OrderedGemCorrector.correct(
|
49
|
-
processed_source,
|
50
|
-
node,
|
51
|
-
previous_declaration(node),
|
52
|
-
treat_comments_as_separators
|
53
|
-
)
|
54
|
-
end
|
55
|
-
|
56
47
|
private
|
57
48
|
|
58
49
|
def previous_declaration(node)
|
@@ -87,8 +87,8 @@ module RuboCop
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def needs_separating_space?
|
90
|
-
block_begin.begin_pos == arguments_end_pos &&
|
91
|
-
selector_end.end_pos == arguments_begin_pos ||
|
90
|
+
(block_begin.begin_pos == arguments_end_pos &&
|
91
|
+
selector_end.end_pos == arguments_begin_pos) ||
|
92
92
|
block_begin.begin_pos == selector_end.end_pos
|
93
93
|
end
|
94
94
|
|
@@ -4,9 +4,10 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
# This auto-corrects gem dependency order
|
6
6
|
class OrderedGemCorrector
|
7
|
-
extend OrderedGemNode
|
8
|
-
|
9
7
|
class << self
|
8
|
+
include OrderedGemNode
|
9
|
+
include RangeHelp
|
10
|
+
|
10
11
|
attr_reader :processed_source, :comments_as_separators
|
11
12
|
|
12
13
|
def correct(processed_source, node,
|
@@ -17,24 +18,24 @@ module RuboCop
|
|
17
18
|
current_range = declaration_with_comment(node)
|
18
19
|
previous_range = declaration_with_comment(previous_declaration)
|
19
20
|
|
20
|
-
->(corrector)
|
21
|
+
->(corrector) { swap_range(corrector, current_range, previous_range) }
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
26
|
def declaration_with_comment(node)
|
26
27
|
buffer = processed_source.buffer
|
27
|
-
begin_pos = get_source_range(node, comments_as_separators).begin_pos
|
28
|
+
begin_pos = range_by_whole_lines(get_source_range(node, comments_as_separators)).begin_pos
|
28
29
|
end_line = buffer.line_for_position(node.loc.expression.end_pos)
|
29
|
-
end_pos = buffer.line_range(end_line)
|
30
|
-
|
30
|
+
end_pos = range_by_whole_lines(buffer.line_range(end_line),
|
31
|
+
include_final_newline: true).end_pos
|
32
|
+
|
33
|
+
range_between(begin_pos, end_pos)
|
31
34
|
end
|
32
35
|
|
33
36
|
def swap_range(corrector, range1, range2)
|
34
|
-
|
35
|
-
|
36
|
-
corrector.replace(range1, src2)
|
37
|
-
corrector.replace(range2, src1)
|
37
|
+
corrector.insert_before(range2, range1.source)
|
38
|
+
corrector.remove(range1)
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -21,21 +21,13 @@ module RuboCop
|
|
21
21
|
#
|
22
22
|
class DateAssignment < Base
|
23
23
|
include RangeHelp
|
24
|
+
include GemspecHelp
|
24
25
|
extend AutoCorrector
|
25
26
|
|
26
27
|
MSG = 'Do not use `date =` in gemspec, it is set automatically when the gem is packaged.'
|
27
28
|
|
28
|
-
# @!method gem_specification(node)
|
29
|
-
def_node_matcher :gem_specification, <<~PATTERN
|
30
|
-
(block
|
31
|
-
(send
|
32
|
-
(const
|
33
|
-
(const {cbase nil?} :Gem) :Specification) :new)
|
34
|
-
...)
|
35
|
-
PATTERN
|
36
|
-
|
37
29
|
def on_block(block_node)
|
38
|
-
return unless gem_specification(block_node)
|
30
|
+
return unless gem_specification?(block_node)
|
39
31
|
|
40
32
|
block_parameter = block_node.arguments.first.source
|
41
33
|
|
@@ -36,20 +36,11 @@ module RuboCop
|
|
36
36
|
# end
|
37
37
|
class DuplicatedAssignment < Base
|
38
38
|
include RangeHelp
|
39
|
+
include GemspecHelp
|
39
40
|
|
40
41
|
MSG = '`%<assignment>s` method calls already given on line '\
|
41
42
|
'%<line_of_first_occurrence>d of the gemspec.'
|
42
43
|
|
43
|
-
# @!method gem_specification(node)
|
44
|
-
def_node_search :gem_specification, <<~PATTERN
|
45
|
-
(block
|
46
|
-
(send
|
47
|
-
(const
|
48
|
-
(const {cbase nil?} :Gem) :Specification) :new)
|
49
|
-
(args
|
50
|
-
(arg $_)) ...)
|
51
|
-
PATTERN
|
52
|
-
|
53
44
|
# @!method assignment_method_declarations(node)
|
54
45
|
def_node_search :assignment_method_declarations, <<~PATTERN
|
55
46
|
(send
|
@@ -50,15 +50,15 @@ module RuboCop
|
|
50
50
|
# spec.add_dependency 'rubocop'
|
51
51
|
# # For tests
|
52
52
|
# spec.add_dependency 'rspec'
|
53
|
-
class OrderedDependencies <
|
54
|
-
|
53
|
+
class OrderedDependencies < Base
|
54
|
+
extend AutoCorrector
|
55
55
|
include OrderedGemNode
|
56
56
|
|
57
57
|
MSG = 'Dependencies should be sorted in an alphabetical order within ' \
|
58
58
|
'their section of the gemspec. '\
|
59
59
|
'Dependency `%<previous>s` should appear before `%<current>s`.'
|
60
60
|
|
61
|
-
def
|
61
|
+
def on_new_investigation
|
62
62
|
return if processed_source.blank?
|
63
63
|
|
64
64
|
dependency_declarations(processed_source.ast)
|
@@ -71,15 +71,6 @@ module RuboCop
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def autocorrect(node)
|
75
|
-
OrderedGemCorrector.correct(
|
76
|
-
processed_source,
|
77
|
-
node,
|
78
|
-
previous_declaration(node),
|
79
|
-
treat_comments_as_separators
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
83
74
|
private
|
84
75
|
|
85
76
|
def previous_declaration(node)
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Gemspec
|
6
|
+
# Requires a gemspec to have `rubygems_mfa_required` metadata set.
|
7
|
+
#
|
8
|
+
# This setting tells RubyGems that MFA is required for accounts to
|
9
|
+
# be able perform any of these privileged operations:
|
10
|
+
#
|
11
|
+
# * gem push
|
12
|
+
# * gem yank
|
13
|
+
# * gem owner --add/remove
|
14
|
+
# * adding or removing owners using gem ownership page
|
15
|
+
#
|
16
|
+
# This helps make your gem more secure, as users can be more
|
17
|
+
# confident that gem updates were pushed by maintainers.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# Gem::Specification.new do |spec|
|
23
|
+
# # no `rubygems_mfa_required` metadata specified
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# Gem::Specification.new do |spec|
|
28
|
+
# spec.metadata = {
|
29
|
+
# 'rubygems_mfa_required' => 'true'
|
30
|
+
# }
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# Gem::Specification.new do |spec|
|
35
|
+
# spec.metadata['rubygems_mfa_required'] = 'true'
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # bad
|
39
|
+
# Gem::Specification.new do |spec|
|
40
|
+
# spec.metadata = {
|
41
|
+
# 'rubygems_mfa_required' => 'false'
|
42
|
+
# }
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# Gem::Specification.new do |spec|
|
47
|
+
# spec.metadata = {
|
48
|
+
# 'rubygems_mfa_required' => 'true'
|
49
|
+
# }
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # bad
|
53
|
+
# Gem::Specification.new do |spec|
|
54
|
+
# spec.metadata['rubygems_mfa_required'] = 'false'
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# # good
|
58
|
+
# Gem::Specification.new do |spec|
|
59
|
+
# spec.metadata['rubygems_mfa_required'] = 'true'
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
class RequireMFA < Base
|
63
|
+
include GemspecHelp
|
64
|
+
extend AutoCorrector
|
65
|
+
|
66
|
+
MSG = "`metadata['rubygems_mfa_required']` must be set to `'true'`."
|
67
|
+
|
68
|
+
# @!method metadata(node)
|
69
|
+
def_node_matcher :metadata, <<~PATTERN
|
70
|
+
`{
|
71
|
+
(send _ :metadata= $_)
|
72
|
+
(send (send _ :metadata) :[]= (str "rubygems_mfa_required") $_)
|
73
|
+
}
|
74
|
+
PATTERN
|
75
|
+
|
76
|
+
# @!method rubygems_mfa_required(node)
|
77
|
+
def_node_search :rubygems_mfa_required, <<~PATTERN
|
78
|
+
(pair (str "rubygems_mfa_required") $_)
|
79
|
+
PATTERN
|
80
|
+
|
81
|
+
# @!method true_string?(node)
|
82
|
+
def_node_matcher :true_string?, <<~PATTERN
|
83
|
+
(str "true")
|
84
|
+
PATTERN
|
85
|
+
|
86
|
+
def on_block(node) # rubocop:disable Metrics/MethodLength
|
87
|
+
gem_specification(node) do |block_var|
|
88
|
+
metadata_value = metadata(node)
|
89
|
+
mfa_value = mfa_value(metadata_value)
|
90
|
+
|
91
|
+
if mfa_value
|
92
|
+
unless true_string?(mfa_value)
|
93
|
+
add_offense(mfa_value) do |corrector|
|
94
|
+
change_value(corrector, mfa_value)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
else
|
98
|
+
add_offense(node) do |corrector|
|
99
|
+
autocorrect(corrector, node, block_var, metadata_value)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def mfa_value(metadata_value)
|
108
|
+
return unless metadata_value
|
109
|
+
return metadata_value if metadata_value.str_type?
|
110
|
+
|
111
|
+
rubygems_mfa_required(metadata_value).first
|
112
|
+
end
|
113
|
+
|
114
|
+
def autocorrect(corrector, node, block_var, metadata)
|
115
|
+
if metadata
|
116
|
+
return unless metadata.hash_type?
|
117
|
+
|
118
|
+
correct_metadata(corrector, metadata)
|
119
|
+
else
|
120
|
+
correct_missing_metadata(corrector, node, block_var)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def correct_metadata(corrector, metadata)
|
125
|
+
if metadata.pairs.any?
|
126
|
+
corrector.insert_after(metadata.pairs.last, ",\n'rubygems_mfa_required' => 'true'")
|
127
|
+
else
|
128
|
+
corrector.insert_before(metadata.loc.end, "'rubygems_mfa_required' => 'true'")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def correct_missing_metadata(corrector, node, block_var)
|
133
|
+
corrector.insert_before(node.loc.end, <<~RUBY)
|
134
|
+
#{block_var}.metadata = {
|
135
|
+
'rubygems_mfa_required' => 'true'
|
136
|
+
}
|
137
|
+
RUBY
|
138
|
+
end
|
139
|
+
|
140
|
+
def change_value(corrector, value)
|
141
|
+
corrector.replace(value, "'true'")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -3,10 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Gemspec
|
6
|
-
# Checks that `required_ruby_version`
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
6
|
+
# Checks that `required_ruby_version` in a gemspec file is set to a valid
|
7
|
+
# value (non-blank) and matches `TargetRubyVersion` as set in RuboCop's
|
8
|
+
# configuration for the gem.
|
9
|
+
#
|
10
|
+
# This ensures that RuboCop is using the same Ruby version as the gem.
|
10
11
|
#
|
11
12
|
# @example
|
12
13
|
# # When `TargetRubyVersion` of .rubocop.yml is `2.5`.
|
@@ -26,6 +27,11 @@ module RuboCop
|
|
26
27
|
# spec.required_ruby_version = '>= 2.6.0'
|
27
28
|
# end
|
28
29
|
#
|
30
|
+
# # bad
|
31
|
+
# Gem::Specification.new do |spec|
|
32
|
+
# spec.required_ruby_version = ''
|
33
|
+
# end
|
34
|
+
#
|
29
35
|
# # good
|
30
36
|
# Gem::Specification.new do |spec|
|
31
37
|
# spec.required_ruby_version = '>= 2.5.0'
|
@@ -42,22 +48,22 @@ module RuboCop
|
|
42
48
|
# end
|
43
49
|
#
|
44
50
|
# # accepted but not recommended, since
|
45
|
-
# # Ruby does not really follow semantic
|
51
|
+
# # Ruby does not really follow semantic versioning
|
46
52
|
# Gem::Specification.new do |spec|
|
47
53
|
# spec.required_ruby_version = '~> 2.5'
|
48
54
|
# end
|
49
55
|
class RequiredRubyVersion < Base
|
50
56
|
include RangeHelp
|
51
57
|
|
52
|
-
|
53
|
-
|
58
|
+
RESTRICT_ON_SEND = %i[required_ruby_version=].freeze
|
59
|
+
NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \
|
54
60
|
'(%<target_ruby_version>s, which may be specified in ' \
|
55
61
|
'.rubocop.yml) should be equal.'
|
56
62
|
MISSING_MSG = '`required_ruby_version` should be specified.'
|
57
63
|
|
58
|
-
# @!method required_ruby_version(node)
|
59
|
-
def_node_search :required_ruby_version
|
60
|
-
(send _ :required_ruby_version=
|
64
|
+
# @!method required_ruby_version?(node)
|
65
|
+
def_node_search :required_ruby_version?, <<~PATTERN
|
66
|
+
(send _ :required_ruby_version= _)
|
61
67
|
PATTERN
|
62
68
|
|
63
69
|
# @!method defined_ruby_version(node)
|
@@ -66,27 +72,28 @@ module RuboCop
|
|
66
72
|
(send (const (const nil? :Gem) :Requirement) :new $(str _))}
|
67
73
|
PATTERN
|
68
74
|
|
69
|
-
# rubocop:disable Metrics/AbcSize
|
70
75
|
def on_new_investigation
|
71
|
-
|
76
|
+
add_global_offense(MISSING_MSG) unless required_ruby_version?(processed_source.ast)
|
77
|
+
end
|
72
78
|
|
73
|
-
|
74
|
-
|
75
|
-
|
79
|
+
def on_send(node)
|
80
|
+
version_def = node.first_argument
|
81
|
+
return if dynamic_version?(version_def)
|
76
82
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
else
|
82
|
-
range = source_range(processed_source.buffer, 1, 0)
|
83
|
-
add_offense(range, message: MISSING_MSG)
|
84
|
-
end
|
83
|
+
ruby_version = extract_ruby_version(defined_ruby_version(version_def))
|
84
|
+
return if ruby_version == target_ruby_version.to_s
|
85
|
+
|
86
|
+
add_offense(version_def, message: not_equal_message(ruby_version, target_ruby_version))
|
85
87
|
end
|
86
|
-
# rubocop:enable Metrics/AbcSize
|
87
88
|
|
88
89
|
private
|
89
90
|
|
91
|
+
def dynamic_version?(node)
|
92
|
+
(node.send_type? && !node.receiver) ||
|
93
|
+
node.variable? ||
|
94
|
+
node.each_descendant(:send, *RuboCop::AST::Node::VARIABLES).any?
|
95
|
+
end
|
96
|
+
|
90
97
|
def extract_ruby_version(required_ruby_version)
|
91
98
|
return unless required_ruby_version
|
92
99
|
|
@@ -26,20 +26,13 @@ module RuboCop
|
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
class RubyVersionGlobalsUsage < Base
|
29
|
+
include GemspecHelp
|
30
|
+
|
29
31
|
MSG = 'Do not use `RUBY_VERSION` in gemspec file.'
|
30
32
|
|
31
33
|
# @!method ruby_version?(node)
|
32
34
|
def_node_matcher :ruby_version?, '(const {cbase nil?} :RUBY_VERSION)'
|
33
35
|
|
34
|
-
# @!method gem_specification?(node)
|
35
|
-
def_node_search :gem_specification?, <<~PATTERN
|
36
|
-
(block
|
37
|
-
(send
|
38
|
-
(const
|
39
|
-
(const {cbase nil?} :Gem) :Specification) :new)
|
40
|
-
...)
|
41
|
-
PATTERN
|
42
|
-
|
43
36
|
def on_const(node)
|
44
37
|
return unless gem_spec_with_ruby_version?(node)
|
45
38
|
|
@@ -49,7 +42,7 @@ module RuboCop
|
|
49
42
|
private
|
50
43
|
|
51
44
|
def gem_spec_with_ruby_version?(node)
|
52
|
-
gem_specification
|
45
|
+
gem_specification(processed_source.ast) && ruby_version?(node)
|
53
46
|
end
|
54
47
|
end
|
55
48
|
end
|
@@ -24,6 +24,11 @@ module RuboCop
|
|
24
24
|
# `SupportedStyle` and unique configuration, there needs to be examples.
|
25
25
|
# Examples must have valid Ruby syntax. Do not use upticks.
|
26
26
|
#
|
27
|
+
# @safety
|
28
|
+
# Delete this section if the cop is not unsafe (`Safe: false` or
|
29
|
+
# `SafeAutoCorrect: false`), or use it to explain how the cop is
|
30
|
+
# unsafe.
|
31
|
+
#
|
27
32
|
# @example EnforcedStyle: bar (default)
|
28
33
|
# # Description of the `bar` style.
|
29
34
|
#
|
@@ -106,9 +111,8 @@ module RuboCop
|
|
106
111
|
'[modify] A configuration for the cop is added into ' \
|
107
112
|
'%<configuration_file_path>s.'
|
108
113
|
|
109
|
-
def initialize(name,
|
114
|
+
def initialize(name, output: $stdout)
|
110
115
|
@badge = Badge.parse(name)
|
111
|
-
@github_user = github_user
|
112
116
|
@output = output
|
113
117
|
return if badge.qualified?
|
114
118
|
|
@@ -142,17 +146,19 @@ module RuboCop
|
|
142
146
|
|
143
147
|
def todo
|
144
148
|
<<~TODO
|
145
|
-
Do
|
146
|
-
1.
|
147
|
-
|
148
|
-
|
149
|
-
|
149
|
+
Do 4 steps:
|
150
|
+
1. Modify the description of #{badge} in config/default.yml
|
151
|
+
2. Implement your new cop in the generated file!
|
152
|
+
3. Commit your new cop with a message such as
|
153
|
+
e.g. "Add new `#{badge}` cop"
|
154
|
+
4. Run `bundle exec rake changelog:new` to generate a changelog entry
|
155
|
+
for your new cop.
|
150
156
|
TODO
|
151
157
|
end
|
152
158
|
|
153
159
|
private
|
154
160
|
|
155
|
-
attr_reader :badge, :
|
161
|
+
attr_reader :badge, :output
|
156
162
|
|
157
163
|
def write_unless_file_exists(path, contents)
|
158
164
|
if File.exist?(path)
|