Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Code smell detector for Ruby
Ruby Cucumber

Merge pull request #520 from troessner/feature/move-warning-collector…

…-to-cli

Move WarningCollector to /cli.
latest commit eb0cb3ccd6
@chastell chastell authored

README.md

reek: code smell detection for Ruby

Overview

Build Status Gem Version Dependency Status Inline docs

Quickstart

reek is a tool that examines Ruby classes, modules and methods and reports any Code Smells it finds. Install it like this:

gem install reek

and run it like this:

reek [options] [dir_or_source_file]*

Example

Imagine a source file demo.rb containing:

class Dirty
  # This method smells of :reek:NestedIterators but ignores them
  def awful(x, y, offset = 0, log = false)
    puts @screen.title
    @screen = widgets.map { |w| w.each { |key| key += 3 * x } }
    puts @screen.contents
  end
end

reek will report the following code smells in this file:

$ reek demo.rb
demo.rb -- 8 warnings:
  [1]:Dirty has no descriptive comment (IrresponsibleModule)
  [3]:Dirty#awful has 4 parameters (LongParameterList)
  [3]:Dirty#awful has boolean parameter 'log' (BooleanParameter)
  [3]:Dirty#awful has the parameter name 'x' (UncommunicativeParameterName)
  [5]:Dirty#awful has the variable name 'w' (UncommunicativeVariableName)
  [3]:Dirty#awful has unused parameter 'log' (UnusedParameters)
  [3]:Dirty#awful has unused parameter 'offset' (UnusedParameters)
  [3]:Dirty#awful has unused parameter 'y' (UnusedParameters)

Sources

There are multiple ways you can have reek work on sources, the most common one just being

reek lib/

If you don't pass any source arguments to reek it just takes the current working directory as source.

So

reek

is the exact same thing as being explicit:

reek .

Additionally you can pipe code to reek like this:

echo "class C; def m; end; end" | reek

This would print out:

$stdin -- 3 warnings:
  [1]:C has no descriptive comment (IrresponsibleModule)
  [1]:C has the name 'C' (UncommunicativeModuleName)
  [1]:C#m has the name 'm' (UncommunicativeMethodName)

Code smells

reek currently includes checks for some aspects of Control Couple, Data Clump, Feature Envy, Large Class, Long Parameter List, Simulated Polymorphism, Too Many Statements, Uncommunicative Name, Unused Parameters and more. See the Code Smells for up to date details of exactly what reek will check in your code.

Configuration

Command-line interface

For a basic overview, run

reek --help

For a summary of those CLI options see Command-Line Options.

Configuration file

Configuration loading

Configuring reek via a configuration file is by far the most powerful way.

There are three ways of passing reek a configuration file:

  1. Using the CLI -c switch (see Command-line interface above)
  2. Having a file ending with .reek either in your current working directory or in a parent directory (more on that later)
  3. Having a file ending with .reek in your home directory

The order in which reek tries to find such a configuration file is exactly the above: first it checks if we have given it a configuration file explicitly via CLI; then it checks the current working directory for a file and if it can't find one, it traverses up the directories until it hits the root directory; lastly, it checks your home directory.

As soon as reek detects a configuration file it stops searching immediately, meaning that from reek's point of view there exists exactly one configuration file and one configuration, regardless of how many *.reek files you might have on your filesystem.

Configuration options

The first thing you probably want to check out are the Basic Smell Options which are supported by every smell type. Certain smell types offer a configuration that goes beyond that of the basic smell options, for instance Data Clump. All options that go beyond the Basic Smell Options should be documented in the corresponding smell type wiki page, but if you want to get a quick and full overview over all possible configurations you can always check out the config/default.reek file in this repository.

Here's an excerpt of a reek configuration file from a commercial project:

---
IrresponsibleModule:
  enabled: false

NestedIterators:
  exclude:
    - "ActiveModelErrorAdder#self.run" # should be refactored
    - "BookingRequests::Transfer#remote_validation"
    - "BookingRequestsController#vehicle_options" # respond_to block
    - "Content::Base#self.expose_fields" # unavoidable due to metaprogramming

DataClump:
  max_copies: 3
  min_clump_size: 3

Source code comments

reek is not the police. In case you need to suppress a smell warning and you can't or don't want to use configuration files for whatever reasons you can also use source code comments like this:

# This method smells of :reek:NestedIterators
def smelly_method foo
  foo.each {|bar| bar.each {|baz| baz.qux}}
end

This is further explained under Smell Suppresion.

Integration

Besides the obvious

reek [options] [dir_or_source_file]*

there are quite a few other ways how to use reek in your projects:

Developing reek / Contributing

The first thing you want to do after checking out the source code is to run Bundler:

bundle install

and then run the tests:

bundle exec rspec spec/your/file_spec.rb            # Runs all tests in spec/your/file_spec.rb
bundle exec rspec spec/your/file_spec.rb:23         # Runs test in line 23
bundle exec cucumber features/your_file.feature     # Runs all scenarios in your_file.feature
bundle exec cucumber features/your_file.feature:23  # Runs scenario at line 23

Or just run the whole test suite:

bundle exec rake

From then on you should check out:

If you don't feel like getting your hands dirty with code there are still other ways you can help us:

  • Open up an issue and report bugs
  • Suggest other improvements like additional smells for instance

Output formats

reek supports 5 output formats:

  • plain text (default)
  • HTML (--format html)
  • YAML (--format yaml, see also YAML Reports)
  • JSON (--format json)
  • XML (--format xml)

Working with Rails

With current versions of reek it's best to examine only your app/models folder, because reek raises false positives against views and controllers.

For example, params is a kind of DTO (data transfer object) close to the system boundary, and so its characteristics should be different than regular code. But Reek doesn't know that (yet); reek thinks that all those params[:something] calls are a problem, and reports them as smells.

We plan to improve Reek in the near future so that it plays better with Rails. For now though, your best bet is to restrict it to looking at app/models and lib.

Additional resources

Tools

Miscellaneous

More information

Contributors

A non-exhaustive list:

  • Kevin Rutherford
  • Matijs van Zuijlen
  • Andrew Wagner
  • Gilles Leblanc
  • Timo Rößner
Something went wrong with that request. Please try again.