Browse Source

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 `<prefix>_<otp_version>_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.
pull/507/head
James Fish 10 years ago
parent
commit
e1f7c8c5f9
2 changed files with 68 additions and 44 deletions
  1. +58
    -35
      src/rebar_prv_dialyzer.erl
  2. +10
    -9
      test/rebar_dialyzer_SUITE.erl

+ 58
- 35
src/rebar_prv_dialyzer.erl View File

@ -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 \"<prefix>_<otp_release>_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).

+ 10
- 9
test/rebar_dialyzer_SUITE.erl View File

@ -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() ->

Loading…
Cancel
Save