Skip to content

Commit

Permalink
Merge pull request #106 from define-null/feature/parsable-output
Browse files Browse the repository at this point in the history
Add parsable option in order to output results in the dialyzer-like format
  • Loading branch information
elbrujohalcon authored Apr 11, 2019
2 parents d9033ca + 66d6182 commit 00b4372
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 24 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,17 @@ list of items with the following structure `{Module, Function, RuleConfig}` or
`disable` certain rules if you want to just by specifying the rule in the `rules`
key and passing `disable` as its third parameter.

`output_format` is used to configure the output format. Possible values are `colors`,
`plain` and `parsable`. The latter could be use for the automated parsing and has a
format very close to dialyzer in a form `FILE:LINE:RULE:MESSAGE`:

```
src/example.erl:1:god_modules:This module has too many functions (56). Consider breaking it into a number of modules.
src/example_a.erl:341:no_debug_call:Remove the debug call to io:format/2 on line 341.
src/example_a.erl:511:used_ignored_variable:Ignored variable is being used on line 511 and column 54.
src/example_a.erl:1252:used_ignored_variable:Ignored variable is being used on line 1252 and column 21.
```

**IMPORTANT:** `disable` will only work if you also provided a `ruleset` as shown above.

Let's say you like your files to have a maximum of 90 characters per line and
Expand Down
2 changes: 1 addition & 1 deletion src/elvis_core.erl
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ apply_rules(Config, File) ->
{RulesResults, _, _} = lists:foldl(fun apply_rule/2, Acc, Rules),

Results = elvis_result:new(file, File, RulesResults),
elvis_result:print(Results),
elvis_result:print_results(Results),
Results.

apply_rule({Module, Function}, {Result, Config, File}) ->
Expand Down
78 changes: 56 additions & 22 deletions src/elvis_result.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
new/4,
status/1,
clean/1,
print/1
print_results/1
]).

-export([
Expand Down Expand Up @@ -105,33 +105,67 @@ get_line_num(#{line_num := LineNum}) -> LineNum.

%% Print

-spec print(item() | rule() | elvis_error() | [file()]) -> ok.
print([]) ->
-spec print_results(file()) -> ok.
print_results(Results) ->
Format = application:get_env(elvis, output_format, colors),
print(Format, Results).

-spec print(plain | colors | parsable, [file()] | file()) -> ok.
print(_, []) ->
ok;
print([Result | Results]) ->
print(Result),
print(Results);
print(Format, [Result | Results]) ->
print(Format, Result),
print(Format, Results);
%% File
print(#{file := File, rules := Rules}) ->
print(Format, #{file := File, rules := Rules}) ->
Path = elvis_file:path(File),
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])
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);
%% Rule
print(#{items := []}) ->
print_rules(Format, Path, Rules);
print(_, Error) ->
print_error(Error).

print_rules(_Format, _File, []) ->
ok;
print(#{name := Name, items := Items}) ->
elvis_utils:error(" - ~s", [atom_to_list(Name)]),
print(Items);
print_rules(Format, File, [#{items := []} | Items]) ->
print_rules(Format, File, Items);
print_rules(Format, File, [#{items := Items, name := Name} | EItems]) ->
case Format of
parsable -> ok;
_ ->
elvis_utils:error(" - ~s", [atom_to_list(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(#{message := Msg, info := Info}) ->
elvis_utils:error(" - " ++ Msg, Info);
%% Error
print(#{error_msg := Msg, info := Info}) ->
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).

-spec status([file() | rule()]) -> ok | fail.
Expand Down
22 changes: 21 additions & 1 deletion test/elvis_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
rock_with_rebar_default_config/1,
rock_this/1,
rock_without_colors/1,
rock_with_parsable/1,
rock_with_no_output_has_no_output/1,
rock_with_errors_has_output/1,
rock_without_errors_has_no_output/1,
Expand Down Expand Up @@ -190,6 +191,24 @@ rock_without_colors(_Config) ->
_:{badmatch, []} -> ok
end.

-spec rock_with_parsable(config()) -> ok.
rock_with_parsable(_Config) ->
{ok, Default} = application:get_env(elvis, output_format),
application:set_env(elvis, output_format, parsable),
ConfigPath = "../../config/test.config",
ElvisConfig = elvis_config:load_file(ConfigPath),
Fun = fun() -> elvis_core:rock(ElvisConfig) end,
Expected = ".*\\.erl:\\d:[a-zA-Z0-9_]+:.*",
ok = try check_some_line_output(Fun, Expected, fun matches_regex/2) of
Result ->
io:format("~p~n", [Result])
catch
_:{badmatch, []} ->
ct:fail("Unexpected result ~p")
after
application:set_env(elvis, output_format, Default)
end.

-spec rock_with_no_output_has_no_output(config()) -> ok.
rock_with_no_output_has_no_output(_Config) ->
application:set_env(elvis, no_output, true),
Expand Down Expand Up @@ -424,5 +443,6 @@ check_no_line_output(Fun) ->
matches_regex(Result, Regex) ->
case re:run(Result, Regex) of
{match, _} -> true;
nomatch -> false
nomatch ->
false
end.

0 comments on commit 00b4372

Please sign in to comment.