README.md

Credo

What can it do?

credo can show you refactoring opportunities in your code, complex and duplicated code fragments, warn you about common mistakes, show inconsistencies in your naming scheme and - if needed - help you enforce a desired coding style.

If you are a Rubyist it is best described as an opinionated mix between Inch and Rubocop.

Now you might want to know more about that particular entry, just copy the filename+line-number combo into the command:

$ mix credo lib/phoenix/channel.ex:26
┃ Phoenix.Channel
┃
┃ [R] Category: refactor
┃ ↗ Priority: medium
┃
┃ If/else blocks should not have a negated condition in `if`.
┃ lib/phoenix/channel.ex:26 (Phoenix.Channel.subscribe)
┃
┃ __ CODE IN QUESTION
┃
┃ if !Socket.authenticated?(socket, channel, topic) do
┃
┃ __ WHY IT MATTERS
┃
┃ An `if` block with a negated condition should not contain an else block.
┃
┃ So while this is fine:
┃
┃ if !allowed? do
┃ raise "Not allowed!"
┃ end
┃
┃ The code in this example ...
┃
┃ if !allowed? do
┃ raise "Not allowed!"
┃ else
┃ proceed_as_planned
┃ end
┃
┃ ... should be refactored to look like this:
┃
┃ if allowed? do
┃ proceed_as_planned
┃ else
┃ raise "Not allowed!"
┃ end
┃
┃ The reason for this is not a technical but a human one. It is easier to wrap
┃ your head around a positive condition and then thinking "and else we do ...".
┃
┃ In the above example raising the error in case something is not allowed
┃ might seem so important to put it first. But when you revisit this code a
┃ while later or have to introduce a colleague to it, you might be surprised
┃ how much clearer things get when the "happy path" comes first.

Configuration

Configuration via .credo.exs

Credo is configured via a file called .credo.exs. This file can live in your project's config/ or root folder, both is fine.

This also works for umbrella projects, where you can have individual .credo.exs files for each app or a global one in the umbrella's config/ or root folder.

explain

explain allows you to dig deeper into an issue, by showing you details about the issue and the reasoning by it being reported. To be convenient, you can just copy-paste the filename:line_number:column string from the report behind the Credo command to check it out.

Credits: This is inspired by how you can snap the info from failed tests behind mix test.

The second example illustrates how the command takes a comma-separated list. All commands matching any of the passed items will be run.

You can use partial names to quickly run checks. mix credo --only todo will show all # TODO comments since todo will match Credo.Check.Design.TagTODO. mix credo --only inspect will show you all calls to IO.inspect since it matches Credo.Check.Warning.IoInspect.

Ignore some checks

To ignore selected checks, you can use the --ignore-checks or the -i alias (also aliased as --ignore).

The second example illustrates how the command takes a comma-separated list. All commands matching any of the passed items will be ignored.

You can use partial names to quickly exclude checks. mix credo --ignore nameredec will exclude all checks for variables/parameters having the same name as declared functions by matching Credo.Check.Warning.NameRedeclarationBy...

Parsing source from STDIN

You can also use Credo to parse source that has been piped directly into it.
This is especially useful when integrating with external editors. You can use this feature by passing the --read-from-stdin option as follows:

$ echo'IO.puts("hello world");'| mix credo --format=flycheck --read-from-stdin
# stdin:1: C: There is no whitespace around parentheses/brackets most of the time, but here there is.

Notice the origin if the source is coming annotated as stdin, you can change this annotation by passing it along after option like so:

$ echo'IO.puts("hello world");'| mix credo --format=flycheck --read-from-stdin /path/representing/the_current/source.ex
# /path/representing/the_current/source.ex:1: C: There is no whitespace around parentheses/brackets most of the time, but here there is.

Do note with the passed option as filename is a stub that is just used to prefix the error and so certain editors can annotate the original file.

Using Credo as stand alone

If you do not want or are not allowed to include Credo in the current project you can also install it as an archive. For this, you also need to install bunt:

You will now be able to invoke credo as usual through Mix with mix credo. This option is especially handy so credo can be used by external editors.

Show code snippets in the output

Use the --verbose switch to include the code snippets in question in the output.

Show all issues including low priority ones

Use the --all-priorities switch to include low priority issues in the output (aliased as --strict).

Issues

Like any code linter, Credo reports issues. Contrary to many other linters these issues are not created equal. Each issue is assigned a priority, based on a base priority set by the config and a dynamic component based on violation severity and location in the source code.

These priorities hint at the importance of each issue and are displayed in the command-line interface using arrows: ↑ ↗ → ↘ ↓

By default, only issues with a positive priority are part of the report (↑ ↗ →).

Checks

Consistency

These checks take a look at your code and ensure a consistent coding style. Using tabs or spaces? Both is fine, just don't mix them or Credo will tell you.

Readability

Readability checks do not concern themselves with the technical correctness of your code, but how easy it is to digest.

Refactoring Opportunities

The Refactor checks show you opportunities to avoid future problems and technical debt.

Software Design

While refactor checks show you possible problems, these checks try to highlight possibilities, like - potentially intended - duplicated code or TODO: and FIXME annotations.

Warnings

These checks warn you about things that are potentially dangerous, like a missed call to IEx.pry or a call to String.downcase without saving the result.

IDE/Editor Integrations

Some IDEs and editors are able to run mix credo in the background and mark and issues directly in the editor view.