From 3778a62ee138ad78f7fea06c19b1c39923e6a213 Mon Sep 17 00:00:00 2001 From: Willian Gustavo Veiga Date: Mon, 13 Nov 2023 16:24:27 -0300 Subject: [PATCH] Add --exclude-smell CLI option --- docs/Command-Line-Options.md | 17 +++++++++++++ .../exclude_smells.feature | 12 ++++++++++ .../command_line_interface/options.feature | 3 +++ lib/reek/cli/options.rb | 24 +++++++++++++++---- 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 features/command_line_interface/exclude_smells.feature diff --git a/docs/Command-Line-Options.md b/docs/Command-Line-Options.md index e96f1b168..d738e71c9 100644 --- a/docs/Command-Line-Options.md +++ b/docs/Command-Line-Options.md @@ -73,6 +73,23 @@ You can select several smells by repeating the `--smell` option like so: reek --smell UtilityFunction --smell UncommunicativeMethodName ``` +## Telling Reek Which Smells to Exclude + +You can tell Reek to exclude specific smells by using the `--exclude-smell` +option and passing in the smell name. + +For example, to exclude checking for [Utility Function](Utility-Function.md), you would use: + +```bash +reek --exclude-smell UtilityFunction +``` + +You can select several smells to exclude by repeating the `--exclude-smell` option like so: + +```bash +reek --exclude-smell UtilityFunction --exclude-smell IrresponsibleModule +``` + ## Output options ### Output smell's line number diff --git a/features/command_line_interface/exclude_smells.feature b/features/command_line_interface/exclude_smells.feature new file mode 100644 index 000000000..0b7512e9e --- /dev/null +++ b/features/command_line_interface/exclude_smells.feature @@ -0,0 +1,12 @@ +Feature: Exclude smells + In order to exclude specific code smells + As a developer + I want to be able to selectively exclude smell detectors + + Scenario: --exclude-smell selects smells to exclude + Given the smelly file 'smelly.rb' + When I run reek --no-line-numbers --exclude-smell UncommunicativeMethodName --exclude-smell UncommunicativeVariableName smelly.rb + Then the exit status is 0 + And it reports: + """ + """ diff --git a/features/command_line_interface/options.feature b/features/command_line_interface/options.feature index 9ac31738d..b4a27c079 100644 --- a/features/command_line_interface/options.feature +++ b/features/command_line_interface/options.feature @@ -44,6 +44,9 @@ Feature: Reek can be controlled using command-line options --smell SMELL Only look for a specific smell. Call it like this: reek --smell MissingSafeMethod source.rb Check out https://github.com/troessner/reek/blob/v6.1.4/docs/Code-Smells.md for a list of smells + --exclude-smell SMELL Exclude a specific smell. + Call it like this: reek --exclude-smell MissingSafeMethod source.rb + Check out https://github.com/troessner/reek/blob/v6.1.4/docs/Code-Smells.md for a list of smells --stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config. Generate a todo list: diff --git a/lib/reek/cli/options.rb b/lib/reek/cli/options.rb index f5143c2cb..783b89ad5 100644 --- a/lib/reek/cli/options.rb +++ b/lib/reek/cli/options.rb @@ -15,7 +15,7 @@ module CLI # See {file:docs/Command-Line-Options.md} for details. # # @quality :reek:TooManyInstanceVariables { max_instance_variables: 13 } - # @quality :reek:TooManyMethods { max_methods: 18 } + # @quality :reek:TooManyMethods { max_methods: 20 } # @quality :reek:Attribute { enabled: false } # class Options @@ -101,8 +101,8 @@ def set_banner BANNER end - # @quality :reek:TooManyStatements { max_statements: 7 } - def set_configuration_options + # @quality :reek:TooManyStatements { max_statements: 10 } + def set_configuration_options # rubocop:disable Metrics/MethodLength, Metrics/AbcSize parser.separator 'Configuration:' parser.on('-c', '--config FILE', 'Read configuration options from FILE') do |file| self.config_file = Pathname.new(file) @@ -110,10 +110,18 @@ def set_configuration_options parser.on('--smell SMELL', 'Only look for a specific smell.', 'Call it like this: reek --smell MissingSafeMethod source.rb', - "Check out #{DocumentationLink.build('Code Smells')} " \ + "Check out #{code_smell_documentation_link} " \ 'for a list of smells') do |smell| smells_to_detect << smell end + parser.on('--exclude-smell SMELL', + 'Exclude a specific smell.', + 'Call it like this: reek --exclude-smell MissingSafeMethod source.rb', + "Check out #{code_smell_documentation_link} " \ + 'for a list of smells') do |smell| + smells_to_detect.append(*smell_detectors) if smells_to_detect.empty? + smells_to_detect.delete(smell) + end parser.on('--stdin-filename FILE', 'When passing code in via pipe, assume this filename when ' \ 'checking file or directory rules in the config.') do |file| @@ -121,6 +129,14 @@ def set_configuration_options end end + def code_smell_documentation_link + @code_smell_documentation_link ||= DocumentationLink.build('Code Smells') + end + + def smell_detectors + @smell_detectors ||= Reek::SmellDetectors.constants.map(&:to_s) + end + def set_generate_todo_list_options parser.separator "\nGenerate a todo list:" parser.on('-t', '--todo', 'Generate a todo list') do