From 21f40b04552069ef70fe037e19045e3855aee9e1 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Fri, 20 Dec 2019 20:18:12 +0300 Subject: [PATCH] Run dialyzer for extra_src_dirs --- src/rebar_prv_dialyzer.erl | 44 ++++++++++++++++++++++++----------- test/rebar_dialyzer_SUITE.erl | 22 ++++++++++++++++-- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index e44c2875..57bcbf30 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/src/rebar_prv_dialyzer.erl @@ -212,7 +212,7 @@ proj_plt_files(State) -> PltMods = get_config(State, plt_extra_mods, []) ++ BasePltMods, Apps = proj_apps(State), DepApps = proj_deps(State), - get_files(State, DepApps ++ PltApps, Apps -- PltApps, PltMods, []). + get_files(State, DepApps ++ PltApps, Apps -- PltApps, PltMods, [], []). proj_apps(State) -> [ec_cnv:to_atom(rebar_app_info:name(App)) || @@ -226,31 +226,33 @@ proj_deps(State) -> all_deps -> collect_nested_dependent_apps(DepApps) end. -get_files(State, Apps, SkipApps, Mods, SkipMods) -> +get_files(State, Apps, SkipApps, Mods, SkipMods, ExtraDirs) -> ?INFO("Resolving files...", []), ExcludeApps = get_config(State, exclude_apps, []), - Files = apps_files(Apps, ExcludeApps ++ SkipApps, dict:new()), + Files0 = apps_files(Apps, ExcludeApps ++ SkipApps, ExtraDirs, dict:new()), + BaseDir = filename:join(rebar_dir:base_dir(State), "extras"), + Files1 = extras_files(BaseDir, ExtraDirs, Files0), ExcludeMods = get_config(State, exclude_mods, []), - Files2 = mods_files(Mods, ExcludeMods ++ SkipMods, Files), + Files2 = mods_files(Mods, ExcludeMods ++ SkipMods, Files1), dict:fold(fun(_, File, Acc) -> [File | Acc] end, [], Files2). -apps_files([], _, Files) -> +apps_files([], _, _ExtraDirs, Files) -> Files; -apps_files([AppName | DepApps], SkipApps, Files) -> +apps_files([AppName | DepApps], SkipApps, ExtraDirs, Files) -> case lists:member(AppName, SkipApps) of true -> - apps_files(DepApps, SkipApps, Files); + apps_files(DepApps, SkipApps, ExtraDirs, Files); false -> - AppFiles = app_files(AppName), + AppFiles = app_files(AppName, ExtraDirs), ?DEBUG("~ts modules: ~p", [AppName, dict:fetch_keys(AppFiles)]), Files2 = merge_files(Files, AppFiles), - apps_files(DepApps, [AppName | SkipApps], Files2) + apps_files(DepApps, [AppName | SkipApps], ExtraDirs, Files2) end. -app_files(AppName) -> +app_files(AppName, ExtraDirs) -> case app_ebin(AppName) of {ok, EbinDir} -> - ebin_files(EbinDir); + merge_files(ebin_files(EbinDir), extra_files(AppName, ExtraDirs)); {error, bad_name} -> throw({unknown_application, AppName}) end. @@ -282,6 +284,21 @@ ebin_files(EbinDir) -> end, lists:foldl(Store, dict:new(), Files). +extras_files(_BaseDir, [], Acc) -> + Acc; +extras_files(BaseDir, [ExtraDir | Rest], Acc) -> + Files = ebin_files(filename:join(BaseDir, ExtraDir)), + extras_files(BaseDir, Rest, merge_files(Acc, Files)). + +extra_files(AppName, ExtraDirs) -> + lists:foldl( + fun(ExtraDir, Files) -> + merge_files(Files, ebin_files(filename:join(code:lib_dir(AppName), ExtraDir))) + end, + dict:new(), + ExtraDirs + ). + merge_files(Files1, Files2) -> Duplicate = fun(Mod, File1, File2) -> throw({duplicate_module, Mod, File1, File2}) @@ -417,7 +434,7 @@ get_base_plt(Args, State) -> base_plt_files(State) -> BasePltApps = base_plt_apps(State), BasePltMods = get_config(State, base_plt_mods, []), - get_files(State, BasePltApps, [], BasePltMods, []). + get_files(State, BasePltApps, [], BasePltMods, [], []). base_plt_apps(State) -> get_config(State, base_plt_apps, [erts, crypto, kernel, stdlib]). @@ -479,7 +496,8 @@ proj_files(State) -> PltApps = get_config(State, plt_extra_apps, []) ++ BasePltApps, BasePltMods = get_config(State, base_plt_mods, []), PltMods = get_config(State, plt_extra_mods, []) ++ BasePltMods, - get_files(State, Apps, PltApps, [], PltMods). + ExtraDirs = rebar_dir:extra_src_dirs(rebar_state:opts(State)), + get_files(State, Apps, PltApps, [], PltMods, ExtraDirs). run_dialyzer(State, Opts, Output) -> {Args, _} = rebar_state:command_parsed_args(State), diff --git a/test/rebar_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl index 724f9d06..4cfedff7 100644 --- a/test/rebar_dialyzer_SUITE.erl +++ b/test/rebar_dialyzer_SUITE.erl @@ -16,7 +16,8 @@ build_release_plt/1, plt_apps_option/1, exclude_and_extra/1, - cli_args/1]). + cli_args/1, + extra_src_dirs/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -59,7 +60,11 @@ all() -> groups() -> [{empty, [empty_base_plt, empty_app_plt, empty_app_succ_typings]}, - {build_and_check, [cli_args, build_release_plt, plt_apps_option, exclude_and_extra]}, + {build_and_check, [cli_args, + build_release_plt, + plt_apps_option, + exclude_and_extra, + extra_src_dirs]}, {update, [update_base_plt, update_app_plt]}]. empty_base_plt(Config) -> @@ -347,6 +352,19 @@ cli_args(Config) -> {ok, PltFiles} = plt_files(Plt), ?assertEqual(ErtsFiles, PltFiles). +extra_src_dirs(Config) -> + AppDir = ?config(apps, Config), + State = ?config(state, Config), + RebarConfig = ?config(rebar_config, Config), + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, []), + % `test` directory is already in `extra_src_dirs` when run test profile + Command = ["as", "test", "dialyzer"], + % there are few warnings for generated test (see rebar_test_utils:erl_eunit_suite_file/1) + {error, {rebar_prv_dialyzer, {dialyzer_warnings, _}}} = + rebar3:run(rebar_state:new(State, RebarConfig, AppDir), Command). + %% Helpers erts_files() ->