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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +8 -6
  4. data/.rubocop_todo.yml +25 -20
  5. data/.simplecov +1 -0
  6. data/.travis.yml +17 -11
  7. data/CHANGELOG.md +31 -3
  8. data/Dockerfile +1 -0
  9. data/Gemfile +14 -17
  10. data/README.md +15 -11
  11. data/bin/code_climate_reek +12 -2
  12. data/docs/Attribute.md +1 -1
  13. data/docs/Boolean-Parameter.md +1 -1
  14. data/docs/Control-Couple.md +1 -1
  15. data/docs/Nil-Check.md +4 -1
  16. data/features/command_line_interface/options.feature +2 -3
  17. data/features/configuration_files/schema_validation.feature +1 -1
  18. data/features/reports/codeclimate.feature +2 -2
  19. data/features/reports/json.feature +3 -3
  20. data/features/reports/reports.feature +4 -4
  21. data/features/reports/yaml.feature +3 -3
  22. data/features/step_definitions/reek_steps.rb +5 -1
  23. data/features/step_definitions/sample_file_steps.rb +2 -2
  24. data/features/support/env.rb +1 -2
  25. data/lib/reek.rb +1 -0
  26. data/lib/reek/ast/sexp_extensions/arguments.rb +11 -0
  27. data/lib/reek/cli/options.rb +3 -3
  28. data/lib/reek/code_comment.rb +45 -38
  29. data/lib/reek/configuration/app_configuration.rb +4 -3
  30. data/lib/reek/configuration/configuration_converter.rb +2 -2
  31. data/lib/reek/configuration/directory_directives.rb +9 -3
  32. data/lib/reek/context/module_context.rb +3 -1
  33. data/lib/reek/errors/legacy_comment_separator_error.rb +36 -0
  34. data/lib/reek/examiner.rb +3 -3
  35. data/lib/reek/report.rb +5 -7
  36. data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
  37. data/lib/reek/report/code_climate/code_climate_report.rb +2 -1
  38. data/lib/reek/report/simple_warning_formatter.rb +0 -7
  39. data/lib/reek/report/text_report.rb +2 -2
  40. data/lib/reek/smell_detectors/base_detector.rb +1 -9
  41. data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
  42. data/lib/reek/smell_detectors/data_clump.rb +23 -56
  43. data/lib/reek/smell_detectors/nil_check.rb +1 -12
  44. data/lib/reek/smell_detectors/subclassed_from_core_class.rb +3 -7
  45. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
  46. data/lib/reek/smell_warning.rb +1 -2
  47. data/lib/reek/source/source_code.rb +3 -2
  48. data/lib/reek/source/source_locator.rb +13 -10
  49. data/lib/reek/spec/smell_matcher.rb +2 -1
  50. data/lib/reek/version.rb +1 -1
  51. data/reek.gemspec +13 -6
  52. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +2 -4
  53. data/spec/quality/documentation_spec.rb +2 -1
  54. data/spec/reek/ast/sexp_extensions_spec.rb +15 -33
  55. data/spec/reek/code_comment_spec.rb +41 -42
  56. data/spec/reek/configuration/directory_directives_spec.rb +6 -0
  57. data/spec/reek/context_builder_spec.rb +110 -113
  58. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
  59. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
  60. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  61. data/spec/reek/report/code_climate/code_climate_report_spec.rb +1 -1
  62. data/spec/reek/report/json_report_spec.rb +1 -1
  63. data/spec/reek/report/location_formatter_spec.rb +3 -3
  64. data/spec/reek/report/text_report_spec.rb +1 -7
  65. data/spec/reek/report/yaml_report_spec.rb +1 -1
  66. data/spec/reek/smell_detectors/base_detector_spec.rb +3 -13
  67. data/spec/reek/smell_detectors/data_clump_spec.rb +14 -0
  68. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +8 -2
  69. data/spec/reek/smell_detectors/nil_check_spec.rb +3 -3
  70. data/spec/reek/smell_warning_spec.rb +12 -12
  71. data/spec/reek/source/source_code_spec.rb +13 -0
  72. data/spec/reek/spec/should_reek_of_spec.rb +0 -1
  73. data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
  74. data/spec/reek/spec/smell_matcher_spec.rb +1 -1
  75. data/spec/spec_helper.rb +20 -6
  76. data/tasks/configuration.rake +1 -2
  77. metadata +15 -25
  78. 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/v5.4.1/docs/Code-Smells.md for a list of smells
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/v5.4.1/docs/Code-Smells.md for a details on each detector
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 reek --format code_climate clean
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 reek --format code_climate smelly.rb
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/v5.4.1/docs/Uncommunicative-Method-Name.md",
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/v5.4.1/docs/Uncommunicative-Variable-Name.md",
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/v5.4.1/docs/Irresponsible-Module.md"
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/v5.4.1/docs/Uncommunicative-Method-Name.md]
186
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.4.1/docs/Uncommunicative-Variable-Name.md]
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/v5.4.1/docs/Uncommunicative-Method-Name.md]
213
- UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.4.1/docs/Uncommunicative-Variable-Name.md]
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/v5.4.1/docs/Uncommunicative-Method-Name.md
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/v5.4.1/docs/Uncommunicative-Variable-Name.md
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/v5.4.1/docs/Irresponsible-Module.md
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 /^I pass "([^\"]*)" to reek *(.*)$/ do |stdin, args|
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 SAMPLES_DIR.join('..').join('docs').join('defaults.reek.yml')
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|
@@ -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/HandleExceptions
7
+ rescue LoadError # rubocop:disable Lint/SuppressedException
9
8
  end
10
9
 
11
10
  #
@@ -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
@@ -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, :code_climate],
134
+ '-f', '--format FORMAT', [:html, :text, :yaml, :json, :xml],
135
135
  'Report smells in the given format:',
136
- ' html', ' text (default)', ' yaml', ' json', ' xml', ' code_climate') do |opt|
136
+ ' html', ' text (default)', ' yaml', ' json', ' xml') do |opt|
137
137
  self.report_format = opt
138
138
  end
139
139
  end
@@ -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: # prefix
18
- (\w+) # smell detector e.g.: UncommunicativeVariableName
19
- (
20
- \s*
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, _option_string, options|
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
- :options,
120
- :detector_class,
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 escalate_bad_detector_configuration
133
- @parsed_options = YAML.safe_load(options || CodeComment::DISABLE_DETECTOR_CONFIGURATION,
134
- permitted_classes: [Regexp])
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, detector_name: detector_name,
137
- original_comment: original_comment,
138
- source: source,
139
- line: line
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, detector_name: detector_name,
148
- offensive_keys: configuration_keys_difference,
149
- original_comment: original_comment,
150
- source: source,
151
- line: line
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
- if key == EXCLUDE_PATHS_KEY
75
+ case key
76
+ when EXCLUDE_PATHS_KEY
76
77
  excluded_paths.add value
77
- elsif key == DIRECTORIES_KEY
78
+ when DIRECTORIES_KEY
78
79
  directory_directives.add value
79
- elsif key == DETECTORS_KEY
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.keys.each do |detector|
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.keys.each do |directory|
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 { |pathname| source_base_dir.to_s.match(glob_to_regexp(pathname.to_s)) }.
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| [:casgn, :class, :module].include? child.type }
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