In this document, we present links to the rules supported by elvis
and the available configuration
options for each one. At the end of this document, we share an
example elvis.config
file you can copy-paste (in your project's root) and
then tweak to your liking.
Rules and other significant changes, like new options (starting from version 0.4.0
), are
identified with (since ...)
for convenience purposes.
- Always Shortcircuit
- Atom Naming Convention
- Behaviour Spelling
- Consistent Generic Type
- Consistent Variable Casing
- Don't Repeat Yourself
- Export Used Types
- Function Naming Convention
- God Modules
- Invalid Dynamic Calls
- Line Length
- Macro Module Names
- Macro Names
- Max Anonymous Function Arity
- Max Function Arity
- Max Function Length
- Max Function Clause Length
- Max Module Length
- Module Naming Convention
- Nesting Level
- No author
- No Behavior Info
- No Block Expressions
- No call
- No catch expressions
- No Common Caveats
- No debug call
- No If Expression
- No Import
- No Macros
- No Match in Condition
- No Nested try...catch Blocks
- No Single-Clause Case Statements
- No Space after #
- No Space
- No Spec With Records
- No Specs
- No Successive Maps
- No Tabs
- No throw
- No Trailing Whitespace
- No Types
- Numeric Format
- Operator Spaces
- Param Pattern Matching
- Private Data Types
- State Record and Type
- Used Ignored Variable
- Variable Naming Convention
- No Init Lists
- Prefer Unquoted Atoms
- ms_transform included
- No deps master erlang.mk - deprecated
- No deps master rebar - deprecated
- No deps with branches
- Old configuration format
- Protocol for deps erlang.mk - deprecated
- Protocol for deps rebar - deprecated
- Protocol for deps
Rulesets in elvis
are used to group individual rules together and can save a lot of duplication.
elvis
currently has five pre-defined rulesets, but gives you the ability to specify custom
rulesets in the configuration file.
The six pre-defined rulesets are:
elvis_config
, for elvis configuration files.erl_files
, for Erlang source files (pre-defined rule set).erl_files_strict
, for Erlang source files (all available rules).gitignore
, for.gitignore
files.hrl_files
, for Erlang header files.makefiles
, for Makefiles.rebar_config
, for rebar configuration files.
Custom rulesets are defined in a {<ruleset>, #{}}
tuple in elvis
' configuration. Each key in the
map represents the ruleset name and is mapped to a list of rules as otherwise defined in a standard
ruleset.
Example configuration with a custom ruleset (named my_ruleset
):
[{elvis, [
{rulesets,
#{ my_ruleset => [{elvis_style, max_module_length, #{}}
, {elvis_style, no_common_caveats_call, #{}}
]
}
}
, {config,
[#{ dirs => ["src/**" , "test/**"]
, filter => "*.erl"
, ruleset => my_ruleset
}
]
}
]}].
Per-module rules can also be configured using attribute -elvis(_).
, with the same content as is
expected in elvis.config
's rules
option, e.g.:
-elvis([{elvis_style, no_behavior_info, #{}}]).
-elvis([{elvis_style, no_nested_try_catch}]).
Note: a single attribute with a list of rules is the same as multiple attributes with a list of rules each - the rules are "merged" - as in:
-elvis([{elvis_style, no_behavior_info, #{}}, {elvis_style, no_nested_try_catch}]).
In this case, the ignore
attribute has limited value since it'll be ignored for "other" modules.
You can always play with the following, but results may not be surprising.
-module(mymodule).
-elvis([{elvis_style, nesting_level, #{ level => 4, ignore => [mymodule] }}]).
...
Rules (as used by you, in elvis.config
) come in 3-element tuples (if you use options) or 2-element
tuples (if you don't). To disable a rule, you need to use the 3-element form, and the reserved word
disable
: let's consider you want to disable rule elvis_text_style:no_tabs
; you do
{elvis_text_style, no_tabs, disable}
, and you're done!
Module-level rules implement a generic ignore mechanism that allows skipping analysis in elements of
your choice.
It suffices to add the ignore
list to your rules, as per the example below.
-elvis([{elvis_style, invalid_dynamic_call, #{ ignore => [elvis_core]}}]).
-elvis([{elvis_style, no_debug_call, #{ ignore => [elvis_result, elvis_utils]}}]).
You can add the exceptions using the following syntax:
- whole module:
ignore => [mod]
- functions (by name only):
ignore => [{mod, fun}]
(available forelvis_style
-based rules only) - module, function and arity:
ignore => [{mod, fun, arity}]
(available forelvis_style
-based rules only)
Specific rules (signaled with "Works on .beam
file? Yes!") allow you to perform analysis directly
on beam files (instead of source code).
Though this analysis may be useful for pin-pointing certain elements, beware that, e.g., reported line numbers will most surely not correspond with those in the source file.
[{elvis, [
{config, [
#{ dirs => ["src/**", "test/**"]
, filter => "*.erl"
, ruleset => erl_files
% these are not enforced by default, so are added here for completeness
, rules => [{elvis_style, max_module_length, #{}}
, {elvis_style, no_common_caveats_call, #{}}
]
}
, #{ dirs => ["include/**"]
, filter => "*.hrl"
, ruleset => hrl_files
}
, #{ dirs => ["."]
, filter => "Makefile"
, ruleset => makefiles
, rules => [] }
, #{ dirs => ["."]
, filter => "rebar.config"
, ruleset => rebar_config
, rules => [] }
, #{ dirs => ["."]
, filter => "elvis.config"
, ruleset => elvis_config
, rules => [] }
, #{ dirs => ["."]
, filter => ".gitignore"
, ruleset => gitignore }
]}
, {verbose, true}
]}].