elint
An Erlang code linter.
Lint rules assume Erlang/OTP 29.0 or later.
Features
- Lints both
.erland.hrlfiles. - Accepts multiple files or directories and walks directories recursively.
- Analyzes every arm of every conditional, including arms the current macro state would not select.
- Embeds the description of every lint rule in the binary and prints it with
--explain. - Lets you declare intentional findings with
-elint_expect, and reports expectations that never matched a finding.
Run elint --list for the available lint rules and shared explanations;
elint --explain <name> prints one.
Example
$ elint --lint element_bif example.erl
error[element_bif]: Disallow `element/2` with a literal index; use pattern matching instead.
--> example.erl:4:5 (in first/1)
|
| first(Tuple) ->
4 | element(1, Tuple).
| ^^^^^^^^^^^^^^^^^
|
note: run `elint --explain element_bif` for details
Found 1 error(s)
The report shows the rule name in brackets, the location
(path:line:col, plus the enclosing function), the offending source line,
and a caret over the reported span. The note points to
elint --explain element_bif for the rule description. elint exits with
status 1 because at least one problem was found.
Installation
Pre-built binaries
Pre-built binaries for Linux and macOS are available from the releases page:
x86_64-unknown-linux-musl(Linux x86_64, fully static)aarch64-unknown-linux-musl(Linux arm64, fully static)aarch64-apple-darwin(macOS Apple Silicon)
For example, download the Linux x86_64 binary from the latest release with the GitHub CLI:
$ gh release download --repo sile/elint \
--pattern "elint-*.x86_64-unknown-linux-musl"
$ chmod +x elint-*.x86_64-unknown-linux-musl
$ ./elint-*.x86_64-unknown-linux-musl --version
The asset name is elint-<version>.<target>, where <target> is one of the
triples above and <version> is the release version without the leading v.
To download a specific version, pass its tag name (for example v0.1.0)
instead of the latest release:
$ gh release download v0.1.0 --repo sile/elint \
--pattern "elint-0.1.0.x86_64-unknown-linux-musl"
With Cargo
If you have cargo (the Rust package manager) installed:
$ cargo install elint
$ elint --version
See the Rust documentation to install Cargo itself.
Usage
$ elint [OPTIONS] [PATH]..
With no PATH, elint lints src/ and tests/. You can pass multiple files
or directories; directories are walked recursively, and .erl / .hrl
files are linted.
$ elint
$ elint src
$ elint src tests
$ elint path/to/module.erl
A path that you specify explicitly must exist; elint reports it as an error otherwise.
For the other command-line options, see the help:
$ elint -h
$ elint --help
Selecting lint rules
-l / --lint <RULE> restricts linting to the named rule and may be
repeated:
$ elint --lint element_bif src
$ elint --lint element_bif --lint strict_generator src
Run elint --list for the available rule names.
Explanations
--list lists the available lint rules and shared explanations, and
--explain <name> prints one:
$ elint --list
$ elint --explain element_bif
$ elint --explain elint_expect_attr
A normal lint finding points to the description of the rule it violates.
elint_expect_attr is a shared explanation referenced from rules with
legitimate intentional exceptions and from -elint_expect diagnostics.
--explain covers rule descriptions and the shared explanations under
docs/explain/; it is not a viewer for every file in docs/.
Documentation
- Preprocessing: how elint preprocesses Erlang source, including conditional-branch exploration and include resolution policy.
- Diagnostics: how elint reports problems and why
-error/-warningdirectives are ignored. - The
-elint_expectattribute: the-elint_expectnotation and suppression.
docs/diagnostics.md and docs/preprocessing.md are meant to be read on
GitHub; they are not --explain targets.
Suppressing intentional findings
When a finding is intentional, declare it with an -elint_expect attribute
so elint suppresses it and reports an expectation that never matched:
$ elint --explain elint_expect_attr
See the -elint_expect attribute for
the notation.
Diagnostics and exit status
Findings and analysis errors are written to stderr. elint exits with status 1 when at least one problem is reported, and status 0 when there are none. See docs/diagnostics.md for the output format.