Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ 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).
- `erl_files_strict`, for Erlang source files (all applicable rules).
- `gitignore`, for `.gitignore` files.
- `hrl_files`, for Erlang header files.
- `hrl_files`, for Erlang header files (pre-defined rule set).
- `hrl_files_strict`, for Erlang header files (all applicable rules).
- `rebar_config`, for rebar configuration files.

Custom rulesets are defined in a `{<ruleset>, #{}}` tuple in `elvis`' configuration. Each key in the
Expand Down Expand Up @@ -189,9 +190,17 @@ rules only**)
Specific rules (signaled with ![](https://img.shields.io/badge/BEAM-yes-orange)) allow you to
perform analysis directly on beam files (instead of source code).

To target these, specifiy `beam_files` (or `beam_files_strict`), instead of `erl_files` (or
`erl_files_strict`), as the target `ruleset`.

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.

## HRL files

Specific rules (signaled with ![](https://img.shields.io/badge/HRL--only-yes-magenta)) are reserved
for `.hrl` files.

## Example `elvis.config`

```erlang
Expand Down
2 changes: 1 addition & 1 deletion config/elvis-test-hrl-files.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{config, [
#{
dirs => ["../../_build/test/lib/elvis_core/test/examples/"],
filter => "test-*.hrl",
filter => "test_*.hrl",
ruleset => hrl_files
}
]}
Expand Down
2 changes: 1 addition & 1 deletion doc_rules/elvis_style/no_nested_hrls.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# No Types [![](https://img.shields.io/badge/since-4.1.0-blue)](https://github.com/inaka/elvis_core/releases/tag/4.1.0)
# No Types [![](https://img.shields.io/badge/since-4.1.0-blue)](https://github.com/inaka/elvis_core/releases/tag/4.1.0) ![](https://img.shields.io/badge/HRL--only-yes-magenta)

`-include` and `-include_lib` attributes **in header files** should be avoided.

Expand Down
2 changes: 1 addition & 1 deletion doc_rules/elvis_style/no_specs.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# No Specs [![](https://img.shields.io/badge/since-3.0.0-blue)](https://github.com/inaka/elvis_core/releases/tag/3.0.0)
# No Specs [![](https://img.shields.io/badge/since-3.0.0-blue)](https://github.com/inaka/elvis_core/releases/tag/3.0.0) ![](https://img.shields.io/badge/HRL--only-yes-magenta)

`-spec` attributes **in header files** should be avoided.

Expand Down
2 changes: 1 addition & 1 deletion doc_rules/elvis_style/no_types.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# No Types [![](https://img.shields.io/badge/since-3.0.0-blue)](https://github.com/inaka/elvis_core/releases/tag/3.0.0)
# No Types [![](https://img.shields.io/badge/since-3.0.0-blue)](https://github.com/inaka/elvis_core/releases/tag/3.0.0) ![](https://img.shields.io/badge/HRL--only-yes-magenta)

`-type` attributes **in header files** should be avoided.

Expand Down
2 changes: 1 addition & 1 deletion doc_rules/elvis_text_style/prefer_unquoted_atoms.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ Use an Erlang code formatter that enforces strict rules for quoted atoms.
## Example configuration

```erlang
{elvis_style, prefer_unquoted_atoms, #{}}
{elvis_text_style, prefer_unquoted_atoms, #{}}
```
1 change: 0 additions & 1 deletion elvis.config
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
{elvis_style, invalid_dynamic_call, #{ignore => [elvis_core]}},
{elvis_style, dont_repeat_yourself, #{min_complexity => 20}},
{elvis_style, no_debug_call, #{ignore => [elvis_result, elvis_utils]}},
{elvis_style, atom_naming_convention, #{ignore => [elvis_task]}},
{elvis_style, god_modules, #{ignore => [elvis_style]}},
{elvis_style, no_throw, disable}
],
Expand Down
6 changes: 3 additions & 3 deletions src/elvis_config.erl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ load(Key, ElvisConfig, Default) ->
load_initial(AppConfig) ->
ElvisConfig = proplists:get_value(elvis, AppConfig, []),
RulesetsConfig = proplists:get_value(rulesets, ElvisConfig, #{}),
elvis_rulesets:set_rulesets(RulesetsConfig),
elvis_ruleset:set_rulesets(RulesetsConfig),
ElvisConfig.

ensure_config_list(config, Config) when is_map(Config) ->
Expand Down Expand Up @@ -192,12 +192,12 @@ files(#{}) ->
rules(Rules) when is_list(Rules) ->
lists:map(fun rules/1, Rules);
rules(#{rules := UserRules, ruleset := RuleSet}) ->
DefaultRules = elvis_rulesets:rules(RuleSet),
DefaultRules = elvis_ruleset:rules(RuleSet),
merge_rules(UserRules, DefaultRules);
rules(#{rules := Rules}) ->
Rules;
rules(#{ruleset := RuleSet}) ->
elvis_rulesets:rules(RuleSet);
elvis_ruleset:rules(RuleSet);
rules(#{}) ->
[].

Expand Down
7 changes: 3 additions & 4 deletions src/elvis_gitignore.erl
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
-module(elvis_gitignore).
-behaviour(elvis_ruleset).

-export([required_patterns/3, forbidden_patterns/3]).
-export([required_patterns/3, forbidden_patterns/3, default/1]).

-define(REQUIRED_PATTERN, "Your .gitignore file should contain pattern '~s'.").
-define(FORBIDDEN_PATTERN, "Your .gitignore file should not contain pattern '~s'.").

-hank([{unnecessary_function_arguments, [{required_patterns, 3}, {forbidden_patterns, 3}]}]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Default values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec default(Rule :: atom()) -> DefaultRuleConfig :: term().
-spec default(RuleName :: atom()) -> DefaultRuleConfig :: #{atom() := term()}.
default(required_patterns) ->
#{
regexes =>
Expand Down
13 changes: 2 additions & 11 deletions src/elvis_project.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-module(elvis_project).
-behaviour(elvis_ruleset).

-export([default/1, no_branch_deps/3, protocol_for_deps/3, old_configuration_format/3]).

Expand All @@ -18,21 +19,11 @@
"new format is."
).

% These are part of a non-declared "behaviour"
% The reason why we don't try to handle them with different arity is
% that arguments are ignored in different positions (1 and 3) so that'd
% probably be messier than to ignore the warning
-hank([
{unnecessary_function_arguments, [
{old_configuration_format, 3}, {no_branch_deps, 3}, {protocol_for_deps, 3}
]}
]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Default values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec default(Rule :: atom()) -> DefaultRuleConfig :: term().
-spec default(RuleName :: atom()) -> DefaultRuleConfig :: #{atom() := term()}.
default(no_branch_deps) ->
#{ignore => []};
default(protocol_for_deps) ->
Expand Down
217 changes: 217 additions & 0 deletions src/elvis_ruleset.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
-module(elvis_ruleset).

-format(#{inline_items => none}).

-export([rules/1, set_rulesets/1]).
-export([default/2]).

-callback default(RuleName :: atom()) -> DefaultRuleConfig :: #{atom() := term()}.

-spec default(Module :: module(), RuleName :: atom()) -> DefaultRuleConfig :: #{atom() := term()}.
default(Module, RuleName) ->
Module:default(RuleName).

-spec set_rulesets(#{atom() => list()}) -> ok.
set_rulesets(RuleSets) ->
Tid = ensure_clean_table(),
lists:foreach(
fun({Name, Rules}) -> true = ets:insert(Tid, {Name, Rules}) end,
maps:to_list(RuleSets)
).

-spec rules(Group :: atom()) -> [elvis_core:rule()].
rules(Group) ->
Rules =
case Group of
gitignore ->
gitignore_rules();
hrl_files ->
hrl_files_rules();
hrl_files_strict ->
hrl_files_strict_rules();
erl_files ->
erl_files_rules();
erl_files_strict ->
erl_files_strict_rules();
beam_files ->
beam_files_rules();
beam_files_strict ->
beam_files_strict_rules();
rebar_config ->
rebar_config_rules();
elvis_config ->
elvis_config_rules();
_ ->
try
ets:lookup_element(?MODULE, Group, 2)
catch
error:badarg ->
[]
end
end,
lists:map(
fun({Mod, Rule}) -> {Mod, Rule, default(Mod, Rule)} end,
Rules
).

ensure_clean_table() ->
case ets:info(?MODULE) of
undefined ->
ets:new(?MODULE, [set, named_table, {keypos, 1}, public]);
_ ->
true = ets:delete_all_objects(?MODULE),
?MODULE
end.

gitignore_rules() ->
[
{elvis_gitignore, forbidden_patterns},
{elvis_gitignore, required_patterns}
].

hrl_files_rules() ->
(erl_files_rules() ++ hrl_only_files_rules()) -- doesnt_work_on_hrl_files().

hrl_only_files_rules() ->
[
{elvis_style, no_nested_hrls},
{elvis_style, no_specs},
{elvis_style, no_types}
].

hrl_files_strict_rules() ->
erl_files_strict_rules() -- doesnt_work_on_hrl_files().

doesnt_work_on_hrl_files() ->
[
{elvis_style, behaviour_spelling},
{elvis_style, dont_repeat_yourself},
{elvis_style, export_used_types},
{elvis_style, function_naming_convention},
{elvis_style, god_modules},
{elvis_style, invalid_dynamic_call},
{elvis_style, max_anonymous_function_arity},
{elvis_style, max_function_clause_length},
{elvis_style, max_function_length},
{elvis_style, ms_transform_included},
{elvis_style, no_call},
{elvis_style, no_common_caveats_call},
{elvis_style, no_init_lists},
{elvis_style, no_macros},
{elvis_style, no_spec_with_records},
{elvis_style, param_pattern_matching},
{elvis_style, private_data_types},
{elvis_style, state_record_and_type}
].

erl_files_rules() ->
elvis_style_rules() ++ elvis_text_style_rules().

elvis_style_rules() ->
[
{elvis_style, atom_naming_convention},
{elvis_style, behaviour_spelling},
{elvis_style, consistent_variable_casing},
{elvis_style, dont_repeat_yourself},
{elvis_style, export_used_types},
{elvis_style, function_naming_convention},
{elvis_style, god_modules},
{elvis_style, invalid_dynamic_call},
{elvis_style, macro_module_names},
{elvis_style, macro_names},
{elvis_style, max_anonymous_function_arity},
{elvis_style, max_function_arity},
{elvis_style, module_naming_convention},
{elvis_style, nesting_level},
{elvis_style, no_author},
{elvis_style, no_behavior_info},
{elvis_style, no_block_expressions},
{elvis_style, no_boolean_in_comparison},
{elvis_style, no_catch_expressions},
{elvis_style, no_debug_call},
{elvis_style, no_dollar_space},
{elvis_style, no_if_expression},
{elvis_style, no_import},
{elvis_style, no_match_in_condition},
{elvis_style, no_nested_try_catch},
{elvis_style, no_operation_on_same_value},
{elvis_style, no_single_clause_case},
{elvis_style, no_single_match_maybe},
{elvis_style, no_space_after_pound},
{elvis_style, no_space},
{elvis_style, no_spec_with_records},
{elvis_style, no_successive_maps},
{elvis_style, no_throw},
{elvis_style, numeric_format},
{elvis_style, operator_spaces},
{elvis_style, param_pattern_matching},
{elvis_style, private_data_types},
{elvis_style, used_ignored_variable},
{elvis_style, variable_naming_convention}
].

elvis_text_style_rules() ->
[
{elvis_text_style, line_length},
{elvis_text_style, no_tabs},
{elvis_text_style, no_trailing_whitespace}
].

erl_files_strict_rules() ->
erl_files_rules() ++ elvis_style_stricter_rules() ++ elvis_text_style_stricter_rules().

elvis_style_stricter_rules() ->
[
{elvis_style, always_shortcircuit},
{elvis_style, consistent_generic_type},
{elvis_style, max_function_clause_length},
{elvis_style, max_function_length},
{elvis_style, max_module_length},
{elvis_style, ms_transform_included},
{elvis_style, no_call},
{elvis_style, no_common_caveats_call},
{elvis_style, no_init_lists},
{elvis_style, no_macros},
{elvis_style, state_record_and_type}
].

elvis_text_style_stricter_rules() ->
[
{elvis_text_style, no_redundant_blank_lines},
{elvis_text_style, prefer_unquoted_atoms}
].

beam_files_rules() ->
erl_files_rules() -- doesnt_work_on_beam_files().

beam_files_strict_rules() ->
erl_files_strict_rules() -- doesnt_work_on_beam_files().

doesnt_work_on_beam_files() ->
not_on_beam() ++ elvis_text_style_rules() ++ elvis_text_style_stricter_rules().

not_on_beam() ->
[
{elvis_style, macro_module_names},
{elvis_style, macro_names},
{elvis_style, max_function_clause_length},
{elvis_style, max_function_length},
{elvis_style, max_module_length},
{elvis_style, no_dollar_space},
{elvis_style, no_macros},
{elvis_style, no_space_after_pound},
{elvis_style, no_space},
{elvis_style, numeric_format},
{elvis_style, operator_spaces}
].

rebar_config_rules() ->
[
{elvis_project, no_branch_deps},
{elvis_project, protocol_for_deps}
].

elvis_config_rules() ->
[
{elvis_project, old_configuration_format}
].
Loading