From e1f7c8c5f93ce6088122016c9558db13557bd9af Mon Sep 17 00:00:00 2001 From: James Fish Date: Sat, 6 Jun 2015 11:59:18 +0100 Subject: Use the same dialyzer rebar.config options as rebar * All configuration is moved to `{dialyzer, PropList}` * `dialyzer_warnings` renamed `warnings` * `dialyzer_plt_warnings` renamed `get_warnings` * `dialyzer_plt_apps` renamed `plt_extra_apps` * `dialyzer_plt_dir` renamed `plt_location` * `{plt_location, local}` uses profile base directory * `dialyzer_plt` removed * `dialyzer_plt_prefix` sets prefix of PLT name (default "rebar3") * `dialyzer_base_plt_apps` renamed `base_plt_apps` * `dialyzer_base_plt_dir` renamed `base_plt_location` * `{base_plt_location, global}` uses rebar3's global cache directory * `dialyzer_base_plt` removed * `base_plt_prefix` sets prefix of PLT name (default "rebar3") PLT files are always named `__plt` to match rebar. `plt_prefix` and `base_plt_prefix` are not available in rebar, where the prefix is always set to the project's top level application. --- src/rebar_prv_dialyzer.erl | 93 +++++++++++++++++++++++++++---------------- test/rebar_dialyzer_SUITE.erl | 19 ++++----- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index a098984..15f1dac 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/src/rebar_prv_dialyzer.erl @@ -14,6 +14,7 @@ -define(PROVIDER, dialyzer). -define(DEPS, [compile]). +-define(PLT_PREFIX, "rebar3"). %% =================================================================== %% Public API @@ -39,24 +40,32 @@ desc() -> "This command will build, and keep up-to-date, a suitable PLT and will use " "it to carry out success typing analysis on the current project.\n" "\n" - "The following (optional) configurations can be added to a rebar.config:\n" - "`dialyzer_warnings` - a list of dialyzer warnings\n" - "`dialyzer_plt` - the PLT file to use\n" - "`dialyzer_plt_apps` - a list of applications to include in the PLT file*\n" - "`dialyzer_plt_warnings` - display warnings when updating a PLT file " - "(boolean)\n" - "`dialyzer_base_plt` - the base PLT file to use**\n" - "`dialyzer_base_plt_dir` - the base PLT directory**\n" - "`dialyzer_base_plt_apps` - a list of applications to include in the base " - "PLT file**\n" + "The following (optional) configurations can be added to a `proplist` of " + "options `dialyzer` in rebar.config:\n" + "`warnings` - a list of dialyzer warnings\n" + "`get_warnings` - display warnings when altering a PLT file (boolean)\n" + "`plt_extra_apps` - a list of applications to include in the PLT file*\n" + "`plt_location` - the location of the PLT file, `local` to store in the " + "profile's base directory (default) or a custom directory.\n" + "`plt_prefix` - the prefix to the PLT file, defaults to \"rebar3\"**\n" + "`base_plt_apps` - a list of applications to include in the base " + "PLT file***\n" + "`base_plt_location` - the location of base PLT file, `global` to store in " + "$HOME/.cache/rebar3 (default) or a custom directory***\n" + "`base_plt_prefix` - the prefix to the base PLT file, defaults to " + "\"rebar3\"** ***\n" + "\n" + "For example, to warn on unmatched returns: \n" + "{dialyzer, [{warnings, [unmatched_returns]}]}.\n" "\n" "*The applications in `dialyzer_base_plt_apps` and any `applications` and " "`included_applications` listed in their .app files will be added to the " "list.\n" - "**The base PLT is a PLT containing the core OTP applications often " - "required for a project's PLT. One base PLT is created per OTP version and " - "stored in `dialyzer_base_plt_dir` (defaults to $HOME/.rebar3/). A base " - "PLT is used to create a project's initial PLT.". + "**PLT files are named \"__plt\".\n" + "***The base PLT is a PLT containing the core applications often required " + "for a project's PLT. One base PLT is created per OTP version and " + "stored in `base_plt_location`. A base PLT is used to build project PLTs." + "\n". short_desc() -> "Run the Dialyzer analyzer on the project.". @@ -65,7 +74,7 @@ short_desc() -> do(State) -> ?INFO("Dialyzer starting, this may take a while...", []), code:add_pathsa(rebar_state:code_paths(State, all_deps)), - Plt = get_plt_location(State), + Plt = get_plt(State), try do(State, Plt) @@ -97,13 +106,19 @@ format_error(Reason) -> %% Internal functions -get_plt_location(State) -> - BaseDir = rebar_dir:base_dir(State), - DefaultPlt = filename:join(BaseDir, default_plt()), - rebar_state:get(State, dialyzer_plt, DefaultPlt). +get_plt(State) -> + Prefix = get_config(State, plt_prefix, ?PLT_PREFIX), + Name = plt_name(Prefix), + case get_config(State, plt_location, local) of + local -> + BaseDir = rebar_dir:base_dir(State), + filename:join(BaseDir, Name); + Dir -> + filename:join(Dir, Name) + end. -default_plt() -> - rebar_utils:otp_release() ++ ".plt". +plt_name(Prefix) -> + Prefix ++ "_" ++ rebar_utils:otp_release() ++ "_plt". do(State, Plt) -> Output = get_output_file(State), @@ -151,9 +166,8 @@ do_update_proj_plt(State, Plt, Output) -> end. proj_plt_files(State) -> - BasePltApps = rebar_state:get(State, dialyzer_base_plt_apps, - default_plt_apps()), - PltApps = rebar_state:get(State, dialyzer_plt_apps, []), + BasePltApps = get_config(State, base_plt_apps, default_plt_apps()), + PltApps = get_config(State, plt_extra_apps, []), Apps = rebar_state:project_apps(State), DepApps = lists:flatmap(fun rebar_app_info:applications/1, Apps), get_plt_files(BasePltApps ++ PltApps ++ DepApps, Apps). @@ -259,16 +273,17 @@ add_plt(State, Plt, Output, Files) -> run_plt(State, Plt, Output, plt_add, Files). run_plt(State, Plt, Output, Analysis, Files) -> - GetWarnings = rebar_state:get(State, dialyzer_plt_warnings, false), + GetWarnings = get_config(State, get_warnings, false), Opts = [{analysis_type, Analysis}, {get_warnings, GetWarnings}, {init_plt, Plt}, + {output_plt, Plt}, {from, byte_code}, {files, Files}], run_dialyzer(State, Opts, Output). build_proj_plt(State, Plt, Output, Files) -> - BasePlt = get_base_plt_location(State), + BasePlt = get_base_plt(State), ?INFO("Updating base plt...", []), BaseFiles = base_plt_files(State), {BaseWarnings, State1} = update_base_plt(State, BasePlt, Output, BaseFiles), @@ -285,15 +300,19 @@ build_proj_plt(State, Plt, Output, Files) -> throw({dialyzer_error, Error}) end. -get_base_plt_location(State) -> - GlobalCacheDir = rebar_dir:global_cache_dir(State), - BaseDir = rebar_state:get(State, dialyzer_base_plt_dir, GlobalCacheDir), - BasePlt = rebar_state:get(State, dialyzer_base_plt, default_plt()), - filename:join(BaseDir, BasePlt). +get_base_plt(State) -> + Prefix = get_config(State, base_plt_prefix, ?PLT_PREFIX), + Name = plt_name(Prefix), + case get_config(State, base_plt_location, global) of + global -> + GlobalCacheDir = rebar_dir:global_cache_dir(State), + filename:join(GlobalCacheDir, Name); + Dir -> + filename:join(Dir, Name) + end. base_plt_files(State) -> - BasePltApps = rebar_state:get(State, dialyzer_base_plt_apps, - default_plt_apps()), + BasePltApps = get_config(State, base_plt_apps, default_plt_apps()), Apps = rebar_state:project_apps(State), get_plt_files(BasePltApps, Apps). @@ -308,7 +327,7 @@ update_base_plt(State, BasePlt, Output, BaseFiles) -> build_plt(State, Plt, Output, Files) -> ?INFO("Adding ~b files to ~p...", [length(Files), Plt]), - GetWarnings = rebar_state:get(State, dialyzer_plt_warnings, false), + GetWarnings = get_config(State, get_warnings, false), Opts = [{analysis_type, plt_build}, {get_warnings, GetWarnings}, {output_plt, Plt}, @@ -349,7 +368,7 @@ run_dialyzer(State, Opts, Output) -> %% dialyzer may return callgraph warnings when get_warnings is false case proplists:get_bool(get_warnings, Opts) of true -> - WarningsList = rebar_state:get(State, dialyzer_warnings, []), + WarningsList = get_config(State, warnings, []), Opts2 = [{warnings, WarningsList}, {check_plt, false} | Opts], @@ -411,3 +430,7 @@ no_warnings() -> no_contracts, no_behaviours, no_undefined_callbacks]. + +get_config(State, Key, Default) -> + Config = rebar_state:get(State, dialyzer, []), + proplists:get_value(Key, Config, Default). diff --git a/test/rebar_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl index 724d8f0..1160d2d 100644 --- a/test/rebar_dialyzer_SUITE.erl +++ b/test/rebar_dialyzer_SUITE.erl @@ -25,15 +25,16 @@ end_per_suite(_Config) -> init_per_testcase(Testcase, Config) -> PrivDir = ?config(priv_dir, Config), Prefix = ec_cnv:to_list(Testcase), - Plt = filename:join(PrivDir, Prefix ++ ".project.plt"), - BasePlt = Prefix ++ "base.plt", - RebarConfig = [{dialyzer_plt, Plt}, - {dialyzer_base_plt, BasePlt}, - {dialyzer_base_plt_dir, PrivDir}, - {dialyzer_base_plt_apps, [erts]}], - [{plt, Plt}, - {base_plt, filename:join(PrivDir, BasePlt)}, - {rebar_config, RebarConfig} | + BasePrefix = Prefix ++ "_base", + Opts = [{plt_prefix, Prefix}, + {plt_location, PrivDir}, + {base_plt_prefix, BasePrefix}, + {base_plt_location, PrivDir}, + {base_plt_apps, [erts]}], + Suffix = "_" ++ rebar_utils:otp_release() ++ "_plt", + [{plt, filename:join(PrivDir, Prefix ++ Suffix)}, + {base_plt, filename:join(PrivDir, BasePrefix ++ Suffix)}, + {rebar_config, [{dialyzer, Opts}]} | rebar_test_utils:init_rebar_state(Config)]. all() -> -- cgit v1.1