rubocop 0.76.0 → 0.79.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 +2 -2
- data/config/default.yml +290 -264
- data/lib/rubocop/ast/builder.rb +43 -42
- data/lib/rubocop/ast/node/block_node.rb +2 -0
- data/lib/rubocop/ast/node/def_node.rb +11 -0
- data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
- data/lib/rubocop/ast/node.rb +1 -1
- data/lib/rubocop/ast/traversal.rb +11 -3
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
- data/lib/rubocop/cli/command/base.rb +33 -0
- data/lib/rubocop/cli/command/execute_runner.rb +76 -0
- data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
- data/lib/rubocop/cli/command/show_cops.rb +80 -0
- data/lib/rubocop/cli/command/version.rb +17 -0
- data/lib/rubocop/cli/command.rb +21 -0
- data/lib/rubocop/cli/environment.rb +21 -0
- data/lib/rubocop/cli.rb +11 -230
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_loader.rb +19 -19
- data/lib/rubocop/config_obsoletion.rb +65 -12
- data/lib/rubocop/config_validator.rb +56 -98
- data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
- data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
- data/lib/rubocop/cop/cop.rb +21 -0
- data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
- data/lib/rubocop/cop/generator.rb +3 -4
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +5 -5
- data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
- data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +3 -3
- data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
- data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +10 -6
- data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +5 -5
- data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
- data/lib/rubocop/cop/{metrics → layout}/line_length.rb +40 -110
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +32 -7
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
- data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +2 -2
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
- data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +4 -4
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +16 -1
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -7
- data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
- data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
- data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
- data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +6 -3
- data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
- data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
- data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
- data/lib/rubocop/cop/offense.rb +11 -0
- data/lib/rubocop/cop/registry.rb +7 -2
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/array_join.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +8 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/even_odd.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +3 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +38 -3
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +168 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +4 -207
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +5 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
- data/lib/rubocop/cop/style/next.rb +5 -5
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
- data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
- data/lib/rubocop/cop/style/option_hash.rb +3 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
- data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/redundant_return.rb +2 -8
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
- data/lib/rubocop/cop/team.rb +5 -0
- data/lib/rubocop/formatter/base_formatter.rb +2 -2
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -3
- data/lib/rubocop/formatter/json_formatter.rb +6 -5
- data/lib/rubocop/formatter/tap_formatter.rb +1 -3
- data/lib/rubocop/node_pattern.rb +1 -1
- data/lib/rubocop/options.rb +8 -8
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -0
- data/lib/rubocop/result_cache.rb +23 -7
- data/lib/rubocop/rspec/shared_contexts.rb +5 -0
- data/lib/rubocop/runner.rb +18 -2
- data/lib/rubocop/target_ruby.rb +151 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +38 -22
- metadata +40 -25
- data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
data/lib/rubocop/ast/builder.rb
CHANGED
@@ -15,48 +15,49 @@ module RuboCop
|
|
15
15
|
# root_node = parser.parse(buffer)
|
16
16
|
class Builder < Parser::Builders::Default
|
17
17
|
NODE_MAP = {
|
18
|
-
and:
|
19
|
-
alias:
|
20
|
-
args:
|
21
|
-
array:
|
22
|
-
block:
|
23
|
-
break:
|
24
|
-
case:
|
25
|
-
class:
|
26
|
-
def:
|
27
|
-
defined?:
|
28
|
-
defs:
|
29
|
-
ensure:
|
30
|
-
for:
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
18
|
+
and: AndNode,
|
19
|
+
alias: AliasNode,
|
20
|
+
args: ArgsNode,
|
21
|
+
array: ArrayNode,
|
22
|
+
block: BlockNode,
|
23
|
+
break: BreakNode,
|
24
|
+
case: CaseNode,
|
25
|
+
class: ClassNode,
|
26
|
+
def: DefNode,
|
27
|
+
defined?: DefinedNode,
|
28
|
+
defs: DefNode,
|
29
|
+
ensure: EnsureNode,
|
30
|
+
for: ForNode,
|
31
|
+
forward_args: ForwardArgsNode,
|
32
|
+
float: FloatNode,
|
33
|
+
hash: HashNode,
|
34
|
+
if: IfNode,
|
35
|
+
int: IntNode,
|
36
|
+
irange: RangeNode,
|
37
|
+
erange: RangeNode,
|
38
|
+
kwsplat: KeywordSplatNode,
|
39
|
+
module: ModuleNode,
|
40
|
+
or: OrNode,
|
41
|
+
pair: PairNode,
|
42
|
+
regexp: RegexpNode,
|
43
|
+
resbody: ResbodyNode,
|
44
|
+
retry: RetryNode,
|
45
|
+
return: ReturnNode,
|
46
|
+
csend: SendNode,
|
47
|
+
send: SendNode,
|
48
|
+
str: StrNode,
|
49
|
+
dstr: StrNode,
|
50
|
+
xstr: StrNode,
|
51
|
+
sclass: SelfClassNode,
|
52
|
+
super: SuperNode,
|
53
|
+
zsuper: SuperNode,
|
54
|
+
sym: SymbolNode,
|
55
|
+
until: UntilNode,
|
56
|
+
until_post: UntilNode,
|
57
|
+
when: WhenNode,
|
58
|
+
while: WhileNode,
|
59
|
+
while_post: WhileNode,
|
60
|
+
yield: YieldNode
|
60
61
|
}.freeze
|
61
62
|
|
62
63
|
# Generates {Node} from the given information.
|
@@ -9,6 +9,8 @@ module RuboCop
|
|
9
9
|
# A `block` node is essentially a method send with a block. Parser nests
|
10
10
|
# the `send` node inside the `block` node.
|
11
11
|
class BlockNode < Node
|
12
|
+
include MethodIdentifierPredicates
|
13
|
+
|
12
14
|
VOID_CONTEXT_METHODS = %i[each tap].freeze
|
13
15
|
|
14
16
|
# The `send` node associated with this block.
|
@@ -16,6 +16,17 @@ module RuboCop
|
|
16
16
|
method?(:initialize) || assignment_method?
|
17
17
|
end
|
18
18
|
|
19
|
+
# Checks whether this method definition node forwards its arguments
|
20
|
+
# as per the feature added in Ruby 2.7.
|
21
|
+
#
|
22
|
+
# @note This is written in a way that may support lead arguments
|
23
|
+
# which are rumored to be added in a later version of Ruby.
|
24
|
+
#
|
25
|
+
# @return [Boolean] whether the `def` node uses argument forwarding
|
26
|
+
def argument_forwarding?
|
27
|
+
arguments.any?(&:forward_args_type?)
|
28
|
+
end
|
29
|
+
|
19
30
|
# The name of the defined method as a symbol.
|
20
31
|
#
|
21
32
|
# @return [Symbol] the name of the defined method
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `forward-args` nodes. This will be used in place
|
6
|
+
# of a plain node when the builder constructs the AST, making its methods
|
7
|
+
# available to all `forward-args` nodes within RuboCop.
|
8
|
+
class ForwardArgsNode < Node
|
9
|
+
include CollectionNode
|
10
|
+
|
11
|
+
# Node wraps itself in an array to be compatible with other
|
12
|
+
# enumerable argument types.
|
13
|
+
def to_a
|
14
|
+
[self]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/rubocop/ast/node.rb
CHANGED
@@ -624,7 +624,7 @@ module RuboCop
|
|
624
624
|
end
|
625
625
|
|
626
626
|
def parent_module_name_for_block(ancestor)
|
627
|
-
if ancestor.
|
627
|
+
if ancestor.method?(:class_eval)
|
628
628
|
# `class_eval` with no receiver applies to whatever module or class
|
629
629
|
# we are currently in
|
630
630
|
return unless (receiver = ancestor.receiver)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ModuleLength
|
3
4
|
module RuboCop
|
4
5
|
module AST
|
5
6
|
# Provides methods for traversing an AST.
|
@@ -18,15 +19,21 @@ module RuboCop
|
|
18
19
|
rational str sym regopt self lvar
|
19
20
|
ivar cvar gvar nth_ref back_ref cbase
|
20
21
|
arg restarg blockarg shadowarg
|
21
|
-
kwrestarg zsuper lambda redo retry
|
22
|
+
kwrestarg zsuper lambda redo retry
|
23
|
+
forward_args forwarded_args
|
24
|
+
match_var match_nil_pattern].freeze
|
22
25
|
ONE_CHILD_NODE = %i[splat kwsplat block_pass not break next
|
23
26
|
preexe postexe match_current_line defined?
|
24
|
-
arg_expr
|
27
|
+
arg_expr pin match_rest if_guard unless_guard
|
28
|
+
match_with_trailing_comma].freeze
|
25
29
|
MANY_CHILD_NODES = %i[dstr dsym xstr regexp array hash pair
|
26
30
|
mlhs masgn or_asgn and_asgn
|
27
31
|
undef alias args super yield or and
|
28
32
|
while_post until_post iflipflop eflipflop
|
29
|
-
match_with_lvasgn begin kwbegin return
|
33
|
+
match_with_lvasgn begin kwbegin return
|
34
|
+
in_match case_match in_pattern match_alt
|
35
|
+
match_as array_pattern array_pattern_with_tail
|
36
|
+
hash_pattern const_pattern].freeze
|
30
37
|
SECOND_CHILD_ONLY = %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
|
31
38
|
kwoptarg].freeze
|
32
39
|
|
@@ -181,3 +188,4 @@ module RuboCop
|
|
181
188
|
end
|
182
189
|
end
|
183
190
|
end
|
191
|
+
# rubocop:enable Metrics/ModuleLength
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# Generate a configuration file acting as a TODO list.
|
7
|
+
class AutoGenerateConfig < Base
|
8
|
+
self.command_name = :auto_gen_config
|
9
|
+
|
10
|
+
PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop'
|
11
|
+
PHASE_2 = 'Phase 2 of 2: run all cops'
|
12
|
+
|
13
|
+
PHASE_1_OVERRIDDEN =
|
14
|
+
'(skipped because the default Layout/LineLength:Max is overridden)'
|
15
|
+
PHASE_1_DISABLED =
|
16
|
+
'(skipped because Layout/LineLength is disabled)'
|
17
|
+
|
18
|
+
def run
|
19
|
+
add_formatter
|
20
|
+
reset_config_and_auto_gen_file
|
21
|
+
line_length_contents = maybe_run_line_length_cop
|
22
|
+
run_all_cops(line_length_contents)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def maybe_run_line_length_cop
|
28
|
+
if !line_length_enabled?(@config_store.for(Dir.pwd))
|
29
|
+
skip_line_length_cop(PHASE_1_DISABLED)
|
30
|
+
elsif !same_max_line_length?(
|
31
|
+
@config_store.for(Dir.pwd), ConfigLoader.default_configuration
|
32
|
+
)
|
33
|
+
skip_line_length_cop(PHASE_1_OVERRIDDEN)
|
34
|
+
else
|
35
|
+
run_line_length_cop
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def skip_line_length_cop(reason)
|
40
|
+
puts Rainbow("#{PHASE_1} #{reason}").yellow
|
41
|
+
''
|
42
|
+
end
|
43
|
+
|
44
|
+
def line_length_enabled?(config)
|
45
|
+
line_length_cop(config)['Enabled']
|
46
|
+
end
|
47
|
+
|
48
|
+
def same_max_line_length?(config1, config2)
|
49
|
+
max_line_length(config1) == max_line_length(config2)
|
50
|
+
end
|
51
|
+
|
52
|
+
def max_line_length(config)
|
53
|
+
line_length_cop(config)['Max']
|
54
|
+
end
|
55
|
+
|
56
|
+
def line_length_cop(config)
|
57
|
+
config.for_cop('Layout/LineLength')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Do an initial run with only Layout/LineLength so that cops that
|
61
|
+
# depend on Layout/LineLength:Max get the correct value for that
|
62
|
+
# parameter.
|
63
|
+
def run_line_length_cop
|
64
|
+
puts Rainbow(PHASE_1).yellow
|
65
|
+
@options[:only] = ['Layout/LineLength']
|
66
|
+
execute_runner
|
67
|
+
@options.delete(:only)
|
68
|
+
@config_store = ConfigStore.new
|
69
|
+
# Save the todo configuration of the LineLength cop.
|
70
|
+
IO.read(ConfigLoader::AUTO_GENERATED_FILE)
|
71
|
+
.lines
|
72
|
+
.drop_while { |line| line.start_with?('#') }
|
73
|
+
.join
|
74
|
+
end
|
75
|
+
|
76
|
+
def run_all_cops(line_length_contents)
|
77
|
+
puts Rainbow(PHASE_2).yellow
|
78
|
+
result = execute_runner
|
79
|
+
# This run was made with the current maximum length allowed, so append
|
80
|
+
# the saved setting for LineLength.
|
81
|
+
File.open(ConfigLoader::AUTO_GENERATED_FILE, 'a') do |f|
|
82
|
+
f.write(line_length_contents)
|
83
|
+
end
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
def reset_config_and_auto_gen_file
|
88
|
+
@config_store = ConfigStore.new
|
89
|
+
@config_store.options_config = @options[:config] if @options[:config]
|
90
|
+
File.open(ConfigLoader::AUTO_GENERATED_FILE, 'w') {}
|
91
|
+
ConfigLoader.add_inheritance_from_auto_generated_file
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_formatter
|
95
|
+
@options[:formatters] << [Formatter::DisabledConfigFormatter,
|
96
|
+
ConfigLoader::AUTO_GENERATED_FILE]
|
97
|
+
end
|
98
|
+
|
99
|
+
def execute_runner
|
100
|
+
Environment.new(@options, @config_store, @paths).run(:execute_runner)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# A subcommand in the CLI.
|
7
|
+
class Base
|
8
|
+
attr_reader :env
|
9
|
+
|
10
|
+
@subclasses = []
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_accessor :command_name
|
14
|
+
|
15
|
+
def inherited(subclass)
|
16
|
+
@subclasses << subclass
|
17
|
+
end
|
18
|
+
|
19
|
+
def by_command_name(name)
|
20
|
+
@subclasses.detect { |s| s.command_name == name }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(env)
|
25
|
+
@env = env
|
26
|
+
@options = env.options
|
27
|
+
@config_store = env.config_store
|
28
|
+
@paths = env.paths
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# Run all the selected cops and report the result.
|
7
|
+
class ExecuteRunner < Base
|
8
|
+
include Formatter::TextUtil
|
9
|
+
|
10
|
+
self.command_name = :execute_runner
|
11
|
+
|
12
|
+
def run
|
13
|
+
execute_runner(@paths)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def execute_runner(paths)
|
19
|
+
runner = Runner.new(@options, @config_store)
|
20
|
+
|
21
|
+
all_passed = runner.run(paths)
|
22
|
+
display_warning_summary(runner.warnings)
|
23
|
+
display_error_summary(runner.errors)
|
24
|
+
maybe_print_corrected_source
|
25
|
+
|
26
|
+
all_pass_or_excluded = all_passed || @options[:auto_gen_config]
|
27
|
+
|
28
|
+
if runner.aborting?
|
29
|
+
STATUS_INTERRUPTED
|
30
|
+
elsif all_pass_or_excluded && runner.errors.empty?
|
31
|
+
STATUS_SUCCESS
|
32
|
+
else
|
33
|
+
STATUS_OFFENSES
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def display_warning_summary(warnings)
|
38
|
+
return if warnings.empty?
|
39
|
+
|
40
|
+
warn Rainbow("\n#{pluralize(warnings.size, 'warning')}:").yellow
|
41
|
+
|
42
|
+
warnings.each { |warning| warn warning }
|
43
|
+
end
|
44
|
+
|
45
|
+
def display_error_summary(errors)
|
46
|
+
return if errors.empty?
|
47
|
+
|
48
|
+
warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red
|
49
|
+
|
50
|
+
errors.each { |error| warn error }
|
51
|
+
|
52
|
+
warn <<~WARNING
|
53
|
+
Errors are usually caused by RuboCop bugs.
|
54
|
+
Please, report your problems to RuboCop's issue tracker.
|
55
|
+
#{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}
|
56
|
+
|
57
|
+
Mention the following information in the issue report:
|
58
|
+
#{RuboCop::Version.version(true)}
|
59
|
+
WARNING
|
60
|
+
end
|
61
|
+
|
62
|
+
def maybe_print_corrected_source
|
63
|
+
# If we are asked to autocorrect source code read from stdin, the only
|
64
|
+
# reasonable place to write it is to stdout
|
65
|
+
# Unfortunately, we also write other information to stdout
|
66
|
+
# So a delimiter is needed for tools to easily identify where the
|
67
|
+
# autocorrected source begins
|
68
|
+
return unless @options[:stdin] && @options[:auto_correct]
|
69
|
+
|
70
|
+
puts '=' * 20
|
71
|
+
print @options[:stdin]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# Generate a .rubocop.yml file in the current directory.
|
7
|
+
class InitDotfile < Base
|
8
|
+
DOTFILE = ConfigLoader::DOTFILE
|
9
|
+
|
10
|
+
self.command_name = :init
|
11
|
+
|
12
|
+
def run
|
13
|
+
path = File.expand_path(DOTFILE)
|
14
|
+
|
15
|
+
if File.exist?(DOTFILE)
|
16
|
+
warn Rainbow("#{DOTFILE} already exists at #{path}").red
|
17
|
+
|
18
|
+
STATUS_ERROR
|
19
|
+
else
|
20
|
+
description = <<~DESC
|
21
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
22
|
+
# configuration file. It makes it possible to enable/disable
|
23
|
+
# certain cops (checks) and to alter their behavior if they accept
|
24
|
+
# any parameters. The file can be placed either in your home
|
25
|
+
# directory or in some project directory.
|
26
|
+
#
|
27
|
+
# RuboCop will start looking for the configuration file in the directory
|
28
|
+
# where the inspected file is and continue its way up to the root directory.
|
29
|
+
#
|
30
|
+
# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
|
31
|
+
DESC
|
32
|
+
|
33
|
+
File.open(DOTFILE, 'w') do |f|
|
34
|
+
f.write(description)
|
35
|
+
end
|
36
|
+
|
37
|
+
puts "Writing new #{DOTFILE} to #{path}"
|
38
|
+
|
39
|
+
STATUS_SUCCESS
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# Shows the given cops, or all cops by default, and their configurations
|
7
|
+
# for the current directory.
|
8
|
+
class ShowCops < Base
|
9
|
+
self.command_name = :show_cops
|
10
|
+
|
11
|
+
def initialize(env)
|
12
|
+
super
|
13
|
+
|
14
|
+
# Load the configs so the require()s are done for custom cops
|
15
|
+
@config = @config_store.for(Dir.pwd)
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
print_available_cops
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def print_available_cops
|
25
|
+
registry = Cop::Cop.registry
|
26
|
+
show_all = @options[:show_cops].empty?
|
27
|
+
|
28
|
+
if show_all
|
29
|
+
puts "# Available cops (#{registry.length}) " \
|
30
|
+
"+ config for #{Dir.pwd}: "
|
31
|
+
end
|
32
|
+
|
33
|
+
registry.departments.sort!.each do |department|
|
34
|
+
print_cops_of_department(registry, department, show_all)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_cops_of_department(registry, department, show_all)
|
39
|
+
selected_cops = if show_all
|
40
|
+
cops_of_department(registry, department)
|
41
|
+
else
|
42
|
+
selected_cops_of_department(registry, department)
|
43
|
+
end
|
44
|
+
|
45
|
+
if show_all
|
46
|
+
puts "# Department '#{department}' (#{selected_cops.length}):"
|
47
|
+
end
|
48
|
+
|
49
|
+
print_cop_details(selected_cops)
|
50
|
+
end
|
51
|
+
|
52
|
+
def print_cop_details(cops)
|
53
|
+
cops.each do |cop|
|
54
|
+
if cop.new(@config).support_autocorrect?
|
55
|
+
puts '# Supports --auto-correct'
|
56
|
+
end
|
57
|
+
puts "#{cop.cop_name}:"
|
58
|
+
puts config_lines(cop)
|
59
|
+
puts
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def selected_cops_of_department(cops, department)
|
64
|
+
cops_of_department(cops, department).select do |cop|
|
65
|
+
@options[:show_cops].include?(cop.cop_name)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def cops_of_department(cops, department)
|
70
|
+
cops.with_department(department).sort!
|
71
|
+
end
|
72
|
+
|
73
|
+
def config_lines(cop)
|
74
|
+
cnf = @config.for_cop(cop)
|
75
|
+
cnf.to_yaml.lines.to_a.drop(1).map { |line| ' ' + line }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
module Command
|
6
|
+
# Display version.
|
7
|
+
class Version < Base
|
8
|
+
self.command_name = :version
|
9
|
+
|
10
|
+
def run
|
11
|
+
puts RuboCop::Version.version(false) if @options[:version]
|
12
|
+
puts RuboCop::Version.version(true) if @options[:verbose_version]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
# Home of subcommands in the CLI.
|
6
|
+
module Command
|
7
|
+
class << self
|
8
|
+
# Find the command with a given name and run it in an environment.
|
9
|
+
def run(env, name)
|
10
|
+
class_for(name).new(env).run
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def class_for(name)
|
16
|
+
Base.by_command_name(name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
class CLI
|
5
|
+
# Execution environment for a CLI command.
|
6
|
+
class Environment
|
7
|
+
attr_reader :options, :config_store, :paths
|
8
|
+
|
9
|
+
def initialize(options, config_store, paths)
|
10
|
+
@options = options
|
11
|
+
@config_store = config_store
|
12
|
+
@paths = paths
|
13
|
+
end
|
14
|
+
|
15
|
+
# Run a command in this environment.
|
16
|
+
def run(name)
|
17
|
+
Command.run(self, name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|