README.md

# `elvis` [![CI][build-badge]][elvis]

[elvis]: https://github.com/inaka/elvis
[build-badge]: https://github.com/inaka/elvis/workflows/build/badge.svg

![Elvis Presley dancing](https://www.reactiongifs.com/wp-content/uploads/2013/01/elvis-dance.gif)

`elvis`, the Erlang style reviewer, is the command-line interface for
[`elvis_core`](https://github.com/inaka/elvis_core).

## What is `elvis`?

`elvis` is an Erlang generic style reviewer that focuses on code and configuration consistency,
as well as readability, across your whole code base. By the very nature of the rules applied from
`elvis_core` it can also be considered a learning tool, by trying to generalize good practices and
allowing teams to adapt it to their own specific needs, while fostering discussions around code
conventions.

### Advantages of using it

Some of the advantages of using `elvis` are:

* enabling consistency in style across all your code base
* encouraging the development team to sit down and talk about code conventions
* allowing continuous monitoring of code quality
* helping developers avoid repeated mistakes that can be automatically detected
* providing homogenisation among different projects in a company, therefore facilitating project
switching for developers, as well as allowing easier code sharing between projects
* learning, since some of the conventions it proposes are themselves the distilled result of
working in very large code bases

## Installation

To use `elvis` as a standalone tool, you need to:

```console
git clone https://github.com/inaka/elvis
cd elvis
rebar3 escriptize
export PATH=${PWD}/_build/default/bin:${PATH}
```

(to make the env. variable export more permanent add it to your shell's configuration file,
i.e. `.bashrc`, `.zshrc`, ...)

Now run it by calling `elvis` (or `elvis help`), and you should get to the `Usage: elvis`
instructions.

## Usage

The most common use case is to `cd` into a folder containing an `elvis.config` file
and executing `elvis rock`.

If you just execute `elvis` with no arguments or options you'll get to the usage instructions
outlined in this README.

## Options

While you can get a more complete list of options by executing `elvis help`, we try to keep them
documented below.

### `--code-path <dir>` (`-p <dir>`)

Adds `<dir>` to the analysis' code path.

### `--commands`

Outputs the list of commands under stood by `elvis`.

#### `git-branch <branch | commit>`

Executes `elvis` on source files that have changed since `<branch>` or `<commit>`.

#### `git-hook`

Executes `elvis` (with the specific configuration file) on the pre-commit hook Git-staged files.

#### `install git-hook`

Installs `elvis` in your current Git repository, as a pre-commit hook.

#### `rock [file...]`

Executes `elvis` analysis on identified files. It will, by default, consider all the files
in the configuration (i.e. either `elvis.config` or the path set by option `--config`).

### `--config <file>` (`-c <file>`)

Allows providing the path to the config. file (by default `elvis.config` is assumed).

### `--help` (`-h`)

Shows help information.

### `--keep-rocking` (`-k`)

Doesn't stop analysis when erroring out on a file, if given a list of files to analyse.

### `--output-format <plain | colors | parsable>`

Allows controlling the output format of the analysis' results.

The default value is `colors`.

`plain` will output results without colors.
`parsable` will allow for consumption by systems (it's less readable for humans).

### `--parallel <n | auto>` (`-P <n | auto>`)

Allows analyzing files concurrently.

Use `n` to set the desired number of parallel workers, or `auto` to have the application choose
an appropriate value (based on the number of schedulers).

### `--quiet` (`-q`)

Allows suppressing all output. The exit code will still be non-`0` if there are failing rules.

### `--verbose` (`-V`)

Allows verbose output.

### `--version` (`-v`)

Outputs the application's version.

## Configuration

`elvis` is configured via `elvis_core`'s `elvis.config` as detailed under
[`elvis_core / Configuration`](https://github.com/inaka/elvis_core?tab=readme-ov-file#configuration).

### Rules

A reference of all rules implemented in `elvis` can be found in `elvis_core`'s [RULES.md](https://github.com/inaka/elvis_core/blob/main/RULES.md).

### User-defined rules

If you have implemented `elvis` rule that are in your local repository or in one of
your dependencies, you can add these rule to your `elvis.config` file and
tell `elvis` where to find the `.beam` that contains the compiled rule using
the `--code-path` option.

For example, if the rule is in one of your dependencies, you can run `elvis rock -p deps/elvis_rules/ebin -c elvis.config`.

## As a Git hook

`elvis` can be used as a [`git` pre-commit hook](https://git-scm.com/book/en/Customizing-Git-Git-Hooks#Client-Side-Hooks)
using the `git-hook` command (installable via `install git-hook`) as:

```sh
#!/bin/sh
elvis git-hook
```

This will have `elvis` execute on staged files, as per its configuration.

If any rule fails, `elvis` exits with a non-zero code, which signals to `git` that the commit
shouldn't be made.

**Note**: your pre-commit hook script should be executable (i.e. by running
`chmod +x .git/hooks/pre-commit`), otherwise `git` won't be able to execute it.

## As a webhook

`elvis` can be used as a GitHub [webhook](https://developer.github.com/v3/repos/hooks/) for
`pull request` (PR) events, by calling the `elvis_webhook:event/1` function. This will add
a comment in each file and rule that is broken, analyzing only the files associated with the PR.

Since GitHub's API needs a valid username and password to allow the creation of
reviews on PRs, parameters `github_user` and `github_password` need to be
added to `elvis`'s configuration file (mind you that the credentials used
must be from an admin. of the repo or someone with permissions for requesting changes
to PRs).

The `elvis_webhook:event/1` function takes a map containing the keys `headers` and `body`,
whose values should be the map of headers and the body from the GitHub's event
request.

```erlang
Headers = #{<<"X-GitHub-Event">>, <<"pull_request">>},
Body = <<"{}">>, %% JSON data from GitHub's event.
Request = #{headers => Headers, body => Body},
elvis:webhook(Request).
```

The extension to the configuration is as follows:

```erlang
[
  {elvis, [
    {config, [...]},
    %% webhook configuration parameters
    {github_user, "user"},
    {github_password, "password"}
  ]}
].
```

## Documentation

You can generate local documentation with `rebar3 ex_doc` and then access it with `open doc/index.html`.

## Contributing

`elvis` is a FOSS application, and as such contributions are welcome. Be sure to read
the [contributing guide](CONTRIBUTING.md) for more detailed information.

## License

`elvis` is licensed under the [Apache License, Version 2.0](LICENSE).

## Inspiration

`elvis` got some of its inspiration from [HoundCI](https://houndci.com/).