Packages
elvis_core
4.1.1
5.0.4
5.0.3
5.0.2
5.0.1
5.0.0
retired
4.2.3
4.2.2
4.2.1
4.2.0
4.1.1
4.1.0
4.0.0
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.0
3.0.1
3.0.0
2.0.1
2.0.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0
0.7.0
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
Core library for the Erlang style reviewer
Current section
Files
Jump to
Current section
Files
src/elvis_result.erl
-module(elvis_result).
-compile({no_auto_import, [error/2]}).
%% API
-export([new/3, new/4, status/1, clean/1, print_results/1]).
-export([
get_path/1,
get_rules/1,
get_name/1,
get_items/1,
get_message/1,
get_info/1,
get_line_num/1
]).
%% Types
-export_type([item/0, rule/0, file/0, elvis_error/0, elvis_warn/0]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Records
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-type item() ::
#{
message => string(),
info => iodata(),
line_num => integer()
}.
-type rule() ::
#{
scope => atom(),
name => atom(),
items => [item()]
}.
-type file() :: #{file => string(), rules => [rule()]}.
-type elvis_error() :: #{error_msg => string(), info => list()}.
-type elvis_warn() :: #{warn_msg => string(), info => list()}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Public
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% New
-spec new
(item, string(), [term()]) -> item();
(rule, {atom(), atom()}, [item()]) -> rule();
(file, elvis_file:file(), [elvis_error() | rule()]) -> file();
(error, string(), string()) -> elvis_error();
(warn, string(), string()) -> elvis_warn().
new(item, Msg, Info) ->
new(item, Msg, Info, 0);
new(rule, {Scope, Name}, Results) ->
#{
scope => Scope,
name => Name,
items => Results
};
new(file, #{path := Path}, Rules) ->
#{file => Path, rules => Rules};
new(error, Msg, Info) ->
#{error_msg => Msg, info => Info};
new(warn, Msg, Info) ->
#{warn_msg => Msg, info => Info}.
-spec new(item, string(), [term()], integer()) -> item().
new(item, Msg, Info, LineNum) ->
#{
message => Msg,
info => Info,
line_num => LineNum
}.
%% Getters
-spec get_path(file()) -> string().
get_path(#{file := File}) ->
File.
-spec get_rules(file()) -> [rule()].
get_rules(#{rules := Rules}) ->
Rules.
-spec get_name(rule()) -> atom().
get_name(#{name := Name}) ->
Name.
-spec get_items(rule()) -> [item()].
get_items(#{items := Items}) ->
Items;
get_items(_) ->
[].
-spec get_message(item()) -> string().
get_message(#{message := Message}) ->
Message.
-spec get_info(item()) -> string().
get_info(#{info := Info}) ->
Info.
-spec get_line_num(item()) -> integer().
get_line_num(#{line_num := LineNum}) ->
LineNum.
%% Print
-spec print_results(file() | [elvis_warn()]) -> ok.
print_results(Results) ->
Format = elvis_config:from_application_or_config(output_format, colors),
print(Format, Results).
-spec print(plain | colors | parsable, [file()] | file()) -> ok.
print(_, []) ->
ok;
print(Format, [Result | Results]) ->
print(Format, Result),
print(Format, Results);
%% File
print(Format, #{file := Path, rules := Rules}) ->
case Format of
parsable ->
ok;
_ ->
case status(Rules) of
ok ->
elvis_utils:notice("# ~s [{{green-bold}}OK{{white-bold}}]", [Path]);
fail ->
elvis_utils:error("# ~s [{{red-bold}}FAIL{{white-bold}}]", [Path])
end
end,
print_rules(Format, Path, Rules);
print(_, Error) ->
print_error(Error).
print_rules(_Format, _File, []) ->
ok;
print_rules(Format, File, [#{items := []} | Items]) ->
print_rules(Format, File, Items);
print_rules(
Format,
File,
[
#{
scope := Scope,
items := Items,
name := Name
}
| EItems
]
) ->
case Format of
parsable ->
ok;
_ ->
elvis_utils:error(
" - ~p "
"(https://github.com/inaka/elvis_core/tree/main/doc_rules/~p/~p.md)",
[Name, Scope, Name]
)
end,
print_item(Format, File, Name, Items),
print_rules(Format, File, EItems);
print_rules(Format, File, [Error | Items]) ->
print_error(Error),
print_rules(Format, File, Items).
%% Item
print_item(
Format,
File,
Name,
[
#{
message := Msg,
line_num := Ln,
info := Info
}
| Items
]
) ->
case Format of
parsable ->
FMsg = io_lib:format(Msg, Info),
io:format("~s:~p:~p:~s~n", [File, Ln, Name, FMsg]);
_ ->
elvis_utils:error(" - " ++ Msg, Info)
end,
print_item(Format, File, Name, Items);
print_item(Format, File, Name, [Error | Items]) ->
print_error(Error),
print_item(Format, File, Name, Items);
print_item(_Format, _File, _Name, []) ->
ok.
print_error(#{error_msg := Msg, info := Info}) ->
elvis_utils:error_prn(Msg, Info);
print_error(#{warn_msg := Msg, info := Info}) ->
elvis_utils:warn_prn(Msg, Info).
-spec status([file() | rule()]) -> ok | fail.
status([]) ->
ok;
status([#{rules := Rules} | Files]) ->
case status(Rules) of
fail ->
fail;
ok ->
status(Files)
end;
status([#{items := []} | Rules]) ->
status(Rules);
status(_Rules) ->
fail.
%% @doc Removes files that don't have any failures.
-spec clean([file() | rule()]) -> [file() | rule()].
clean(Files) ->
clean(Files, []).
-spec clean([file() | rule()], [file() | rule()]) -> [file() | rule()].
clean([], Result) ->
lists:reverse(Result);
clean([#{rules := []} | Files], Result) ->
clean(Files, Result);
clean([File = #{rules := Rules} | Files], Result) ->
CleanRules = clean(Rules),
NewFile = File#{rules => CleanRules},
clean(Files, [NewFile | Result]);
clean([#{items := []} | Rules], Result) ->
clean(Rules, Result);
clean([Rule | Rules], Result) ->
clean(Rules, [Rule | Result]).