reek 5.4.1 → 6.0.2
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/.gitignore +1 -0
- data/.rubocop.yml +8 -6
- data/.rubocop_todo.yml +25 -20
- data/.simplecov +1 -0
- data/.travis.yml +17 -11
- data/CHANGELOG.md +31 -3
- data/Dockerfile +1 -0
- data/Gemfile +14 -17
- data/README.md +15 -11
- data/bin/code_climate_reek +12 -2
- data/docs/Attribute.md +1 -1
- data/docs/Boolean-Parameter.md +1 -1
- data/docs/Control-Couple.md +1 -1
- data/docs/Nil-Check.md +4 -1
- data/features/command_line_interface/options.feature +2 -3
- data/features/configuration_files/schema_validation.feature +1 -1
- data/features/reports/codeclimate.feature +2 -2
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +4 -4
- data/features/reports/yaml.feature +3 -3
- data/features/step_definitions/reek_steps.rb +5 -1
- data/features/step_definitions/sample_file_steps.rb +2 -2
- data/features/support/env.rb +1 -2
- data/lib/reek.rb +1 -0
- data/lib/reek/ast/sexp_extensions/arguments.rb +11 -0
- data/lib/reek/cli/options.rb +3 -3
- data/lib/reek/code_comment.rb +45 -38
- data/lib/reek/configuration/app_configuration.rb +4 -3
- data/lib/reek/configuration/configuration_converter.rb +2 -2
- data/lib/reek/configuration/directory_directives.rb +9 -3
- data/lib/reek/context/module_context.rb +3 -1
- data/lib/reek/errors/legacy_comment_separator_error.rb +36 -0
- data/lib/reek/examiner.rb +3 -3
- data/lib/reek/report.rb +5 -7
- data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
- data/lib/reek/report/code_climate/code_climate_report.rb +2 -1
- data/lib/reek/report/simple_warning_formatter.rb +0 -7
- data/lib/reek/report/text_report.rb +2 -2
- data/lib/reek/smell_detectors/base_detector.rb +1 -9
- data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
- data/lib/reek/smell_detectors/data_clump.rb +23 -56
- data/lib/reek/smell_detectors/nil_check.rb +1 -12
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +3 -7
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
- data/lib/reek/smell_warning.rb +1 -2
- data/lib/reek/source/source_code.rb +3 -2
- data/lib/reek/source/source_locator.rb +13 -10
- data/lib/reek/spec/smell_matcher.rb +2 -1
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +13 -6
- data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +2 -4
- data/spec/quality/documentation_spec.rb +2 -1
- data/spec/reek/ast/sexp_extensions_spec.rb +15 -33
- data/spec/reek/code_comment_spec.rb +41 -42
- data/spec/reek/configuration/directory_directives_spec.rb +6 -0
- data/spec/reek/context_builder_spec.rb +110 -113
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/code_climate/code_climate_report_spec.rb +1 -1
- data/spec/reek/report/json_report_spec.rb +1 -1
- data/spec/reek/report/location_formatter_spec.rb +3 -3
- data/spec/reek/report/text_report_spec.rb +1 -7
- data/spec/reek/report/yaml_report_spec.rb +1 -1
- data/spec/reek/smell_detectors/base_detector_spec.rb +3 -13
- data/spec/reek/smell_detectors/data_clump_spec.rb +14 -0
- data/spec/reek/smell_detectors/missing_safe_method_spec.rb +8 -2
- data/spec/reek/smell_detectors/nil_check_spec.rb +3 -3
- data/spec/reek/smell_warning_spec.rb +12 -12
- data/spec/reek/source/source_code_spec.rb +13 -0
- data/spec/reek/spec/should_reek_of_spec.rb +0 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
- data/spec/reek/spec/smell_matcher_spec.rb +1 -1
- data/spec/spec_helper.rb +20 -6
- data/tasks/configuration.rake +1 -2
- metadata +15 -25
- data/spec/factories/factories.rb +0 -37
@@ -43,7 +43,7 @@ Feature: Reek can be controlled using command-line options
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
44
44
|
--smell SMELL Only look for a specific smell.
|
45
45
|
Call it like this: reek --smell MissingSafeMethod source.rb
|
46
|
-
Check out https://github.com/troessner/reek/blob/
|
46
|
+
Check out https://github.com/troessner/reek/blob/v6.0.2/docs/Code-Smells.md for a list of smells
|
47
47
|
--stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config.
|
48
48
|
|
49
49
|
Generate a todo list:
|
@@ -56,7 +56,6 @@ Feature: Reek can be controlled using command-line options
|
|
56
56
|
yaml
|
57
57
|
json
|
58
58
|
xml
|
59
|
-
code_climate
|
60
59
|
|
61
60
|
Text format options:
|
62
61
|
--[no-]color Use colors for the output (default: true)
|
@@ -120,5 +119,5 @@ Feature: Reek can be controlled using command-line options
|
|
120
119
|
UnusedPrivateMethod
|
121
120
|
UtilityFunction
|
122
121
|
|
123
|
-
Check out https://github.com/troessner/reek/blob/
|
122
|
+
Check out https://github.com/troessner/reek/blob/v6.0.2/docs/Code-Smells.md for a details on each detector
|
124
123
|
"""
|
@@ -6,7 +6,7 @@ Feature: Validate schema
|
|
6
6
|
Scenario: Our generated default configuration
|
7
7
|
Given our default configuration file
|
8
8
|
And the clean file "clean.rb"
|
9
|
-
When I run reek -c defaults.reek clean.rb
|
9
|
+
When I run reek -c defaults.reek.yml clean.rb
|
10
10
|
Then it succeeds
|
11
11
|
And it reports nothing
|
12
12
|
|
@@ -4,7 +4,7 @@ Feature: Report smells using Code Climate format
|
|
4
4
|
|
5
5
|
Scenario: output is empty when there are no smells
|
6
6
|
Given a directory called 'clean' containing two clean files
|
7
|
-
When I run
|
7
|
+
When I run the code climate reek runner
|
8
8
|
Then it succeeds
|
9
9
|
And it reports this Code Climate output:
|
10
10
|
"""
|
@@ -12,7 +12,7 @@ Feature: Report smells using Code Climate format
|
|
12
12
|
|
13
13
|
Scenario: Indicate smells and print them as JSON when using files
|
14
14
|
Given the smelly file 'smelly.rb'
|
15
|
-
When I run
|
15
|
+
When I run the code climate reek runner
|
16
16
|
Then it reports this Code Climate output:
|
17
17
|
"""
|
18
18
|
{
|
@@ -24,7 +24,7 @@ Feature: Report smells using simple JSON layout
|
|
24
24
|
"context": "Smelly#x",
|
25
25
|
"lines": [ 4 ],
|
26
26
|
"message": "has the name 'x'",
|
27
|
-
"documentation_link": "https://github.com/troessner/reek/blob/
|
27
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Method-Name.md",
|
28
28
|
"name": "x"
|
29
29
|
},
|
30
30
|
{
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple JSON layout
|
|
33
33
|
"context": "Smelly#x",
|
34
34
|
"lines": [ 5 ],
|
35
35
|
"message": "has the variable name 'y'",
|
36
|
-
"documentation_link": "https://github.com/troessner/reek/blob/
|
36
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Variable-Name.md",
|
37
37
|
"name": "y"
|
38
38
|
}
|
39
39
|
]
|
@@ -53,7 +53,7 @@ Feature: Report smells using simple JSON layout
|
|
53
53
|
1
|
54
54
|
],
|
55
55
|
"message": "has no descriptive comment",
|
56
|
-
"documentation_link": "https://github.com/troessner/reek/blob/
|
56
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.2/docs/Irresponsible-Module.md"
|
57
57
|
}
|
58
58
|
]
|
59
59
|
"""
|
@@ -182,8 +182,8 @@ Feature: Correctly formatted reports
|
|
182
182
|
And it reports:
|
183
183
|
"""
|
184
184
|
smelly.rb -- 2 warnings:
|
185
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/
|
186
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/
|
185
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Method-Name.md]
|
186
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Variable-Name.md]
|
187
187
|
"""
|
188
188
|
|
189
189
|
Examples:
|
@@ -209,8 +209,8 @@ Feature: Correctly formatted reports
|
|
209
209
|
And it reports:
|
210
210
|
"""
|
211
211
|
smelly.rb -- 2 warnings:
|
212
|
-
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/
|
213
|
-
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/
|
212
|
+
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Method-Name.md]
|
213
|
+
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Variable-Name.md]
|
214
214
|
"""
|
215
215
|
|
216
216
|
Examples:
|
@@ -25,7 +25,7 @@ Feature: Report smells using simple YAML layout
|
|
25
25
|
smell_type: UncommunicativeMethodName
|
26
26
|
source: smelly.rb
|
27
27
|
name: x
|
28
|
-
documentation_link: https://github.com/troessner/reek/blob/
|
28
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Method-Name.md
|
29
29
|
- context: Smelly#x
|
30
30
|
lines:
|
31
31
|
- 5
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple YAML layout
|
|
33
33
|
smell_type: UncommunicativeVariableName
|
34
34
|
source: smelly.rb
|
35
35
|
name: y
|
36
|
-
documentation_link: https://github.com/troessner/reek/blob/
|
36
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.2/docs/Uncommunicative-Variable-Name.md
|
37
37
|
"""
|
38
38
|
|
39
39
|
Scenario: Indicate smells and print them as yaml when using STDIN
|
@@ -48,5 +48,5 @@ Feature: Report smells using simple YAML layout
|
|
48
48
|
lines:
|
49
49
|
- 1
|
50
50
|
message: has no descriptive comment
|
51
|
-
documentation_link: https://github.com/troessner/reek/blob/
|
51
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.2/docs/Irresponsible-Module.md
|
52
52
|
"""
|
@@ -2,7 +2,11 @@ When /^I run reek (.*)$/ do |args|
|
|
2
2
|
reek(args)
|
3
3
|
end
|
4
4
|
|
5
|
-
When
|
5
|
+
When 'I run the code climate reek runner' do
|
6
|
+
run_command_and_stop 'code_climate_reek'
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I pass "([^"]*)" to reek *(.*)$/ do |stdin, args|
|
6
10
|
reek_with_pipe(stdin, args)
|
7
11
|
end
|
8
12
|
|
@@ -44,8 +44,8 @@ Given(/^a configuration file '(.+)'$/) do |filename|
|
|
44
44
|
end
|
45
45
|
|
46
46
|
Given(/^our default configuration file$/) do
|
47
|
-
default_configuration = File.read
|
48
|
-
write_file('defaults.reek', default_configuration)
|
47
|
+
default_configuration = File.read Reek::DEFAULT_SMELL_CONFIGURATION
|
48
|
+
write_file('defaults.reek.yml', default_configuration)
|
49
49
|
end
|
50
50
|
|
51
51
|
When(/^I run "reek (.*?)" in a subdirectory$/) do |args|
|
data/features/support/env.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
require_relative '../../lib/reek'
|
2
2
|
require_relative '../../lib/reek/cli/application'
|
3
3
|
require 'aruba/cucumber'
|
4
|
-
require 'active_support/core_ext/string/strip'
|
5
4
|
|
6
5
|
begin
|
7
6
|
require 'pry-byebug'
|
8
|
-
rescue LoadError # rubocop:disable Lint/
|
7
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
9
8
|
end
|
10
9
|
|
11
10
|
#
|
data/lib/reek.rb
CHANGED
@@ -8,6 +8,7 @@ require_relative 'reek/examiner'
|
|
8
8
|
require_relative 'reek/report'
|
9
9
|
|
10
10
|
module Reek
|
11
|
+
DEFAULT_SMELL_CONFIGURATION = File.join(__dir__, '../docs/defaults.reek.yml').freeze
|
11
12
|
DEFAULT_CONFIGURATION_FILE_NAME = '.reek.yml'
|
12
13
|
DETECTORS_KEY = 'detectors'
|
13
14
|
EXCLUDE_PATHS_KEY = 'exclude_paths'
|
@@ -93,6 +93,17 @@ module Reek
|
|
93
93
|
module ShadowargNode
|
94
94
|
include ArgNodeBase
|
95
95
|
end
|
96
|
+
|
97
|
+
# Utility methods for :forward_args nodes.
|
98
|
+
# rubocop:disable Naming/ClassAndModuleCamelCase
|
99
|
+
module Forward_ArgsNode
|
100
|
+
include ArgNodeBase
|
101
|
+
|
102
|
+
def anonymous_splat?
|
103
|
+
true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# rubocop:enable Naming/ClassAndModuleCamelCase
|
96
107
|
end
|
97
108
|
end
|
98
109
|
end
|
data/lib/reek/cli/options.rb
CHANGED
@@ -87,7 +87,7 @@ module Reek
|
|
87
87
|
|
88
88
|
def set_banner
|
89
89
|
program_name = parser.program_name
|
90
|
-
parser.banner = <<-BANNER.gsub(/^
|
90
|
+
parser.banner = <<-BANNER.gsub(/^ +/, '')
|
91
91
|
Usage: #{program_name} [options] [files]
|
92
92
|
|
93
93
|
Examples:
|
@@ -131,9 +131,9 @@ module Reek
|
|
131
131
|
def set_alternative_formatter_options
|
132
132
|
parser.separator "\nReport format:"
|
133
133
|
parser.on(
|
134
|
-
'-f', '--format FORMAT', [:html, :text, :yaml, :json, :xml
|
134
|
+
'-f', '--format FORMAT', [:html, :text, :yaml, :json, :xml],
|
135
135
|
'Report smells in the given format:',
|
136
|
-
' html', ' text (default)', ' yaml', ' json', ' xml'
|
136
|
+
' html', ' text (default)', ' yaml', ' json', ' xml') do |opt|
|
137
137
|
self.report_format = opt
|
138
138
|
end
|
139
139
|
end
|
data/lib/reek/code_comment.rb
CHANGED
@@ -6,6 +6,7 @@ require_relative 'smell_detectors/base_detector'
|
|
6
6
|
require_relative 'errors/bad_detector_in_comment_error'
|
7
7
|
require_relative 'errors/bad_detector_configuration_key_in_comment_error'
|
8
8
|
require_relative 'errors/garbage_detector_configuration_in_comment_error'
|
9
|
+
require_relative 'errors/legacy_comment_separator_error'
|
9
10
|
|
10
11
|
module Reek
|
11
12
|
#
|
@@ -14,12 +15,10 @@ module Reek
|
|
14
15
|
#
|
15
16
|
class CodeComment
|
16
17
|
CONFIGURATION_REGEX = /
|
17
|
-
:reek:
|
18
|
-
(\w+)
|
19
|
-
(
|
20
|
-
|
21
|
-
(\{.*?\}) # optional details in hash style e.g.: { max_methods: 30 }
|
22
|
-
)?
|
18
|
+
:reek: # prefix
|
19
|
+
(\w+) # smell detector e.g.: UncommunicativeVariableName
|
20
|
+
(:?\s*) # separator
|
21
|
+
(\{.*?\})? # details in hash style e.g.: { max_methods: 30 }
|
23
22
|
/x.freeze
|
24
23
|
SANITIZE_REGEX = /(#|\n|\s)+/.freeze # Matches '#', newlines and > 1 whitespaces.
|
25
24
|
DISABLE_DETECTOR_CONFIGURATION = '{ enabled: false }'
|
@@ -38,7 +37,8 @@ module Reek
|
|
38
37
|
@source = source
|
39
38
|
@config = Hash.new { |hash, key| hash[key] = {} }
|
40
39
|
|
41
|
-
@original_comment.scan(CONFIGURATION_REGEX) do |detector_name,
|
40
|
+
@original_comment.scan(CONFIGURATION_REGEX) do |detector_name, separator, options|
|
41
|
+
escalate_legacy_separator separator
|
42
42
|
CodeCommentValidator.new(detector_name: detector_name,
|
43
43
|
original_comment: original_comment,
|
44
44
|
line: line,
|
@@ -64,6 +64,14 @@ module Reek
|
|
64
64
|
strip
|
65
65
|
end
|
66
66
|
|
67
|
+
def escalate_legacy_separator(separator)
|
68
|
+
return unless separator.start_with? ':'
|
69
|
+
|
70
|
+
raise Errors::LegacyCommentSeparatorError.new(original_comment: original_comment,
|
71
|
+
source: source,
|
72
|
+
line: line)
|
73
|
+
end
|
74
|
+
|
67
75
|
#
|
68
76
|
# A typical configuration via code comment looks like this:
|
69
77
|
#
|
@@ -88,25 +96,22 @@ module Reek
|
|
88
96
|
# @param source [String] path to source file or "string"
|
89
97
|
# @param options [String] the configuration options as String for the detector that were
|
90
98
|
# extracted from the original comment
|
91
|
-
def initialize(detector_name:, original_comment:, line:, source:, options:
|
99
|
+
def initialize(detector_name:, original_comment:, line:, source:, options:)
|
92
100
|
@detector_name = detector_name
|
93
101
|
@original_comment = original_comment
|
94
102
|
@line = line
|
95
103
|
@source = source
|
96
104
|
@options = options
|
97
|
-
@detector_class = nil # We only know this one after our first initial checks
|
98
|
-
@parsed_options = nil # We only know this one after our first initial checks
|
99
105
|
end
|
100
106
|
|
101
107
|
#
|
102
108
|
# Method can raise the following errors:
|
109
|
+
# * Errors::LegacyCommentSeparatorError
|
103
110
|
# * Errors::BadDetectorInCommentError
|
104
111
|
# * Errors::GarbageDetectorConfigurationInCommentError
|
105
112
|
# * Errors::BadDetectorConfigurationKeyInCommentError
|
106
113
|
# @return [undefined]
|
107
114
|
def validate
|
108
|
-
escalate_bad_detector
|
109
|
-
escalate_bad_detector_configuration
|
110
115
|
escalate_unknown_configuration_key
|
111
116
|
end
|
112
117
|
|
@@ -116,39 +121,41 @@ module Reek
|
|
116
121
|
:original_comment,
|
117
122
|
:line,
|
118
123
|
:source,
|
119
|
-
:
|
120
|
-
:
|
121
|
-
:parsed_options
|
122
|
-
|
123
|
-
def escalate_bad_detector
|
124
|
-
return if SmellDetectors::BaseDetector.valid_detector?(detector_name)
|
125
|
-
|
126
|
-
raise Errors::BadDetectorInCommentError, detector_name: detector_name,
|
127
|
-
original_comment: original_comment,
|
128
|
-
source: source,
|
129
|
-
line: line
|
130
|
-
end
|
124
|
+
:separator,
|
125
|
+
:options
|
131
126
|
|
132
|
-
def
|
133
|
-
@parsed_options
|
134
|
-
|
127
|
+
def parsed_options
|
128
|
+
@parsed_options ||= YAML.safe_load(options || CodeComment::DISABLE_DETECTOR_CONFIGURATION,
|
129
|
+
permitted_classes: [Regexp])
|
135
130
|
rescue Psych::SyntaxError
|
136
|
-
raise Errors::GarbageDetectorConfigurationInCommentError
|
137
|
-
|
138
|
-
|
139
|
-
|
131
|
+
raise Errors::GarbageDetectorConfigurationInCommentError.new(detector_name: detector_name,
|
132
|
+
original_comment: original_comment,
|
133
|
+
source: source,
|
134
|
+
line: line)
|
140
135
|
end
|
141
136
|
|
142
137
|
def escalate_unknown_configuration_key
|
143
|
-
@detector_class = SmellDetectors::BaseDetector.to_detector(detector_name)
|
144
|
-
|
145
138
|
return if given_keys_legit?
|
146
139
|
|
147
|
-
raise Errors::BadDetectorConfigurationKeyInCommentError
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
140
|
+
raise Errors::BadDetectorConfigurationKeyInCommentError.new(detector_name: detector_name,
|
141
|
+
offensive_keys: configuration_keys_difference,
|
142
|
+
original_comment: original_comment,
|
143
|
+
source: source,
|
144
|
+
line: line)
|
145
|
+
end
|
146
|
+
|
147
|
+
def detector_class
|
148
|
+
@detector_class ||= SmellDetectors::BaseDetector.to_detector(detector_name)
|
149
|
+
rescue NameError
|
150
|
+
raise Errors::BadDetectorInCommentError.new(detector_name: detector_name,
|
151
|
+
original_comment: original_comment,
|
152
|
+
source: source,
|
153
|
+
line: line)
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return [Boolean] comment uses legacy three-colon format
|
157
|
+
def legacy_format?
|
158
|
+
separator.start_with? ':'
|
152
159
|
end
|
153
160
|
|
154
161
|
# @return [Boolean] all keys in code comment are applicable to the detector in question
|
@@ -72,11 +72,12 @@ module Reek
|
|
72
72
|
|
73
73
|
def load_values(values)
|
74
74
|
values.each do |key, value|
|
75
|
-
|
75
|
+
case key
|
76
|
+
when EXCLUDE_PATHS_KEY
|
76
77
|
excluded_paths.add value
|
77
|
-
|
78
|
+
when DIRECTORIES_KEY
|
78
79
|
directory_directives.add value
|
79
|
-
|
80
|
+
when DETECTORS_KEY
|
80
81
|
default_directive.add value
|
81
82
|
end
|
82
83
|
end
|
@@ -74,7 +74,7 @@ module Reek
|
|
74
74
|
return unless configuration[DETECTORS_KEY]
|
75
75
|
|
76
76
|
configuration[DETECTORS_KEY].tap do |detectors|
|
77
|
-
detectors.
|
77
|
+
detectors.each_key do |detector|
|
78
78
|
convertible_attributes(detectors[detector]).each do |attribute|
|
79
79
|
detectors[detector][attribute] = detectors[detector][attribute].map do |item|
|
80
80
|
to_regex item
|
@@ -94,7 +94,7 @@ module Reek
|
|
94
94
|
return unless configuration[DIRECTORIES_KEY]
|
95
95
|
|
96
96
|
configuration[DIRECTORIES_KEY].tap do |directories|
|
97
|
-
directories.
|
97
|
+
directories.each_key do |directory|
|
98
98
|
directories[directory].each do |detector, configuration|
|
99
99
|
convertible_attributes(configuration).each do |attribute|
|
100
100
|
directories[directory][detector][attribute] = directories[directory][detector][attribute].map do |item|
|
@@ -53,10 +53,16 @@ module Reek
|
|
53
53
|
# @quality :reek:FeatureEnvy
|
54
54
|
def best_match_for(source_base_dir)
|
55
55
|
keys.
|
56
|
-
select
|
56
|
+
select do |pathname|
|
57
|
+
match?(source_base_dir, pathname) || match?(source_base_dir, pathname.expand_path)
|
58
|
+
end.
|
57
59
|
max_by { |pathname| pathname.to_s.length }
|
58
60
|
end
|
59
61
|
|
62
|
+
def match?(source_base_dir, pathname)
|
63
|
+
source_base_dir.to_s.match(glob_to_regexp(pathname.to_s))
|
64
|
+
end
|
65
|
+
|
60
66
|
# Transform a glob pattern to a regexp.
|
61
67
|
#
|
62
68
|
# It changes:
|
@@ -78,7 +84,7 @@ module Reek
|
|
78
84
|
gsub('<<to_eol_wildcards>>', '.*').
|
79
85
|
gsub('<<to_wildcards>>', '.*')
|
80
86
|
else
|
81
|
-
glob
|
87
|
+
"#{glob}.*"
|
82
88
|
end
|
83
89
|
|
84
90
|
Regexp.new("^#{regexp}$", Regexp::IGNORECASE)
|
@@ -86,7 +92,7 @@ module Reek
|
|
86
92
|
|
87
93
|
def error_message_for_invalid_smell_type(klass)
|
88
94
|
"You are trying to configure smell type #{klass} but we can't find one with that name.\n" \
|
89
|
-
"Please make sure you spelled it right. (See 'docs/defaults.reek' in the Reek\n" \
|
95
|
+
"Please make sure you spelled it right. (See 'docs/defaults.reek.yml' in the Reek\n" \
|
90
96
|
'repository for a list of all available smell types.)'
|
91
97
|
end
|
92
98
|
end
|
@@ -66,6 +66,8 @@ module Reek
|
|
66
66
|
CodeComment.new(comment: exp.leading_comment).descriptive?
|
67
67
|
end
|
68
68
|
|
69
|
+
CONSTANT_SEXP_TYPES = [:casgn, :class, :module].freeze
|
70
|
+
|
69
71
|
# A namespace module is a module (or class) that is only there for namespacing
|
70
72
|
# purposes, and thus contains only nested constants, modules or classes.
|
71
73
|
#
|
@@ -78,7 +80,7 @@ module Reek
|
|
78
80
|
return false if exp.type == :casgn
|
79
81
|
|
80
82
|
children = exp.direct_children
|
81
|
-
children.any? && children.all? { |child|
|
83
|
+
children.any? && children.all? { |child| CONSTANT_SEXP_TYPES.include? child.type }
|
82
84
|
end
|
83
85
|
|
84
86
|
def track_visibility(visibility, names)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_error'
|
4
|
+
|
5
|
+
module Reek
|
6
|
+
module Errors
|
7
|
+
# Gets raised for old-style comment configuration format.
|
8
|
+
class LegacyCommentSeparatorError < BaseError
|
9
|
+
MESSAGE = <<-MESSAGE
|
10
|
+
Error: You are using the legacy configuration format (including three
|
11
|
+
colons) to configure Reek in one your source code comments.
|
12
|
+
|
13
|
+
The source is '%<source>s' and the comment belongs to the expression
|
14
|
+
starting in line %<line>d.
|
15
|
+
|
16
|
+
Here's the original comment:
|
17
|
+
|
18
|
+
%<comment>s
|
19
|
+
|
20
|
+
Please see the Reek docs for information on how to configure Reek via
|
21
|
+
source code comments: #{DocumentationLink.build('Smell Suppression')}
|
22
|
+
|
23
|
+
Update the offensive comment and re-run Reek.
|
24
|
+
|
25
|
+
MESSAGE
|
26
|
+
|
27
|
+
def initialize(source:, line:, original_comment:)
|
28
|
+
message = format(MESSAGE,
|
29
|
+
source: source,
|
30
|
+
line: line,
|
31
|
+
comment: original_comment)
|
32
|
+
super message
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|