瀏覽代碼

Merge pull request #2049 from tsloughter/dialyzer-cli

support dialyzer plt location and prefix in cli args
pull/2051/head
Fred Hebert 6 年之前
committed by GitHub
父節點
當前提交
d58e35e65c
沒有發現已知的金鑰在資料庫的簽署中 GPG 金鑰 ID: 4AEE18F83AFDEB23
共有 2 個檔案被更改,包括 66 行新增26 行删除
  1. +27
    -24
      src/rebar_prv_dialyzer.erl
  2. +39
    -2
      test/rebar_dialyzer_SUITE.erl

+ 27
- 24
src/rebar_prv_dialyzer.erl 查看文件

@ -23,7 +23,11 @@
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Opts = [{update_plt, $u, "update-plt", boolean, "Enable updating the PLT. Default: true"},
{succ_typings, $s, "succ-typings", boolean, "Enable success typing analysis. Default: true"}],
{succ_typings, $s, "succ-typings", boolean, "Enable success typing analysis. Default: true"},
{base_plt_location, undefined, "base-plt-location", string, "The location of base PLT file, defaults to $HOME/.cache/rebar3"},
{plt_location, undefined, "plt-location", string, "The location of the PLT file, defaults to the profile's base directory"},
{plt_prefix, undefined, "plt-prefix", string, "The prefix to the PLT file, defaults to \"rebar3\"" },
{base_plt_prefix, undefined, "base-plt-prefix", string, "The prefix to the base PLT file, defaults to \"rebar3\"" }],
State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER},
{module, ?MODULE},
{bare, true},
@ -87,10 +91,11 @@ do(State) ->
?INFO("Dialyzer starting, this may take a while...", []),
rebar_paths:unset_paths([plugins], State), % no plugins in analysis
rebar_paths:set_paths([deps], State),
Plt = get_plt(State),
{Args, _} = rebar_state:command_parsed_args(State),
Plt = get_plt(Args, State),
try
do(State, Plt)
do(Args, State, Plt)
catch
throw:{dialyzer_error, Error} ->
?PRV_ERROR({error_processing_apps, Error});
@ -134,10 +139,10 @@ format_error(Reason) ->
%% Internal functions
get_plt(State) ->
Prefix = get_config(State, plt_prefix, ?PLT_PREFIX),
get_plt(Args, State) ->
Prefix = proplists:get_value(plt_prefix, Args, get_config(State, plt_prefix, ?PLT_PREFIX)),
Name = plt_name(Prefix),
case get_config(State, plt_location, local) of
case proplists:get_value(plt_location, Args, get_config(State, plt_location, local)) of
local ->
BaseDir = rebar_dir:base_dir(State),
filename:join(BaseDir, Name);
@ -148,10 +153,10 @@ get_plt(State) ->
plt_name(Prefix) ->
Prefix ++ "_" ++ rebar_utils:otp_release() ++ "_plt".
do(State, Plt) ->
do(Args, State, Plt) ->
Output = get_output_file(State),
{PltWarnings, State1} = update_proj_plt(State, Plt, Output),
{Warnings, State2} = succ_typings(State1, Plt, Output),
{PltWarnings, State1} = update_proj_plt(Args, State, Plt, Output),
{Warnings, State2} = succ_typings(Args, State1, Plt, Output),
case PltWarnings + Warnings of
0 ->
{ok, State2};
@ -174,23 +179,22 @@ get_output_file(State) ->
default_output_file() ->
rebar_utils:otp_release() ++ ".dialyzer_warnings".
update_proj_plt(State, Plt, Output) ->
{Args, _} = rebar_state:command_parsed_args(State),
update_proj_plt(Args, State, Plt, Output) ->
case proplists:get_value(update_plt, Args) of
false ->
{0, State};
_ ->
do_update_proj_plt(State, Plt, Output)
do_update_proj_plt(Args, State, Plt, Output)
end.
do_update_proj_plt(State, Plt, Output) ->
do_update_proj_plt(Args, State, Plt, Output) ->
?INFO("Updating plt...", []),
Files = proj_plt_files(State),
case read_plt(State, Plt) of
{ok, OldFiles} ->
check_plt(State, Plt, Output, OldFiles, Files);
error ->
build_proj_plt(State, Plt, Output, Files)
build_proj_plt(Args, State, Plt, Output, Files)
end.
proj_plt_files(State) ->
@ -373,8 +377,8 @@ run_plt(State, Plt, Output, Analysis, Files) ->
{files, Files}],
run_dialyzer(State, Opts, Output).
build_proj_plt(State, Plt, Output, Files) ->
BasePlt = get_base_plt(State),
build_proj_plt(Args, State, Plt, Output, Files) ->
BasePlt = get_base_plt(Args, State),
?INFO("Updating base plt...", []),
BaseFiles = base_plt_files(State),
{BaseWarnings, State1} = update_base_plt(State, BasePlt, Output, BaseFiles),
@ -391,10 +395,10 @@ build_proj_plt(State, Plt, Output, Files) ->
throw({dialyzer_error, Error})
end.
get_base_plt(State) ->
Prefix = get_config(State, base_plt_prefix, ?PLT_PREFIX),
get_base_plt(Args, State) ->
Prefix = proplists:get_value(base_plt_prefix, Args, get_config(State, base_plt_prefix, ?PLT_PREFIX)),
Name = plt_name(Prefix),
case get_config(State, base_plt_location, global) of
case proplists:get_value(base_plt_location, Args, get_config(State, base_plt_location, global)) of
global ->
GlobalCacheDir = rebar_dir:global_cache_dir(rebar_state:opts(State)),
filename:join(GlobalCacheDir, Name);
@ -439,21 +443,20 @@ build_plt(State, Plt, Output, Files) ->
{files, Files}],
run_dialyzer(State, Opts, Output).
succ_typings(State, Plt, Output) ->
{Args, _} = rebar_state:command_parsed_args(State),
succ_typings(Args, State, Plt, Output) ->
case proplists:get_value(succ_typings, Args) of
false ->
{0, State};
_ ->
?INFO("Doing success typing analysis...", []),
Files = proj_files(State),
succ_typings(State, Plt, Output, Files)
succ_typings_(State, Plt, Output, Files)
end.
succ_typings(State, Plt, _, []) ->
succ_typings_(State, Plt, _, []) ->
?INFO("Analyzing no files with ~p...", [Plt]),
{0, State};
succ_typings(State, Plt, Output, Files) ->
succ_typings_(State, Plt, Output, Files) ->
?INFO("Analyzing ~b files with ~p...", [length(Files), Plt]),
Opts = [{analysis_type, succ_typings},
{get_warnings, true},

+ 39
- 2
test/rebar_dialyzer_SUITE.erl 查看文件

@ -15,7 +15,8 @@
update_app_plt/1,
build_release_plt/1,
plt_apps_option/1,
exclude_and_extra/1]).
exclude_and_extra/1,
cli_args/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@ -58,7 +59,7 @@ all() ->
groups() ->
[{empty, [empty_base_plt, empty_app_plt, empty_app_succ_typings]},
{build_and_check, [build_release_plt, plt_apps_option, exclude_and_extra]},
{build_and_check, [cli_args, build_release_plt, plt_apps_option, exclude_and_extra]},
{update, [update_base_plt, update_app_plt]}].
empty_base_plt(Config) ->
@ -309,6 +310,42 @@ exclude_and_extra(Config) ->
{ok, PltFiles} = plt_files(Plt),
?assertEqual(Pair, PltFiles).
cli_args(Config) ->
AppDir = ?config(apps, Config),
[{dialyzer, Opts}] = ?config(rebar_config, Config),
BasePlt = ?config(base_plt, Config),
Plt = ?config(plt, Config),
{value, {_, Prefix}, Opts1} = lists:keytake(plt_prefix, 1, Opts),
{value, {_, BasePrefix}, Opts2} = lists:keytake(base_plt_prefix, 1, Opts1),
{value, {_, Location}, Opts3} = lists:keytake(plt_location, 1, Opts2),
{value, {_, BasePltLocation}, Opts4} = lists:keytake(base_plt_location, 1, Opts3),
RebarConfig = [{dialyzer, Opts4}],
Name1 = rebar_test_utils:create_random_name("relapp1_"),
Vsn1 = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(filename:join([AppDir,"apps",Name1]), Name1, Vsn1,
[erts]),
Name2 = rebar_test_utils:create_random_name("relapp2_"),
Vsn2 = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(filename:join([AppDir,"apps",Name2]), Name2, Vsn2,
[erts, ec_cnv:to_atom(Name1)]),
rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer",
"--plt-location=" ++ Location,
"--base-plt-location=" ++ BasePltLocation,
"--plt-prefix=" ++ Prefix,
"--base-plt-prefix=" ++ BasePrefix],
{ok, [{app, Name1}, {app, Name2}]}),
ErtsFiles = erts_files(),
{ok, BasePltFiles} = plt_files(BasePlt),
?assertEqual(ErtsFiles, BasePltFiles),
{ok, PltFiles} = plt_files(Plt),
?assertEqual(ErtsFiles, PltFiles).
%% Helpers
erts_files() ->

Loading…
取消
儲存