diff options
-rw-r--r-- | src/rebar_prv_dialyzer.erl | 51 | ||||
-rw-r--r-- | test/rebar_dialyzer_SUITE.erl | 41 |
2 files changed, 66 insertions, 26 deletions
diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index 585051c..82b4012 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/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}, diff --git a/test/rebar_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl index 6579afb..8577a32 100644 --- a/test/rebar_dialyzer_SUITE.erl +++ b/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() -> |