Browse Source

Fail if any dialyzer warnings aren't unknowns

pull/132/head
James Fish 10 years ago
parent
commit
52319655a5
1 changed files with 48 additions and 25 deletions
  1. +48
    -25
      src/rebar_prv_dialyzer.erl

+ 48
- 25
src/rebar_prv_dialyzer.erl View File

@ -67,16 +67,19 @@ do(State) ->
Apps = rebar_state:project_apps(State), Apps = rebar_state:project_apps(State),
try try
{ok, State1} = update_proj_plt(State, Plt, Apps),
succ_typings(State1, Plt, Apps)
do(State, Plt, Apps)
catch catch
throw:{dialyzer_error, Error} -> throw:{dialyzer_error, Error} ->
{error, {?MODULE, {error_processing_apps, Error, Apps}}}
{error, {?MODULE, {error_processing_apps, Error}}};
throw:{dialyzer_warnings, Warnings} ->
{error, {?MODULE, {dialyzer_warnings, Warnings}}}
end. end.
-spec format_error(any()) -> iolist(). -spec format_error(any()) -> iolist().
format_error({error_processing_apps, Error, _Apps}) ->
format_error({error_processing_apps, Error}) ->
io_lib:format("Error in dialyzing apps: ~s", [Error]); io_lib:format("Error in dialyzing apps: ~s", [Error]);
format_error({dialyzer_warnings, Warnings}) ->
io_lib:format("Warnings occured running dialyzer: ~b", [Warnings]);
format_error(Reason) -> format_error(Reason) ->
io_lib:format("~p", [Reason]). io_lib:format("~p", [Reason]).
@ -106,11 +109,22 @@ otp_version(Release) ->
[Vsn] = binary:split(Contents, [<<$\n>>], [global, trim]), [Vsn] = binary:split(Contents, [<<$\n>>], [global, trim]),
[_ | _] = unicode:characters_to_list(Vsn). [_ | _] = unicode:characters_to_list(Vsn).
do(State, Plt, Apps) ->
{PltWarnings, State1} = update_proj_plt(State, Plt, Apps),
{Warnings, State2} = succ_typings(State1, Plt, Apps),
case PltWarnings + Warnings of
0 ->
{ok, State2};
TotalWarnings ->
throw({dialyzer_warnings, TotalWarnings})
end.
update_proj_plt(State, Plt, Apps) -> update_proj_plt(State, Plt, Apps) ->
{Args, _} = rebar_state:command_parsed_args(State), {Args, _} = rebar_state:command_parsed_args(State),
case proplists:get_value(update_plt, Args) of case proplists:get_value(update_plt, Args) of
false -> false ->
{ok, State};
{0, State};
_ -> _ ->
do_update_proj_plt(State, Plt, Apps) do_update_proj_plt(State, Plt, Apps)
end. end.
@ -238,26 +252,28 @@ check_plt(State, Plt, OldList, FilesList) ->
Old = sets:from_list(OldList), Old = sets:from_list(OldList),
Files = sets:from_list(FilesList), Files = sets:from_list(FilesList),
Remove = sets:subtract(Old, Files), Remove = sets:subtract(Old, Files),
{ok, State1} = remove_plt(State, Plt, sets:to_list(Remove)),
{RemWarnings, State1} = remove_plt(State, Plt, sets:to_list(Remove)),
Check = sets:intersection(Files, Old), Check = sets:intersection(Files, Old),
{ok, State2} = check_plt(State1, Plt, sets:to_list(Check)),
{CheckWarnings, State2} = check_plt(State1, Plt, sets:to_list(Check)),
Add = sets:subtract(Files, Old), Add = sets:subtract(Files, Old),
add_plt(State2, Plt, sets:to_list(Add)).
{AddWarnings, State3} = add_plt(State2, Plt, sets:to_list(Add)),
?DEBUG("~p", [[RemWarnings, CheckWarnings, AddWarnings]]),
{RemWarnings + CheckWarnings + AddWarnings, State3}.
remove_plt(State, _Plt, []) -> remove_plt(State, _Plt, []) ->
{ok, State};
{0, State};
remove_plt(State, Plt, Files) -> remove_plt(State, Plt, Files) ->
?INFO("Removing ~b files from ~p...", [length(Files), Plt]), ?INFO("Removing ~b files from ~p...", [length(Files), Plt]),
run_plt(State, Plt, plt_remove, Files). run_plt(State, Plt, plt_remove, Files).
check_plt(State, _Plt, []) -> check_plt(State, _Plt, []) ->
{ok, State};
{o, State};
check_plt(State, Plt, Files) -> check_plt(State, Plt, Files) ->
?INFO("Checking ~b files in ~p...", [length(Files), Plt]), ?INFO("Checking ~b files in ~p...", [length(Files), Plt]),
run_plt(State, Plt, plt_check, Files). run_plt(State, Plt, plt_check, Files).
add_plt(State, _Plt, []) -> add_plt(State, _Plt, []) ->
{ok, State};
{0, State};
add_plt(State, Plt, Files) -> add_plt(State, Plt, Files) ->
?INFO("Adding ~b files to ~p...", [length(Files), Plt]), ?INFO("Adding ~b files to ~p...", [length(Files), Plt]),
run_plt(State, Plt, plt_add, Files). run_plt(State, Plt, plt_add, Files).
@ -274,12 +290,13 @@ run_plt(State, Plt, Analysis, Files) ->
build_proj_plt(State, Plt, Files) -> build_proj_plt(State, Plt, Files) ->
BasePlt = get_base_plt_location(State), BasePlt = get_base_plt_location(State),
BaseFiles = get_base_plt_files(State), BaseFiles = get_base_plt_files(State),
{ok, State1} = update_base_plt(State, BasePlt, BaseFiles),
{BaseWarnings, State1} = update_base_plt(State, BasePlt, BaseFiles),
?INFO("Copying ~p to ~p...", [BasePlt, Plt]), ?INFO("Copying ~p to ~p...", [BasePlt, Plt]),
_ = filelib:ensure_dir(Plt), _ = filelib:ensure_dir(Plt),
case file:copy(BasePlt, Plt) of case file:copy(BasePlt, Plt) of
{ok, _} -> {ok, _} ->
check_plt(State1, Plt, BaseFiles, Files);
{CheckWarnings, State2} = check_plt(State1, Plt, BaseFiles, Files),
{BaseWarnings + CheckWarnings, State2};
{error, Reason} -> {error, Reason} ->
Error = io_lib:format("Could not copy PLT from ~p to ~p: ~p", Error = io_lib:format("Could not copy PLT from ~p to ~p: ~p",
[BasePlt, Plt, file:format_error(Reason)]), [BasePlt, Plt, file:format_error(Reason)]),
@ -353,22 +370,28 @@ app_to_files(App) ->
Files. Files.
run_dialyzer(State, Opts) -> run_dialyzer(State, Opts) ->
Warnings = rebar_state:get(State, dialyzer_warnings, default_warnings()),
Opts2 = [{warnings, Warnings} | Opts],
_ = [?CONSOLE("~s", [format_warning(Warning)])
|| Warning <- dialyzer:run(Opts2)],
{ok, State}.
WarningsList = rebar_state:get(State, dialyzer_warnings, default_warnings()),
Opts2 = [{warnings, WarningsList} | Opts],
{Unknowns, Warnings} = format_warnings(dialyzer:run(Opts2)),
_ = [?CONSOLE("~s", [Unknown]) || Unknown <- Unknowns],
_ = [?CONSOLE("~s", [Warning]) || Warning <- Warnings],
{length(Warnings), State}.
format_warning(Warning) ->
string:strip(dialyzer_format_warning(Warning), right, $\n).
format_warnings(Warnings) ->
format_warnings(Warnings, [], []).
dialyzer_format_warning(Warning) ->
format_warnings([Warning | Rest], Unknowns, Warnings) ->
case dialyzer:format_warning(Warning) of case dialyzer:format_warning(Warning) of
":0: " ++ Warning2 ->
Warning2;
":0: " ++ Unknown ->
format_warnings(Rest, [strip(Unknown) | Unknowns], Warnings);
Warning2 -> Warning2 ->
Warning2
end.
format_warnings(Rest, Unknowns, [strip(Warning2) | Warnings])
end;
format_warnings([], Unknowns, Warnings) ->
{Unknowns, Warnings}.
strip(Warning) ->
string:strip(Warning, right, $\n).
default_warnings() -> default_warnings() ->
[error_handling, [error_handling,

Loading…
Cancel
Save