{"id":13412061,"url":"https://github.com/troessner/reek","last_synced_at":"2025-03-14T17:31:36.716Z","repository":{"id":429246,"uuid":"49515","full_name":"troessner/reek","owner":"troessner","description":"Code smell detector for Ruby","archived":false,"fork":false,"pushed_at":"2024-10-13T08:29:12.000Z","size":5974,"stargazers_count":4035,"open_issues_count":55,"forks_count":280,"subscribers_count":47,"default_branch":"master","last_synced_at":"2024-10-14T11:43:37.669Z","etag":null,"topics":["linters","parsing","quality","ruby","smell","smell-detector","smell-warnings","static-analysis"],"latest_commit_sha":null,"homepage":"https://github.com/troessner/reek","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/troessner.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2008-09-05T10:48:33.000Z","updated_at":"2024-10-13T08:29:17.000Z","dependencies_parsed_at":"2023-10-20T23:33:00.591Z","dependency_job_id":"400f0c3b-ee91-4d7d-a9c7-9f9f5fd13ee7","html_url":"https://github.com/troessner/reek","commit_stats":{"total_commits":1936,"total_committers":113,"mean_commits":17.13274336283186,"dds":0.7024793388429752,"last_synced_commit":"b878e969fc6e9be590da9ee25177ca9d52abc75e"},"previous_names":[],"tags_count":166,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troessner%2Freek","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troessner%2Freek/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troessner%2Freek/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troessner%2Freek/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troessner","download_url":"https://codeload.github.com/troessner/reek/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243618752,"owners_count":20320286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linters","parsing","quality","ruby","smell","smell-detector","smell-warnings","static-analysis"],"created_at":"2024-07-30T20:01:20.618Z","updated_at":"2025-03-14T17:31:31.702Z","avatar_url":"https://github.com/troessner.png","language":"Ruby","readme":"![reek logo](logo/reek.text.png)\n\n# Code smell detector for Ruby\n\n**Table of Contents**\n\n- [Overview](#overview)\n- [Quickstart](#quickstart)\n- [Example](#example)\n- [Supported Ruby versions](#supported-ruby-versions)\n- [Fixing Smell Warnings](#fixing-smell-warnings)\n- [Sources](#sources)\n- [Code smells](#code-smells)\n- [Configuration](#configuration)\n  - [Command-line interface](#command-line-interface)\n  - [Configuration file](#configuration-file)\n    - [Configuration loading](#configuration-loading)\n    - [Configuration options](#configuration-options)\n  - [Generating a 'todo' list](#generating-a-todo-list)\n  - [Beware of multiple configuration files](#beware-of-multiple-configuration-files)\n  - [Source code comments](#source-code-comments)\n- [Usage](#usage)\n- [Developing Reek / Contributing](#developing-reek--contributing)\n- [Output formats](#output-formats)\n- [Working with Rails](#working-with-rails)\n- [Integrations](#integrations)\n  - [Editor integrations](#editor-integrations)\n  - [Projects that use or support us](#projects-that-use-or-support-us)\n  - [Misc](#misc)\n- [Brothers and sisters](#brothers-and-sisters)\n- [Contributors](#contributors)\n- [Additional resources](#additional-resources)\n  - [Miscellaneous](#miscellaneous)\n  - [More information](#more-information)\n\n## Overview\n\n* ![Downloads](https://img.shields.io/badge/Downloads-%3E24_million-blue)\n* ![Build Status](https://github.com/troessner/reek/actions/workflows/ruby.yml/badge.svg?branch=master)\n* [![Gem Version](https://badge.fury.io/rb/reek.svg)](https://badge.fury.io/rb/reek)\n* ![Git Tag](http://img.shields.io/github/tag/troessner/reek.svg)\n* ![Licence](http://img.shields.io/badge/license-MIT-brightgreen.svg)\n* [![Inline docs](https://inch-ci.org/github/troessner/reek.png)](https://inch-ci.org/github/troessner/reek)\n* [![Code Climate](https://codeclimate.com/github/troessner/reek/badges/gpa.svg)](https://codeclimate.com/github/troessner/reek)\n* [![codebeat](https://codebeat.co/badges/42fed4ff-3e55-4aed-8ecc-409b4aa539b3)](https://codebeat.co/projects/github-com-troessner-reek)\n\n\n## Quickstart\n\nReek is a tool that examines Ruby classes, modules and methods and reports any\n[Code Smells](docs/Code-Smells.md) it finds.\n\nFor an excellent introduction to\n[Code Smells](docs/Code-Smells.md) and Reek check out [this blog post](https://blog.codeship.com/how-to-find-ruby-code-smells-with-reek/)\nor [that one](https://troessner.svbtle.com/the-latest-and-greatest-additions-to-reek). There is also [this talk](https://www.youtube.com/watch?v=pazYe7WRWRU) from [RubyConfBY](http://rubyconference.by/) (there is also a [slide deck](http://talks.chastell.net/rubyconf-by-lt-2016/) if you prefer that).\n\nInstall it via rubygems:\n\n```bash\ngem install reek\n```\n\nand run it like this:\n\n```bash\nreek [options] [dir_or_source_file]*\n```\n\n## Example\n\nImagine a source file `demo.rb` containing:\n\n```ruby\n# Smelly class\nclass Smelly\n  # This will reek of UncommunicativeMethodName\n  def x\n    y = 10 # This will reek of UncommunicativeVariableName\n  end\nend\n```\n\nReek will report the following code smells in this file:\n\n```\n$ reek --no-documentation demo.rb\nInspecting 1 file(s):\nS\n\ndemo.rb -- 2 warnings:\n  [4]:UncommunicativeMethodName: Smelly#x has the name 'x'\n  [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'\n```\n\n## Supported Ruby versions\n\nReek is officially supported for CRuby 3.0 through 3.3 and for JRuby 9.4.\nOther Ruby implementations (like Rubinius) are not officially supported but\nshould work as well.\n\nNote that, on each Ruby version, Reek will use the parser for that version of\nRuby. So, you should always run Reek using one of your project's target Ruby\nversions.\n\n## Fixing Smell Warnings\n\nReek focuses on high-level code smells, so we can't tell you how to fix warnings in\na generic fashion; this is and will always be completely dependent on your domain\nlanguage and business logic.\n\nThat said, an example might help you get going. Have a look at this sample of a\nRuby on Rails model (be aware that this is truncated, not working code):\n\n```ruby\nclass ShoppingCart \u003c ActiveRecord::Base\n  has_many :items\n\n  def gross_price\n    items.sum { |item| item.net + item.tax }\n  end\nend\n\nclass Item \u003c ActiveRecord::Base\n  belongs_to :shopping_cart\nend\n```\n\nRunning Reek on this file like this:\n\n```\nreek app/models/shopping_cart.rb\n```\n\nwould report:\n\n```\n  [5, 5]:ShoppingCart#gross_price refers to item more than self (FeatureEnvy)\n```\n\nFixing this is pretty straightforward. Put the gross price calculation for a single item\nwhere it belongs, which would be the `Item` class:\n\n```ruby\nclass ShoppingCart \u003c ActiveRecord::Base\n  has_many :items\n\n  def gross_price\n    items.sum { |item| item.gross_price }\n  end\nend\n\nclass Item \u003c ActiveRecord::Base\n  belongs_to :shopping_cart\n\n  def gross_price\n    net + tax\n  end\nend\n```\n\nThe [Code Smells](docs/Code-Smells.md) docs may give you further hints - be sure to check out\nthose first when you have a warning that you don't know how to deal with.\n\n## Sources\n\nThere are multiple ways you can have Reek work on sources, the most common one just being\n\n```bash\nreek lib/\n```\n\nIf you don't pass any source arguments to Reek it just takes the current working directory as source.\n\nSo\n\n```bash\nreek\n```\n\nis the exact same thing as being explicit:\n\n```bash\nreek .\n```\n\nAdditionally you can pipe code to Reek like this:\n\n```bash\necho \"class C; def m; end; end\" | reek\n```\n\nThis would print out:\n\n```bash\n$stdin -- 3 warnings:\n  [1]:C has no descriptive comment (IrresponsibleModule)\n  [1]:C has the name 'C' (UncommunicativeModuleName)\n  [1]:C#m has the name 'm' (UncommunicativeMethodName)\n```\n\n## Code smells\n\nReek currently includes checks for some aspects of\n[Control Couple](docs/Control-Couple.md),\n[Data Clump](docs/Data-Clump.md),\n[Feature Envy](docs/Feature-Envy.md),\n[Large Class](docs/Large-Class.md),\n[Long Parameter List](docs/Long-Parameter-List.md),\n[Simulated Polymorphism](docs/Simulated-Polymorphism.md),\n[Too Many Statements](docs/Too-Many-Statements.md),\n[Uncommunicative Name](docs/Uncommunicative-Name.md),\n[Unused Parameters](docs/Unused-Parameters.md)\nand more. See the [Code Smells](docs/Code-Smells.md)\nfor up to date details of exactly what Reek will check in your code.\n\n**Special configuration for controversial detectors:**\n\n[Unused Private Method](docs/Unused-Private-Method.md) is disabled by default\nbecause it is [kind of controversial](https://github.com/troessner/reek/issues/844) which means\nyou have to explicitly activate it in your configuration via\n\n```yaml\nUnusedPrivateMethod:\n  enabled: true\n```\n\n[Utility Function](docs/Utility-Function.md) is a [controversial detector](https://github.com/troessner/reek/issues/681)\nas well that can turn out to be really unforgiving.\nAs a consequence, we made it possible to disable it for non-public methods like this:\n\n```yaml\n---\nUtilityFunction:\n  public_methods_only: true\n```\n\n## Configuration\n\n### Command-line interface\n\nFor a basic overview, run\n\n```ruby\nreek --help\n```\n\nFor a summary of those CLI options see [Command-Line Options](docs/Command-Line-Options.md).\n\n### Configuration file\n\n#### Configuration loading\n\nConfiguring Reek via a configuration file is by far the most powerful way.\nReek expects this filename to be `.reek.yml` but you can override this via the CLI `-c` switch (see below).\n\nThere are three ways of passing Reek the configuration file:\n\n1. Using the CLI `-c` switch (see [_Command-line interface_](#command-line-interface) above)\n2. Having the configuration file either in your current working directory or in a parent directory (more on that later)\n3. Having the configuration file in your home directory\n\nThe order in which Reek tries to find such a configuration\nfile is exactly the above: first it checks if we have given\nit a configuration file explicitly via CLI; then it checks\nthe current working directory for a file and if it can't\nfind one, it traverses up the directories until it hits the\nroot directory; lastly, it checks your home directory.\n\nAs soon as Reek detects a configuration file it stops searching\nimmediately, meaning that from Reek's point of view there exists\nexactly one configuration file and one configuration, regardless\nof how many `*.reek` files you might have on your filesystem.\n\n#### Configuration options\n\nWe put a lot of effort into making Reek's configuration as self explanatory as possible so the\nbest way to understand it is by looking at a simple\nexample (e.g. `.reek.yml` in your project directory):\n\n```yaml\n---\n\n### Generic smell configuration\n\ndetectors:\n  # You can disable smells completely\n  IrresponsibleModule:\n    enabled: false\n\n  # You can use filters to silence Reek warnings.\n  # Either because you simply disagree with Reek (we are not the police) or\n  # because you want to fix this at a later point in time.\n  NestedIterators:\n    exclude:\n      - \"MyWorker#self.class_method\" # should be refactored\n      - \"AnotherWorker#instance_method\" # should be refactored as well\n\n  # A lot of smells allow fine tuning their configuration. You can look up all available options\n  # in the corresponding smell documentation in /docs. In most cases you probably can just go\n  # with the defaults as documented in defaults.reek.yml.\n  DataClump:\n    max_copies: 3\n    min_clump_size: 3\n\n### Directory specific configuration\n\n# You can configure smells on a per-directory base.\n# E.g. the classic Rails case: controllers smell of NestedIterators (see /docs/Nested-Iterators.md) and\n# helpers smell of UtilityFunction (see docs/Utility-Function.md)\n#\n# Note that we only allow configuration on a directory level, not a file level,\n# so all paths have to point to directories.\n# A Dir.glob pattern can be used.\ndirectories:\n  \"web_app/app/controllers\":\n    NestedIterators:\n      enabled: false\n  \"web_app/app/helpers**\":\n    UtilityFunction:\n      enabled: false\n  \"web_app/lib/**/test/**\":\n    UtilityFunction:\n      enabled: false\n\n### Excluding directories\n\n# Directories and files below will not be scanned at all\nexclude_paths:\n  - lib/legacy\n  - lib/rake/legacy_tasks\n  - lib/smelly.rb\n```\n\nAs you see above, Reek's configuration consists of 3 different sections denoted by 3 different keys:\n\n* detectors\n* directories\n* exclude_paths\n\nWhatever you add to your configuration should be scoped under one of those keys.\n\nIf you have a directory directive for which a default directive exists, the more specific\none (which is the directory directive) will take precedence.\n\nThis configuration for instance:\n\n```yaml\n---\ndetectors:\n  IrresponsibleModule:\n    enabled: false\n\n  TooManyStatements:\n    max_statements: 5\n\ndirectories:\n  \"app/controllers\":\n    TooManyStatements:\n      max_statements: 10\n```\n\ntranslates to:\n\n* IrresponsibleModule is disabled everywhere\n* TooManyStatements#max_statements is 10 in \"app/controllers\"\n* TooManyStatements#max_statements is 5 everywhere else\n\nEvery smell detector supports our [Basic Smell Options](docs/Basic-Smell-Options.md). As you can see above,\ncertain smell types offer a configuration that goes beyond that of the basic smell options, for instance\n[Data Clump](docs/Data-Clump.md).\nAll options that go beyond the [Basic Smell Options](docs/Basic-Smell-Options.md)\nare documented in the corresponding smell type /docs page (if you want to get a quick overview over all possible\nconfigurations you can also check out [the `defaults.reek.yml` file in this repository](docs/defaults.reek.yml).\n\nNote that you do not need a configuration file at all.\nIf you're fine with all the [defaults](docs/defaults.reek.yml) we set you can skip this completely.\n\nDon't worry about introducing a mistake in your configuration file that might go unnoticed - Reek uses a\nschema to validate your configuration against on start up and will faily loudly in case you\nmisspelled an option or used the wrong data type for a value like this:\n\n```\nError: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.\n```\n\nReek takes one configuration file and one configuration file only with `.reek.yml` being the default name.\n\nIn case you have to have one or more configuration files in the directory (e.g. you're\ntoying around with different, mutually exclusive settings) you need to tell Reek\nexplicitly which file to use via `reek -c config.reek`.\n\n### Source code comments\n\nIn case you need to suppress a smell warning and you can't or don't want to\nuse configuration files for whatever reasons you can also use special\nsource code comments like this:\n\n```ruby\n# This method smells of :reek:NestedIterators\ndef smelly_method foo\n  foo.each {|bar| bar.each {|baz| baz.qux}}\nend\n```\n\nYou can even pass in smell specific configuration settings:\n\n```ruby\n# :reek:NestedIterators { max_allowed_nesting: 2 }\ndef smelly_method foo\n  foo.each {|bar| bar.each {|baz| baz.qux}}\nend\n```\n\nThis is an incredibly powerful feature and further explained under [Smell Suppression](docs/Smell-Suppression.md).\n\n#### Debugging trouble with the configuration\n\nWith Reeks dynamic mechanism of finding a configuration file you might run into a situation where you are not\n100% sure what configuration file Reek is using. E.g. you have a project specific configuration file in your\nproject root and also another Reek configuration in your HOME directory that you use for all your other projects\nand for whatever reasons Reek seems to be using another configuration file than the one you assumed it would.\n\nIn this case you can pass the flag `--show-configuration-path` to Reek which will cause Reek to output the path\nto the configuration file it is using.\n\n### Generating a 'todo' list\n\nIntegrating tools like Reek into an existing larger codebase can be daunting when you have to fix\npossibly hundreds or thousands of smell warnings first.\nSure you could manually disable smell warnings like shown above but depending on the size of your\ncodebase this might not be an option.\nFortunately Reek provides a 'todo' flag which you can use to generate a configuration that will\nsuppress all smell warnings for the current codebase:\n\n```bash\nreek --todo lib/\n```\n\nThis will create the file '.reek.yml' in your current working directory.\n\nYou can then use this as your configuration - since your working directory\nprobably is your project root in most cases you don't have to tell Reek\nexplicitly to use '.reek.yml' because Reek will automatically pick it up\nand use it as configuration file. See [Configuration Loading](#configuration-loading) above.\n\nIf for whatever reasons you decide to put '.reek.yml' somewhere else where\nReek won't pick it up automatically you need to tell Reek explicitly to do so\nvia:\n\n```bash\nreek -c whatever/.reek.yml lib/\n```\n\nIt's important to understand that the number one use case of the `--todo` flag\nis to be run once at the beginning of the introduction of Reek to ease the transition.\nIf you find yourself wanting to re-run Reek with the `--todo` flag in order to silence a lot of new warnings\nyou're defeating the purpose of both the `--todo` flag and of Reek itself.\n\nAs a consequence, running Reek with the `--todo` flag again will not overwrite an existing '.reek.yml'\nand instead abort execution. It also will not take **any** other configuration file you might have into account.\n\nThis means that when you run\n\n```bash\nreek -c other_configuration.reek --todo lib/\n```\n\n`other_configuration.reek` will simply be ignored.\n\nOf course you can always just delete the existing .reek.yml file and then run Reek with the `--todo` flag\nbut keep in mind that this is not the intended use case of this feature.\n\n## Usage\n\nBesides the obvious\n\n```bash\nreek [options] [dir_or_source_file]*\n```\n\nthere are quite a few other ways how to use Reek in your projects:\n\n* Use Reek's [Rake task](docs/Rake-Task.md) to automate detecting code smells\n* Add Reek's custom matcher to your [RSpec examples](docs/RSpec-matchers.md)\n* Include Reek using the [Developer API](docs/API.md)\n\n## Developing Reek / Contributing\n\nThe first thing you want to do after checking out the source code is to run Bundler:\n\n```\nbundle install\n```\n\nand then run the tests:\n\n```bash\nbundle exec rspec spec/your/file_spec.rb            # Runs all tests in spec/your/file_spec.rb\nbundle exec rspec spec/your/file_spec.rb:23         # Runs test in line 23\nbundle exec cucumber features/your_file.feature     # Runs all scenarios in your_file.feature\nbundle exec cucumber features/your_file.feature:23  # Runs scenario at line 23\n```\n\nOr just run the whole test suite:\n\n```\nbundle exec rake\n```\n\nThis will run the tests (RSpec and Cucumber), RuboCop and Reek itself.\n\nAnother useful Rake task is the `console` task. This will throw you right into an environment where you can play around with Reeks modules and classes:\n\n```\nbundle exec rake console\n\n[3] pry(main)\u003e require_relative 'lib/reek/examiner'\n=\u003e true\n[4] pry(main)\u003e Reek::Examiner\n=\u003e Reek::Examiner\n```\n\nYou can also use Pry while running the tests by adding the following at the\npoint where you want to start debugging:\n\n```ruby\nrequire 'pry'\nbinding.pry\n```\n\nHave a look at our [Developer API](docs/API.md) for more inspiration.\n\nFrom then on you should check out:\n\n* [How Reek works internally](docs/How-reek-works-internally.md)\n* [the contributing guide](CONTRIBUTING.md)\n\nIf you don't feel like getting your hands dirty with code there are still other ways you can help us:\n\n* Open up an [issue](https://github.com/troessner/reek/issues) and report bugs\n* Suggest other improvements like additional smells for instance\n\n### Running Code Climate locally\n\nIf you run into Code Climate issues (e.g., go over code duplication\nthreshold) you might want to be able to run Code Climate against\nthe Reek codebase locally. To do this, you need to do the following:\n\n* [install Docker CE](https://docs.docker.com/engine/installation/)\n* [install Code Climate CLI](https://github.com/codeclimate/codeclimate#installation)\n* `gem install codeclimate`\n* `codeclimate engines:install`\n\nNow you can run various Code Climate engines,\ne.g., `codeclimate analyze -e duplication`\n\n## Output formats\n\nReek supports 5 output formats:\n\n* plain text (default)\n* HTML (`--format html`)\n* YAML (`--format yaml`, see also [YAML Reports](docs/YAML-Reports.md))\n* JSON (`--format json`)\n* XML  (`--format xml`)\n\n## Working with Rails\n\nMaking Reek \"Rails\"-friendly is fairly simple since we support directory specific configurations (`directory directives` in Reek talk).\nJust add this to your configuration file:\n\n```yaml\ndirectories:\n  \"app/controllers\":\n    IrresponsibleModule:\n      enabled: false\n    NestedIterators:\n      max_allowed_nesting: 2\n    UnusedPrivateMethod:\n      enabled: false\n    InstanceVariableAssumption:\n      enabled: false\n  \"app/helpers\":\n    IrresponsibleModule:\n      enabled: false\n    UtilityFunction:\n      enabled: false\n  \"app/mailers\":\n    InstanceVariableAssumption:\n      enabled: false\n  \"app/models\":\n    InstanceVariableAssumption:\n      enabled: false\n```\n\nBe careful though, Reek does not merge your configuration entries, so if you already have a directory directive for \"app/controllers\" or \"app/helpers\" you need to update those directives instead of copying the above YAML sample into your configuration file.\n\n## Integrations\n\n### Editor integrations\n\n* [Vim plugin](https://github.com/rainerborene/vim-reek)\n* [TextMate Bundle](https://github.com/peeyush1234/reek.tmbundle)\n* [Atom plugin](https://atom.io/packages/linter-reek)\n* [SublimeLinter plugin](https://packagecontrol.io/packages/SublimeLinter-contrib-reek)\n* [VS Code plugin](https://github.com/rubyide/vscode-ruby)\n* [Emacs plugin](https://github.com/hanmoi-choi/reek-emacs)\n\n### Projects that use or support us\n\n* [overcommit](https://github.com/brigade/overcommit) - a Git commit hook manager with support for\n  Reek\n* [ruby-critic](https://github.com/whitesmith/rubycritic) - gem that wraps around static analysis gems such as Reek, [flay](https://github.com/seattlerb/flay) and [flog](https://github.com/seattlerb/flog)\n* [pronto-reek](https://github.com/mmozuras/pronto-reek) - Reek integration for [pronto](https://github.com/mmozuras/pronto)\n* [action-reek](https://github.com/reviewdog/action-reek) - GitHub Action to run reek with [reviewdog](https://github.com/reviewdog/reviewdog) 🐶\n\n### Misc\n\n* [Colorful output for Reek](https://github.com/joenas/preek)\n  (also with [Guard::Preek](https://github.com/joenas/guard-preek))\n\n## Brothers and sisters\n\nA non-exhaustive list of other static code analyzers you might want to look into:\n\n* [debride](https://github.com/seattlerb/debride) - analyze code for potentially uncalled / dead methods\n* [flay](https://github.com/seattlerb/flay) - analyze code for structural similarities\n* [flog](https://github.com/seattlerb/flog) - reports the most tortured code in an easy to read pain\nreport\n* [SandiMeter](https://github.com/makaroni4/sandi_meter) - checking your Ruby code for Sandi Metz' four rules\n* [ruby-lint](https://github.com/YorickPeterse/ruby-lint) - static code analysis tool\n* [Fasterer](https://github.com/DamirSvrtan/fasterer) - Fasterer will suggest some speed improvements based on [fast-ruby](https://github.com/JuanitoFatas/fast-ruby)\n\n## Contributors\n\nThe Reek core team consists of:\n\n* [Matijs van Zuijlen](https://github.com/mvz)\n* [Piotr Szotkowski](https://github.com/chastell)\n* [Waldyr Souza](https://github.com/waldyr)\n* [Timo Rößner](https://github.com/troessner)\n\nThe original author of Reek is [Kevin Rutherford](https://github.com/kevinrutherford).\n\nThe author of Reek’s logo is [Sonja Heinen](http://yippee.io).\n\nNotable contributions came from:\n\n* [Andrew Wagner](https://github.com/arwagner)\n* [Gilles Leblanc](https://github.com/gilles-leblanc)\n* [Emil Rehnberg](https://github.com/EmilRehnberg)\n\n## Additional resources\n\n### Miscellaneous\n\n* [Reek Driven Development](docs/Reek-Driven-Development.md)\n* [Versioning policy](docs/Versioning-Policy.md)\n\n### More information\n\n* [Stack Overflow](https://stackoverflow.com/questions/tagged/reek)\n* [RubyDoc.info](http://www.rubydoc.info/gems/reek)\n","funding_links":[],"categories":["Ruby","Code Quality","Ruby Style Guides","Code Analysis and Metrics","Tools","Programming Languages","Code Analysis and Linter","Ruby Linter / Code Checker / Static Code Analyzer","Awesome Ruby CLIs"],"sub_categories":["Code Metrics","Other tools","Code Quality"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroessner%2Freek","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroessner%2Freek","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroessner%2Freek/lists"}