Skip to content

Latest commit

 

History

History
206 lines (174 loc) · 8.57 KB

RULES.md

File metadata and controls

206 lines (174 loc) · 8.57 KB

Rules

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.

Style rules

Project rules

Rulesets

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).
  • 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
          }
        ]
    }
]}].

The -elvis attribute

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] }}]).
...

Disabling rules

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!

The "ignore" option

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 for elvis_style-based rules only)
  • module, function and arity: ignore => [{mod, fun, arity}] (available for elvis_style-based rules only)

BEAM files

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.

Example elvis.config

[{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 => [] }
    ]}
  , {verbose, true}
]}].