rubocop 1.3.1 → 1.4.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 +18 -2
- data/lib/rubocop.rb +1 -0
- data/lib/rubocop/cli/command/execute_runner.rb +26 -11
- data/lib/rubocop/config_regeneration.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +77 -7
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +7 -4
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +13 -4
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +1 -3
- data/lib/rubocop/cop/style/documentation.rb +12 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/redundant_argument.rb +73 -0
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +21 -6
- data/lib/rubocop/options.rb +5 -0
- data/lib/rubocop/rake_task.rb +2 -2
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +4 -8
- data/assets/logo.png +0 -0
- data/assets/output.html.erb +0 -261
- data/bin/console +0 -10
- data/bin/rubocop-profile +0 -32
- data/bin/setup +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 840dbd224c26defdcf3fe6d5c48f6e495f4288141a38f5e79de74552a0a1d9d8
|
4
|
+
data.tar.gz: 381215eaceb9e62bdb1ba0df04880b4b8c702bfd4e11df78d0683b539451fb3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3a563aeb426e7ae74dcc9dbc28d153e3b672d0abcae22bea62ff6077bb2bb7eff78cdacf3f4f9a384d09ddc417744135c3a47536145052bbbca985008514b5e
|
7
|
+
data.tar.gz: 0c832cf607fa6fe0bd5513dc82f315638285f225c7456a2a884830cd173bb740ca741b4ea2279e908b8a00ecb94e60f40c7b2064841efa2152f50ce6a40477a2
|
data/README.md
CHANGED
@@ -51,7 +51,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
51
51
|
in your `Gemfile`:
|
52
52
|
|
53
53
|
```rb
|
54
|
-
gem 'rubocop', '~> 1.
|
54
|
+
gem 'rubocop', '~> 1.4', require: false
|
55
55
|
```
|
56
56
|
|
57
57
|
See [versioning](https://docs.rubocop.org/rubocop/1.0/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -463,6 +463,10 @@ Layout/EmptyLineBetweenDefs:
|
|
463
463
|
StyleGuide: '#empty-lines-between-methods'
|
464
464
|
Enabled: true
|
465
465
|
VersionAdded: '0.49'
|
466
|
+
VersionChanged: '1.4'
|
467
|
+
EmptyLineBetweenMethodDefs: true
|
468
|
+
EmptyLineBetweenClassDefs: true
|
469
|
+
EmptyLineBetweenModuleDefs: true
|
466
470
|
# If `true`, this parameter means that single line method definitions don't
|
467
471
|
# need an empty line between them.
|
468
472
|
AllowAdjacentOneLineDefs: false
|
@@ -891,8 +895,8 @@ Layout/LineLength:
|
|
891
895
|
StyleGuide: '#max-line-length'
|
892
896
|
Enabled: true
|
893
897
|
VersionAdded: '0.25'
|
894
|
-
VersionChanged: '1.
|
895
|
-
AutoCorrect:
|
898
|
+
VersionChanged: '1.4'
|
899
|
+
AutoCorrect: true
|
896
900
|
Max: 120
|
897
901
|
# To make it possible to copy or click on URIs in the code, we allow lines
|
898
902
|
# containing a URI to be longer than Max.
|
@@ -1684,6 +1688,7 @@ Lint/MissingSuper:
|
|
1684
1688
|
without calls to `super`'.
|
1685
1689
|
Enabled: true
|
1686
1690
|
VersionAdded: '0.89'
|
1691
|
+
VersionChanged: '1.4'
|
1687
1692
|
|
1688
1693
|
Lint/MixedRegexpCaptureTypes:
|
1689
1694
|
Description: 'Do not mix named captures and numbered captures in a Regexp literal.'
|
@@ -3976,6 +3981,17 @@ Style/RandomWithOffset:
|
|
3976
3981
|
Enabled: true
|
3977
3982
|
VersionAdded: '0.52'
|
3978
3983
|
|
3984
|
+
Style/RedundantArgument:
|
3985
|
+
Description: 'Check for a redundant argument passed to certain methods.'
|
3986
|
+
Enabled: pending
|
3987
|
+
Safe: false
|
3988
|
+
VersionAdded: '1.4'
|
3989
|
+
Methods:
|
3990
|
+
# Array#join
|
3991
|
+
join: ''
|
3992
|
+
# String#split
|
3993
|
+
split: ' '
|
3994
|
+
|
3979
3995
|
Style/RedundantAssignment:
|
3980
3996
|
Description: 'Checks for redundant assignment before returning.'
|
3981
3997
|
Enabled: true
|
data/lib/rubocop.rb
CHANGED
@@ -529,6 +529,7 @@ require_relative 'rubocop/cop/style/preferred_hash_methods'
|
|
529
529
|
require_relative 'rubocop/cop/style/proc'
|
530
530
|
require_relative 'rubocop/cop/style/raise_args'
|
531
531
|
require_relative 'rubocop/cop/style/random_with_offset'
|
532
|
+
require_relative 'rubocop/cop/style/redundant_argument'
|
532
533
|
require_relative 'rubocop/cop/style/redundant_begin'
|
533
534
|
require_relative 'rubocop/cop/style/redundant_capital_w'
|
534
535
|
require_relative 'rubocop/cop/style/redundant_condition'
|
@@ -22,12 +22,13 @@ module RuboCop
|
|
22
22
|
def execute_runner(paths)
|
23
23
|
runner = Runner.new(@options, @config_store)
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
all_pass_or_excluded = with_redirect do
|
26
|
+
all_passed = runner.run(paths)
|
27
|
+
display_summary(runner)
|
28
|
+
all_passed || @options[:auto_gen_config]
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
+
maybe_print_corrected_source
|
31
32
|
|
32
33
|
if runner.aborting?
|
33
34
|
STATUS_INTERRUPTED
|
@@ -38,6 +39,25 @@ module RuboCop
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
42
|
+
def with_redirect
|
43
|
+
if @options[:stderr]
|
44
|
+
orig_stdout = $stdout.dup
|
45
|
+
$stdout.reopen($stderr)
|
46
|
+
|
47
|
+
result = yield
|
48
|
+
|
49
|
+
$stdout.reopen(orig_stdout)
|
50
|
+
result
|
51
|
+
else
|
52
|
+
yield
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def display_summary(runner)
|
57
|
+
display_warning_summary(runner.warnings)
|
58
|
+
display_error_summary(runner.errors)
|
59
|
+
end
|
60
|
+
|
41
61
|
def display_warning_summary(warnings)
|
42
62
|
return if warnings.empty?
|
43
63
|
|
@@ -69,14 +89,9 @@ module RuboCop
|
|
69
89
|
# See: https://github.com/rubocop-hq/rubocop/issues/8673
|
70
90
|
return if INTEGRATION_FORMATTERS.include?(@options[:format])
|
71
91
|
|
72
|
-
# If we are asked to autocorrect source code read from stdin, the only
|
73
|
-
# reasonable place to write it is to stdout
|
74
|
-
# Unfortunately, we also write other information to stdout
|
75
|
-
# So a delimiter is needed for tools to easily identify where the
|
76
|
-
# autocorrected source begins
|
77
92
|
return unless @options[:stdin] && @options[:auto_correct]
|
78
93
|
|
79
|
-
puts '=' * 20
|
94
|
+
(@options[:stderr] ? $stderr : $stdout).puts '=' * 20
|
80
95
|
print @options[:stdin]
|
81
96
|
end
|
82
97
|
end
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
48
48
|
def autocorrect_multiline_words(node, escape, delimiters)
|
49
49
|
contents = process_multiline_words(node, escape, delimiters)
|
50
50
|
contents << end_content(node.source)
|
51
|
-
contents.join
|
51
|
+
contents.join
|
52
52
|
end
|
53
53
|
|
54
54
|
def autocorrect_words(node, escape, delimiters)
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
38
38
|
|
39
39
|
def assertions_using_described_class_msg
|
40
40
|
described_class_msg(processed_source.ast).reject do |node|
|
41
|
-
node.ancestors.any?
|
41
|
+
node.ancestors.any? { |ancestor| rspec_expectation_on_msg?(ancestor) }
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -13,7 +13,8 @@ module RuboCop
|
|
13
13
|
# `AllowAdjacentOneLineDefs` configures whether adjacent
|
14
14
|
# one-line method definitions are considered an offense.
|
15
15
|
#
|
16
|
-
# @example
|
16
|
+
# @example EmptyLineBetweenMethodDefs: true (default)
|
17
|
+
# # checks for empty lines between method definitions.
|
17
18
|
#
|
18
19
|
# # bad
|
19
20
|
# def a
|
@@ -29,11 +30,57 @@ module RuboCop
|
|
29
30
|
#
|
30
31
|
# def b
|
31
32
|
# end
|
33
|
+
#
|
34
|
+
# @example EmptyLineBetweenClassDefs: true (default)
|
35
|
+
# # checks for empty lines between class definitions.
|
36
|
+
#
|
37
|
+
# # bad
|
38
|
+
# class A
|
39
|
+
# end
|
40
|
+
# class B
|
41
|
+
# end
|
42
|
+
# def b
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# class A
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# class B
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# def b
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# @example EmptyLineBetweenModuleDefs: true (default)
|
58
|
+
# # checks for empty lines between module definitions.
|
59
|
+
#
|
60
|
+
# # bad
|
61
|
+
# module A
|
62
|
+
# end
|
63
|
+
# module B
|
64
|
+
# end
|
65
|
+
# def b
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
#
|
70
|
+
# # good
|
71
|
+
# module A
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# module B
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# def b
|
78
|
+
# end
|
32
79
|
class EmptyLineBetweenDefs < Base
|
33
80
|
include RangeHelp
|
34
81
|
extend AutoCorrector
|
35
82
|
|
36
|
-
MSG = 'Use empty lines between
|
83
|
+
MSG = 'Use empty lines between %<type>s definitions.'
|
37
84
|
|
38
85
|
def self.autocorrect_incompatible_with
|
39
86
|
[Layout::EmptyLines]
|
@@ -47,7 +94,7 @@ module RuboCop
|
|
47
94
|
def on_begin(node)
|
48
95
|
node.children.each_cons(2) do |prev, n|
|
49
96
|
nodes = [prev, n]
|
50
|
-
check_defs(nodes) if nodes.all?(
|
97
|
+
check_defs(nodes) if nodes.all? { |def_candidate| candidate?(def_candidate) }
|
51
98
|
end
|
52
99
|
end
|
53
100
|
|
@@ -57,8 +104,9 @@ module RuboCop
|
|
57
104
|
return if nodes.all?(&:single_line?) &&
|
58
105
|
cop_config['AllowAdjacentOneLineDefs']
|
59
106
|
|
60
|
-
|
61
|
-
|
107
|
+
correction_node = nodes.last
|
108
|
+
location = correction_node.loc.keyword.join(correction_node.loc.name)
|
109
|
+
add_offense(location, message: message(correction_node)) do |corrector|
|
62
110
|
autocorrect(corrector, *nodes)
|
63
111
|
end
|
64
112
|
end
|
@@ -83,10 +131,32 @@ module RuboCop
|
|
83
131
|
|
84
132
|
private
|
85
133
|
|
86
|
-
def
|
134
|
+
def candidate?(node)
|
87
135
|
return unless node
|
88
136
|
|
89
|
-
node
|
137
|
+
method_candidate?(node) || class_candidate?(node) || module_candidate?(node)
|
138
|
+
end
|
139
|
+
|
140
|
+
def method_candidate?(node)
|
141
|
+
cop_config['EmptyLineBetweenMethodDefs'] && (node.def_type? || node.defs_type?)
|
142
|
+
end
|
143
|
+
|
144
|
+
def class_candidate?(node)
|
145
|
+
cop_config['EmptyLineBetweenClassDefs'] && node.class_type?
|
146
|
+
end
|
147
|
+
|
148
|
+
def module_candidate?(node)
|
149
|
+
cop_config['EmptyLineBetweenModuleDefs'] && node.module_type?
|
150
|
+
end
|
151
|
+
|
152
|
+
def message(node)
|
153
|
+
type = case node.type
|
154
|
+
when :def, :defs
|
155
|
+
:method
|
156
|
+
else
|
157
|
+
node.type
|
158
|
+
end
|
159
|
+
format(MSG, type: type)
|
90
160
|
end
|
91
161
|
|
92
162
|
def multiple_blank_lines_groups?(first_def_node, second_def_node)
|
@@ -53,7 +53,8 @@ module RuboCop
|
|
53
53
|
def find_offense_node(node, regexp_receiver)
|
54
54
|
return node unless node.parent
|
55
55
|
|
56
|
-
if node.parent.send_type?
|
56
|
+
if (node.parent.send_type? && node.receiver) ||
|
57
|
+
method_chain_to_regexp_receiver?(node, regexp_receiver)
|
57
58
|
node = find_offense_node(node.parent, regexp_receiver)
|
58
59
|
end
|
59
60
|
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
def autocorrected_value_for_array(node)
|
96
96
|
return node.source.gsub('"', '\"') unless node.percent_literal?
|
97
97
|
|
98
|
-
contents_range(node).source.split
|
98
|
+
contents_range(node).source.split.to_s.gsub('"', '\"')
|
99
99
|
end
|
100
100
|
|
101
101
|
# Does node print its own source when converted to a string?
|
@@ -6,6 +6,11 @@ module RuboCop
|
|
6
6
|
# This cop checks for the presence of constructors and lifecycle callbacks
|
7
7
|
# without calls to `super`.
|
8
8
|
#
|
9
|
+
# This cop does not consider `method_missing` (and `respond_to_missing?`)
|
10
|
+
# because in some cases it makes sense to overtake what is considered a
|
11
|
+
# missing method. In other cases, the theoretical ideal handling could be
|
12
|
+
# challenging or verbose for no actual gain.
|
13
|
+
#
|
9
14
|
# @example
|
10
15
|
# # bad
|
11
16
|
# class Employee < Person
|
@@ -43,15 +48,13 @@ module RuboCop
|
|
43
48
|
|
44
49
|
STATELESS_CLASSES = %w[BasicObject Object].freeze
|
45
50
|
|
46
|
-
OBJECT_LIFECYCLE_CALLBACKS = %i[method_missing respond_to_missing?].freeze
|
47
51
|
CLASS_LIFECYCLE_CALLBACKS = %i[inherited].freeze
|
48
52
|
METHOD_LIFECYCLE_CALLBACKS = %i[method_added method_removed method_undefined
|
49
53
|
singleton_method_added singleton_method_removed
|
50
54
|
singleton_method_undefined].freeze
|
51
55
|
|
52
|
-
CALLBACKS = (
|
53
|
-
|
54
|
-
METHOD_LIFECYCLE_CALLBACKS).to_set.freeze
|
56
|
+
CALLBACKS = (CLASS_LIFECYCLE_CALLBACKS +
|
57
|
+
METHOD_LIFECYCLE_CALLBACKS).to_set.freeze
|
55
58
|
|
56
59
|
def on_def(node)
|
57
60
|
return unless offender?(node)
|
@@ -54,6 +54,9 @@ module RuboCop
|
|
54
54
|
# value
|
55
55
|
# end
|
56
56
|
#
|
57
|
+
# # good, recursive
|
58
|
+
# keys.reduce(self) { |result, key| result[key] }
|
59
|
+
#
|
57
60
|
# # ignored as the return value cannot be determined
|
58
61
|
# enum.reduce do |acc, el|
|
59
62
|
# x = foo(acc, el)
|
@@ -131,7 +134,7 @@ module RuboCop
|
|
131
134
|
element_name = block_arg_name(block_node, 1)
|
132
135
|
message_opts = { method: block_node.method_name, accum: accumulator_name }
|
133
136
|
|
134
|
-
if (node = returned_accumulator_index(return_values, accumulator_name))
|
137
|
+
if (node = returned_accumulator_index(return_values, accumulator_name, element_name))
|
135
138
|
add_offense(node, message: format(MSG_INDEX, message_opts))
|
136
139
|
elsif potential_offense?(return_values, block_node.body, element_name, accumulator_name)
|
137
140
|
return_values.each do |return_val|
|
@@ -146,11 +149,17 @@ module RuboCop
|
|
146
149
|
node.arguments[index].node_parts[0]
|
147
150
|
end
|
148
151
|
|
149
|
-
# Look for an index of the accumulator being returned
|
152
|
+
# Look for an index of the accumulator being returned, except where the index
|
153
|
+
# is the element.
|
150
154
|
# This is always an offense, in order to try to catch potential exceptions
|
151
155
|
# due to type mismatches
|
152
|
-
def returned_accumulator_index(return_values, accumulator_name)
|
153
|
-
return_values.detect
|
156
|
+
def returned_accumulator_index(return_values, accumulator_name, element_name)
|
157
|
+
return_values.detect do |val|
|
158
|
+
next unless accumulator_index?(val, accumulator_name)
|
159
|
+
next true if val.method?(:[]=)
|
160
|
+
|
161
|
+
val.arguments.none? { |arg| lvar_used?(arg, element_name) }
|
162
|
+
end
|
154
163
|
end
|
155
164
|
|
156
165
|
def potential_offense?(return_values, block_body, element_name, accumulator_name)
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
|
37
37
|
def on_def(node)
|
38
38
|
excluded_methods = cop_config['ExcludedMethods']
|
39
|
-
return if excluded_methods.
|
39
|
+
return if excluded_methods.any? { |m| m.match? String(node.method_name) }
|
40
40
|
|
41
41
|
check_code_length(node)
|
42
42
|
end
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
31
31
|
# b c { block }. <-- b is indented relative to a
|
32
32
|
# d <-- d is indented relative to a
|
33
33
|
def left_hand_side(lhs)
|
34
|
-
lhs = lhs.parent while lhs.parent&.send_type?
|
34
|
+
lhs = lhs.parent while lhs.parent&.send_type? && lhs.parent.loc.dot
|
35
35
|
lhs
|
36
36
|
end
|
37
37
|
|
@@ -16,9 +16,7 @@ module RuboCop
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def find_visibility_start(node)
|
19
|
-
node.left_siblings
|
20
|
-
.reverse
|
21
|
-
.find(&method(:visibility_block?))
|
19
|
+
node.left_siblings.reverse.find { |sibling| visibility_block?(sibling) }
|
22
20
|
end
|
23
21
|
|
24
22
|
# Navigate to find the last protected method
|
@@ -55,6 +55,11 @@ module RuboCop
|
|
55
55
|
# Public = Class.new
|
56
56
|
# end
|
57
57
|
#
|
58
|
+
# # Macro calls
|
59
|
+
# module Namespace
|
60
|
+
# extend Foo
|
61
|
+
# end
|
62
|
+
#
|
58
63
|
class Documentation < Base
|
59
64
|
include DocumentationComment
|
60
65
|
|
@@ -83,15 +88,21 @@ module RuboCop
|
|
83
88
|
return if documentation_comment?(node) || nodoc_comment?(node)
|
84
89
|
return if compact_namespace?(node) &&
|
85
90
|
nodoc_comment?(outer_module(node).first)
|
91
|
+
return if macro_only?(body)
|
86
92
|
|
87
93
|
add_offense(node.loc.keyword, message: format(MSG, type: type))
|
88
94
|
end
|
89
95
|
|
96
|
+
def macro_only?(body)
|
97
|
+
body.respond_to?(:macro?) && body.macro? ||
|
98
|
+
body.respond_to?(:children) && body.children&.all? { |child| macro_only?(child) }
|
99
|
+
end
|
100
|
+
|
90
101
|
def namespace?(node)
|
91
102
|
return false unless node
|
92
103
|
|
93
104
|
if node.begin_type?
|
94
|
-
node.children.all?
|
105
|
+
node.children.all? { |child| constant_declaration?(child) }
|
95
106
|
else
|
96
107
|
constant_definition?(node)
|
97
108
|
end
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
parent &&
|
75
75
|
(logical_operator?(parent) ||
|
76
76
|
parent.send_type? &&
|
77
|
-
parent.arguments.any?
|
77
|
+
parent.arguments.any? { |argument| logical_operator?(argument) })
|
78
78
|
end
|
79
79
|
|
80
80
|
def call_in_optional_arguments?(node)
|
@@ -110,7 +110,7 @@ module RuboCop
|
|
110
110
|
def hash_literal_in_arguments?(node)
|
111
111
|
node.arguments.any? do |n|
|
112
112
|
hash_literal?(n) ||
|
113
|
-
n.send_type? && node.descendants.any?
|
113
|
+
n.send_type? && node.descendants.any? { |descendant| hash_literal?(descendant) }
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'parser/current'
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
# This cop checks for a redundant argument passed to certain methods.
|
9
|
+
#
|
10
|
+
# Limitations:
|
11
|
+
#
|
12
|
+
# 1. This cop matches for method names only and hence cannot tell apart
|
13
|
+
# methods with same name in different classes.
|
14
|
+
# 2. This cop is limited to methods with single parameter.
|
15
|
+
# 3. This cop is unsafe if certain special global variables (e.g. `$;`) are set.
|
16
|
+
# That depends on the nature of the target methods, of course.
|
17
|
+
#
|
18
|
+
# Method names and their redundant arguments can be configured like this:
|
19
|
+
#
|
20
|
+
# Methods:
|
21
|
+
# join: ''
|
22
|
+
# split: ' '
|
23
|
+
# foo: 2
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# # bad
|
27
|
+
# array.join('')
|
28
|
+
# [1, 2, 3].join("")
|
29
|
+
# string.split(" ")
|
30
|
+
# "first\nsecond".split(" ")
|
31
|
+
# A.foo(2)
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# array.join
|
35
|
+
# [1, 2, 3].join
|
36
|
+
# string.split
|
37
|
+
# "first second".split
|
38
|
+
# A.foo
|
39
|
+
class RedundantArgument < Cop
|
40
|
+
MSG = 'Argument %<arg>s is redundant because it is implied by default.'
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
return unless redundant_argument?(node)
|
44
|
+
|
45
|
+
add_offense(node, message: format(MSG, arg: node.arguments.first.source))
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def redundant_argument?(node)
|
51
|
+
redundant_argument = redundant_arg_for_method(node.method_name.to_s)
|
52
|
+
return false if redundant_argument.nil?
|
53
|
+
|
54
|
+
node.arguments.first == redundant_argument
|
55
|
+
end
|
56
|
+
|
57
|
+
def redundant_arg_for_method(method_name)
|
58
|
+
return nil unless cop_config['Methods'].key?(method_name)
|
59
|
+
|
60
|
+
@mem ||= {}
|
61
|
+
@mem[method_name] ||=
|
62
|
+
begin
|
63
|
+
arg = cop_config['Methods'].fetch(method_name)
|
64
|
+
buffer = Parser::Source::Buffer.new('(string)', 1)
|
65
|
+
buffer.source = arg.inspect
|
66
|
+
builder = RuboCop::AST::Builder.new
|
67
|
+
Parser::CurrentRuby.new(builder).parse(buffer)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -53,7 +53,7 @@ module RuboCop
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def on_node(syms, sexp, excludes = [], &block)
|
56
|
-
return to_enum(:on_node, syms, sexp, excludes) unless
|
56
|
+
return to_enum(:on_node, syms, sexp, excludes) unless block
|
57
57
|
|
58
58
|
yield sexp if Array(syms).include?(sexp.type)
|
59
59
|
return if Array(excludes).include?(sexp.type)
|
@@ -78,7 +78,7 @@ module RuboCop
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def each_ancestor(include_self: false, &block)
|
81
|
-
return to_enum(__method__, include_self: include_self) unless
|
81
|
+
return to_enum(__method__, include_self: include_self) unless block
|
82
82
|
|
83
83
|
yield self if include_self
|
84
84
|
scan_ancestors(&block)
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
# This formatter displays a YAML configuration file where all cops that
|
6
6
|
# detected any offenses are configured to not detect the offense.
|
7
7
|
class DisabledConfigFormatter < BaseFormatter
|
8
|
+
include PathUtil
|
9
|
+
|
8
10
|
HEADING = <<~COMMENTS
|
9
11
|
# This configuration was generated by
|
10
12
|
# `%<command>s`
|
@@ -195,15 +197,28 @@ module RuboCop
|
|
195
197
|
end
|
196
198
|
|
197
199
|
def excludes(offending_files, cop_name, parent)
|
198
|
-
# Exclude properties in .rubocop_todo.yml override default ones, as well
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
# just look at the current working directory
|
200
|
+
# Exclude properties in .rubocop_todo.yml override default ones, as well as any custom
|
201
|
+
# excludes in .rubocop.yml, so in order to retain those excludes we must copy them.
|
202
|
+
# There can be multiple .rubocop.yml files in subdirectories, but we just look at the
|
203
|
+
# current working directory.
|
203
204
|
config = ConfigStore.new.for(parent)
|
204
205
|
cfg = config[cop_name] || {}
|
205
206
|
|
206
|
-
(
|
207
|
+
if merge_mode_for_exclude?(config) || merge_mode_for_exclude?(cfg)
|
208
|
+
offending_files
|
209
|
+
else
|
210
|
+
cop_exclude = cfg['Exclude']
|
211
|
+
if cop_exclude && cop_exclude != default_config(cop_name)['Exclude']
|
212
|
+
warn "`#{cop_name}: Exclude` in `#{smart_path(config.loaded_path)}` overrides a " \
|
213
|
+
'generated `Exclude` in `.rubocop_todo.yml`. Either remove ' \
|
214
|
+
"`#{cop_name}: Exclude` or add `inherit_mode: merge: - Exclude`."
|
215
|
+
end
|
216
|
+
((cop_exclude || []) + offending_files).uniq
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def merge_mode_for_exclude?(cfg)
|
221
|
+
Array(cfg.to_h.dig('inherit_mode', 'merge')).include?('Exclude')
|
207
222
|
end
|
208
223
|
|
209
224
|
def output_exclude_path(output_buffer, exclude_path, parent)
|
data/lib/rubocop/options.rb
CHANGED
@@ -5,6 +5,7 @@ require 'shellwords'
|
|
5
5
|
|
6
6
|
module RuboCop
|
7
7
|
class IncorrectCopNameError < StandardError; end
|
8
|
+
|
8
9
|
class OptionArgumentError < StandardError; end
|
9
10
|
|
10
11
|
# This class handles command line options.
|
@@ -195,6 +196,7 @@ module RuboCop
|
|
195
196
|
|
196
197
|
option(opts, '--safe')
|
197
198
|
|
199
|
+
option(opts, '--stderr')
|
198
200
|
option(opts, '--[no-]color')
|
199
201
|
|
200
202
|
option(opts, '-v', '--version')
|
@@ -498,6 +500,9 @@ module RuboCop
|
|
498
500
|
extra_details: 'Display extra details in offense messages.',
|
499
501
|
lint: 'Run only lint cops.',
|
500
502
|
safe: 'Run only safe cops.',
|
503
|
+
stderr: ['Write all output to stderr except for the',
|
504
|
+
'autocorrected source. This is especially useful',
|
505
|
+
'when combined with --auto-correct and --stdin.'],
|
501
506
|
list_target_files: 'List all files RuboCop will inspect.',
|
502
507
|
auto_correct: 'Auto-correct offenses (only when it\'s safe).',
|
503
508
|
safe_auto_correct: '(same, deprecated)',
|
data/lib/rubocop/rake_task.rb
CHANGED
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
|
23
23
|
task(name, *args) do |_, task_args|
|
24
24
|
RakeFileUtils.verbose(verbose) do
|
25
|
-
yield(*[self, task_args].slice(0, task_block.arity)) if
|
25
|
+
yield(*[self, task_args].slice(0, task_block.arity)) if task_block
|
26
26
|
run_cli(verbose, full_options)
|
27
27
|
end
|
28
28
|
end
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
|
67
67
|
task(:auto_correct, *args) do |_, task_args|
|
68
68
|
RakeFileUtils.verbose(verbose) do
|
69
|
-
yield(*[self, task_args].slice(0, task_block.arity)) if
|
69
|
+
yield(*[self, task_args].slice(0, task_block.arity)) if task_block
|
70
70
|
options = full_options.unshift('--auto-correct-all')
|
71
71
|
options.delete('--parallel')
|
72
72
|
run_cli(verbose, options)
|
data/lib/rubocop/runner.rb
CHANGED
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
# instances that each inspects its allotted group of files.
|
65
65
|
def warm_cache(target_files)
|
66
66
|
puts 'Running parallel inspection' if @options[:debug]
|
67
|
-
Parallel.each(target_files
|
67
|
+
Parallel.each(target_files) { |target_file| file_offenses(target_file) }
|
68
68
|
end
|
69
69
|
|
70
70
|
def find_target_files(paths)
|
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-11-
|
13
|
+
date: 2020-11-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -169,11 +169,6 @@ extra_rdoc_files:
|
|
169
169
|
files:
|
170
170
|
- LICENSE.txt
|
171
171
|
- README.md
|
172
|
-
- assets/logo.png
|
173
|
-
- assets/output.html.erb
|
174
|
-
- bin/console
|
175
|
-
- bin/rubocop-profile
|
176
|
-
- bin/setup
|
177
172
|
- config/default.yml
|
178
173
|
- exe/rubocop
|
179
174
|
- lib/rubocop.rb
|
@@ -685,6 +680,7 @@ files:
|
|
685
680
|
- lib/rubocop/cop/style/proc.rb
|
686
681
|
- lib/rubocop/cop/style/raise_args.rb
|
687
682
|
- lib/rubocop/cop/style/random_with_offset.rb
|
683
|
+
- lib/rubocop/cop/style/redundant_argument.rb
|
688
684
|
- lib/rubocop/cop/style/redundant_assignment.rb
|
689
685
|
- lib/rubocop/cop/style/redundant_begin.rb
|
690
686
|
- lib/rubocop/cop/style/redundant_capital_w.rb
|
@@ -821,7 +817,7 @@ metadata:
|
|
821
817
|
homepage_uri: https://rubocop.org/
|
822
818
|
changelog_uri: https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md
|
823
819
|
source_code_uri: https://github.com/rubocop-hq/rubocop/
|
824
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
820
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.4/
|
825
821
|
bug_tracker_uri: https://github.com/rubocop-hq/rubocop/issues
|
826
822
|
post_install_message:
|
827
823
|
rdoc_options: []
|
data/assets/logo.png
DELETED
Binary file
|
data/assets/output.html.erb
DELETED
@@ -1,261 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta charset='UTF-8' />
|
5
|
-
<title>RuboCop Inspection Report</title>
|
6
|
-
<%# TODO: Clean up the messy markup and style definitions. %>
|
7
|
-
<style>
|
8
|
-
* {
|
9
|
-
-webkit-box-sizing: border-box;
|
10
|
-
-moz-box-sizing: border-box;
|
11
|
-
box-sizing: border-box;
|
12
|
-
}
|
13
|
-
|
14
|
-
body, html {
|
15
|
-
font-size: 62.5%;
|
16
|
-
}
|
17
|
-
body {
|
18
|
-
background-color: #ecedf0;
|
19
|
-
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
20
|
-
margin: 0;
|
21
|
-
}
|
22
|
-
code {
|
23
|
-
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
24
|
-
font-size: 85%;
|
25
|
-
}
|
26
|
-
#header {
|
27
|
-
background: #f9f9f9;
|
28
|
-
color: #333;
|
29
|
-
border-bottom: 3px solid #ccc;
|
30
|
-
height: 50px;
|
31
|
-
padding: 0;
|
32
|
-
}
|
33
|
-
#header .logo {
|
34
|
-
float: left;
|
35
|
-
margin: 5px 12px 7px 20px;
|
36
|
-
width: 38px;
|
37
|
-
height: 38px;
|
38
|
-
}
|
39
|
-
#header .title {
|
40
|
-
display: inline-block;
|
41
|
-
float: left;
|
42
|
-
height: 50px;
|
43
|
-
font-size: 2.4rem;
|
44
|
-
letter-spacing: normal;
|
45
|
-
line-height: 50px;
|
46
|
-
margin: 0;
|
47
|
-
}
|
48
|
-
|
49
|
-
.information, #offenses {
|
50
|
-
width: 100%;
|
51
|
-
padding: 20px;
|
52
|
-
color: #333;
|
53
|
-
}
|
54
|
-
#offenses {
|
55
|
-
padding: 0 20px;
|
56
|
-
}
|
57
|
-
|
58
|
-
.information .infobox {
|
59
|
-
border-left: 3px solid;
|
60
|
-
border-radius: 4px;
|
61
|
-
background-color: #fff;
|
62
|
-
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
63
|
-
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
64
|
-
padding: 15px;
|
65
|
-
border-color: #0088cc;
|
66
|
-
font-size: 1.4rem;
|
67
|
-
}
|
68
|
-
.information .infobox .info-title {
|
69
|
-
font-size: 1.8rem;
|
70
|
-
line-height: 2.2rem;
|
71
|
-
margin: 0 0 0.5em;
|
72
|
-
}
|
73
|
-
.information .offenses-list li {
|
74
|
-
line-height: 1.8rem
|
75
|
-
}
|
76
|
-
.information .offenses-list {
|
77
|
-
padding-left: 20px;
|
78
|
-
margin-bottom: 0;
|
79
|
-
}
|
80
|
-
|
81
|
-
#offenses .offense-box {
|
82
|
-
border-radius: 4px;
|
83
|
-
margin-bottom: 20px;
|
84
|
-
background-color: #fff;
|
85
|
-
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
86
|
-
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
87
|
-
}
|
88
|
-
.fixed .box-title {
|
89
|
-
position: fixed;
|
90
|
-
top: 0;
|
91
|
-
z-index: 10;
|
92
|
-
width: 100%;
|
93
|
-
}
|
94
|
-
.box-title-placeholder {
|
95
|
-
display: none;
|
96
|
-
}
|
97
|
-
.fixed .box-title-placeholder {
|
98
|
-
display: block;
|
99
|
-
}
|
100
|
-
#offenses .offense-box .box-title h3, #offenses .offense-box .box-title-placeholder h3 {
|
101
|
-
color: #33353f;
|
102
|
-
background-color: #f6f6f6;
|
103
|
-
font-size: 2rem;
|
104
|
-
line-height: 2rem;
|
105
|
-
display: block;
|
106
|
-
padding: 15px;
|
107
|
-
border-radius: 5px;
|
108
|
-
margin: 0;
|
109
|
-
}
|
110
|
-
#offenses .offense-box .offense-reports {
|
111
|
-
padding: 0 15px;
|
112
|
-
}
|
113
|
-
#offenses .offense-box .offense-reports .report {
|
114
|
-
border-bottom: 1px dotted #ddd;
|
115
|
-
padding: 15px 0px;
|
116
|
-
position: relative;
|
117
|
-
font-size: 1.3rem;
|
118
|
-
}
|
119
|
-
#offenses .offense-box .offense-reports .report:last-child {
|
120
|
-
border-bottom: none;
|
121
|
-
}
|
122
|
-
#offenses .offense-box .offense-reports .report pre code {
|
123
|
-
display: block;
|
124
|
-
background: #000;
|
125
|
-
color: #fff;
|
126
|
-
padding: 10px 15px;
|
127
|
-
border-radius: 5px;
|
128
|
-
line-height: 1.6rem;
|
129
|
-
}
|
130
|
-
#offenses .offense-box .offense-reports .report .location {
|
131
|
-
font-weight: bold;
|
132
|
-
}
|
133
|
-
#offenses .offense-box .offense-reports .report .message code {
|
134
|
-
padding: 0.3em;
|
135
|
-
background-color: rgba(0,0,0,0.07);
|
136
|
-
border-radius: 3px;
|
137
|
-
}
|
138
|
-
.severity {
|
139
|
-
text-transform: capitalize;
|
140
|
-
font-weight: bold;
|
141
|
-
}
|
142
|
-
.highlight {
|
143
|
-
padding: 2px;
|
144
|
-
border-radius: 2px;
|
145
|
-
font-weight: bold;
|
146
|
-
}
|
147
|
-
<%- SEVERITY_COLORS.each do |severity, color| %>
|
148
|
-
.severity.<%= severity %> {
|
149
|
-
color: <%= color %>;
|
150
|
-
}
|
151
|
-
.highlight.<%= severity %> {
|
152
|
-
background-color: <%= color.fade_out(0.4) %>;
|
153
|
-
border: 1px solid <%= color.fade_out(0.6) %>;
|
154
|
-
}
|
155
|
-
<%- end %>
|
156
|
-
footer {
|
157
|
-
margin-bottom: 20px;
|
158
|
-
margin-right: 20px;
|
159
|
-
font-size: 1.3rem;
|
160
|
-
color: #777;
|
161
|
-
text-align: right;
|
162
|
-
}
|
163
|
-
.extra-code {
|
164
|
-
color: #ED9C28
|
165
|
-
}
|
166
|
-
</style>
|
167
|
-
|
168
|
-
<script>
|
169
|
-
(function() {
|
170
|
-
// floating headers. requires classList support.
|
171
|
-
if (!('classList' in document.createElement("_"))) return;
|
172
|
-
|
173
|
-
var loaded = false,
|
174
|
-
boxes,
|
175
|
-
boxPositions;
|
176
|
-
|
177
|
-
window.onload = function() {
|
178
|
-
var scrollY = window.scrollY;
|
179
|
-
boxes = document.querySelectorAll('.offense-box');
|
180
|
-
boxPositions = [];
|
181
|
-
for (var i = 0; i < boxes.length; i++)
|
182
|
-
// need to add scrollY because the page might be somewhere other than the top when loaded.
|
183
|
-
boxPositions[i] = boxes[i].getBoundingClientRect().top + scrollY;
|
184
|
-
loaded = true;
|
185
|
-
};
|
186
|
-
|
187
|
-
window.onscroll = function() {
|
188
|
-
if (!loaded) return;
|
189
|
-
var i,
|
190
|
-
idx,
|
191
|
-
scrollY = window.scrollY;
|
192
|
-
for (i = 0; i < boxPositions.length; i++) {
|
193
|
-
if (scrollY <= boxPositions[i] - 1) {
|
194
|
-
idx = i;
|
195
|
-
break;
|
196
|
-
}
|
197
|
-
}
|
198
|
-
if (typeof idx == 'undefined') idx = boxes.length;
|
199
|
-
if (idx > 0)
|
200
|
-
boxes[idx - 1].classList.add('fixed');
|
201
|
-
for (i = 0; i < boxes.length; i++) {
|
202
|
-
if (i < idx) continue;
|
203
|
-
boxes[i].classList.remove('fixed');
|
204
|
-
}
|
205
|
-
};
|
206
|
-
})();
|
207
|
-
</script>
|
208
|
-
</head>
|
209
|
-
<body>
|
210
|
-
<div id="header">
|
211
|
-
<img class="logo" src="data:image/png;base64,<%= base64_encoded_logo_image %>" alt="">
|
212
|
-
<h1 class="title">RuboCop Inspection Report</h1>
|
213
|
-
</div>
|
214
|
-
<div class="information">
|
215
|
-
<div class="infobox">
|
216
|
-
<div class="total">
|
217
|
-
<%= pluralize(files.count, 'file') %> inspected,
|
218
|
-
<%= pluralize(summary.offense_count, 'offense', no_for_zero: true) %> detected:
|
219
|
-
</div>
|
220
|
-
<ul class="offenses-list">
|
221
|
-
<% files.each do |file| %>
|
222
|
-
<% next if file.offenses.none? %>
|
223
|
-
<li>
|
224
|
-
<a href="#offense_<%= relative_path(file.path) %>">
|
225
|
-
<%= relative_path(file.path) %> - <%= pluralize(file.offenses.count, 'offense') %>
|
226
|
-
</a>
|
227
|
-
</li>
|
228
|
-
<% end %>
|
229
|
-
</ul>
|
230
|
-
</div>
|
231
|
-
</div>
|
232
|
-
<div id="offenses">
|
233
|
-
<% files.each do |file| %>
|
234
|
-
<% if file.offenses.any? %>
|
235
|
-
<div class="offense-box" id="offense_<%= relative_path(file.path) %>">
|
236
|
-
<div class="box-title-placeholder"><h3> </h3></div>
|
237
|
-
<div class="box-title"><h3><%= relative_path(file.path) %> - <%= pluralize(file.offenses.count, 'offense') %></h3></div>
|
238
|
-
<div class="offense-reports">
|
239
|
-
<% file.offenses.each do |offense| %>
|
240
|
-
<div class="report">
|
241
|
-
<div class="meta">
|
242
|
-
<span class="location">Line #<%= offense.location.line %></span> –
|
243
|
-
<span class="severity <%= offense.severity %>"><%= offense.severity %>:</span>
|
244
|
-
<span class="message"><%= decorated_message(offense) %></span>
|
245
|
-
</div>
|
246
|
-
<% unless offense.location.source_line.strip.empty? %>
|
247
|
-
<pre><code><%= highlighted_source_line(offense) %></code></pre>
|
248
|
-
<% end %>
|
249
|
-
</div>
|
250
|
-
<% end %>
|
251
|
-
</div>
|
252
|
-
</div>
|
253
|
-
<% end %>
|
254
|
-
<% end %>
|
255
|
-
</div>
|
256
|
-
<footer>
|
257
|
-
Generated by <a href="https://github.com/rubocop-hq/rubocop">RuboCop</a>
|
258
|
-
<span class="version"><%= RuboCop::Version::STRING %></span>
|
259
|
-
</footer>
|
260
|
-
</body>
|
261
|
-
</html>
|
data/bin/console
DELETED
data/bin/rubocop-profile
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
if ARGV.include?('-h') || ARGV.include?('--help')
|
5
|
-
puts "Usage: same as main `rubocop` command but gathers profiling info"
|
6
|
-
puts "Additional option: `--memory` to print memory usage"
|
7
|
-
exit(0)
|
8
|
-
end
|
9
|
-
with_mem = ARGV.delete('--memory')
|
10
|
-
ARGV.unshift '--cache', 'false' unless ARGV.include?('--cache')
|
11
|
-
|
12
|
-
require 'stackprof'
|
13
|
-
if with_mem
|
14
|
-
require 'memory_profiler'
|
15
|
-
MemoryProfiler.start
|
16
|
-
end
|
17
|
-
StackProf.start
|
18
|
-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
19
|
-
begin
|
20
|
-
load "#{__dir__}/../exe/rubocop"
|
21
|
-
ensure
|
22
|
-
delta = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
23
|
-
puts "Finished in #{delta.round(1)} seconds"
|
24
|
-
StackProf.stop
|
25
|
-
if with_mem
|
26
|
-
puts "Building memory report..."
|
27
|
-
report = MemoryProfiler.stop
|
28
|
-
end
|
29
|
-
Dir.mkdir('tmp') unless File.exist?('tmp')
|
30
|
-
StackProf.results('tmp/stackprof.dump')
|
31
|
-
report&.pretty_print(scale_bytes: true)
|
32
|
-
end
|