diff options
Diffstat (limited to 'src/rebar_prv_dialyzer.erl')
-rw-r--r-- | src/rebar_prv_dialyzer.erl | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index 7f26487..7cf7e28 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/src/rebar_prv_dialyzer.erl @@ -44,25 +44,29 @@ desc() -> "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_apps` - the strategy for determining the applications which included " + "in the PLT file, `top_level_deps` to include just the direct dependencies " + "or `all_deps` to include all nested dependencies*\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" + "`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" + "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" + "$HOME/.cache/rebar3 (default) or a custom directory****\n" "`base_plt_prefix` - the prefix to the base PLT file, defaults to " - "\"rebar3\"** ***\n" + "\"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" - "**PLT files are named \"<prefix>_<otp_release>_plt\".\n" - "***The base PLT is a PLT containing the core applications often required " + "*The direct dependent applications are listed in `applications` and " + "`included_applications` of their .app files.\n" + "**The applications in `base_plt_apps` will be added to the " + "list. \n" + "***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". @@ -178,7 +182,12 @@ proj_plt_files(State) -> 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). + DepApps1 = + case get_config(State, plt_apps, top_level_deps) of + top_level_deps -> DepApps; + all_deps -> collect_nested_dependent_apps(DepApps) + end, + get_plt_files(BasePltApps ++ PltApps ++ DepApps1, Apps). default_plt_apps() -> [erts, @@ -395,19 +404,12 @@ run_dialyzer(State, Opts, Output) -> format_warnings(Output, Warnings) -> Warnings1 = format_warnings(Warnings), console_warnings(Warnings1), - file_warnings(Output, Warnings1), + file_warnings(Output, Warnings), length(Warnings1). format_warnings(Warnings) -> - [format_warning(Warning) || Warning <- Warnings]. - -format_warning(Warning) -> - case strip(dialyzer:format_warning(Warning, fullpath)) of - ":0: " ++ Unknown -> - Unknown; - Warning1 -> - Warning1 - end. + [rebar_dialyzer_format:format(Warning) || Warning <- Warnings]. + console_warnings(Warnings) -> _ = [?CONSOLE("~s", [Warning]) || Warning <- Warnings], @@ -416,7 +418,7 @@ console_warnings(Warnings) -> file_warnings(_, []) -> ok; file_warnings(Output, Warnings) -> - Warnings1 = [[Warning, $\n] || Warning <- Warnings], + Warnings1 = [[dialyzer:format_warning(Warning, fullpath), $\n] || Warning <- Warnings], case file:write_file(Output, Warnings1, [append]) of ok -> ok; @@ -424,9 +426,6 @@ file_warnings(Output, Warnings) -> throw({output_file_error, Output, Reason}) end. -strip(Warning) -> - string:strip(Warning, right, $\n). - no_warnings() -> [no_return, no_unused, @@ -442,3 +441,30 @@ no_warnings() -> get_config(State, Key, Default) -> Config = rebar_state:get(State, dialyzer, []), proplists:get_value(Key, Config, Default). + +-spec collect_nested_dependent_apps([atom()]) -> [atom()]. +collect_nested_dependent_apps(RootApps) -> + Deps = lists:foldl(fun collect_nested_dependent_apps/2, sets:new(), RootApps), + sets:to_list(Deps). + +-spec collect_nested_dependent_apps(atom(), rebar_set()) -> rebar_set(). +collect_nested_dependent_apps(App, Seen) -> + case sets:is_element(App, Seen) of + true -> + Seen; + false -> + Seen1 = sets:add_element(App, Seen), + case code:lib_dir(App) of + {error, _} -> + throw({unknown_application, App}); + AppDir -> + case rebar_app_discover:find_app(AppDir, all) of + false -> + throw({unknown_application, App}); + {true, AppInfo} -> + lists:foldl(fun collect_nested_dependent_apps/2, + Seen1, + rebar_app_info:applications(AppInfo)) + end + end + end. |