From a3d4cc1259babf1541d5e278f11fc9ec9be75bb0 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 19 Apr 2015 12:54:32 -0500 Subject: track and cleanup code paths for different contexts --- src/rebar3.erl | 4 +++- src/rebar_erlc_compiler.erl | 2 -- src/rebar_otp_app.erl | 4 ---- src/rebar_prv_common_test.erl | 6 ++++++ src/rebar_prv_compile.erl | 11 +++++++++-- src/rebar_prv_cover.erl | 2 +- src/rebar_prv_dialyzer.erl | 3 +++ src/rebar_prv_eunit.erl | 4 ++++ src/rebar_prv_install_deps.erl | 6 +++--- src/rebar_prv_shell.erl | 13 +++++++------ src/rebar_prv_xref.erl | 22 +++++----------------- src/rebar_state.erl | 14 ++++++++++++++ src/rebar_utils.erl | 8 -------- test/rebar_compile_SUITE.erl | 13 ++++++++----- test/rebar_profiles_SUITE.erl | 11 ++++++++--- test/rebar_test_utils.erl | 3 ++- test/rebar_xref_SUITE.erl | 4 ++-- 17 files changed, 75 insertions(+), 55 deletions(-) diff --git a/src/rebar3.erl b/src/rebar3.erl index 460bc36..e5e3173 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -134,7 +134,9 @@ run_aux(State, RawArgs) -> {Task, Args} = parse_args(RawArgs), - rebar_core:init_command(rebar_state:command_args(State7, Args), Task). + State8 = rebar_state:code_paths(State7, default, code:get_path()), + + rebar_core:init_command(rebar_state:command_args(State8, Args), Task). init_config() -> %% Initialize logging system diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 174f5f8..ced8ca8 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -148,7 +148,6 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) -> %% Make sure that ebin/ exists and is on the path ok = filelib:ensure_dir(filename:join(OutDir, "dummy.beam")), - CurrPath = code:get_path(), true = code:add_path(filename:absname(OutDir)), OutDir1 = proplists:get_value(outdir, ErlOpts, OutDir), @@ -173,7 +172,6 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) -> fun(S, C) -> internal_erl_compile(C, Dir, S, OutDir1, ErlOpts) end), - true = code:set_path(CurrPath), ok. erl_first_files(Config, Dir, NeededErlFiles) -> diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl index a93defc..41cd5f3 100644 --- a/src/rebar_otp_app.erl +++ b/src/rebar_otp_app.erl @@ -120,10 +120,6 @@ preprocess(State, AppInfo, AppSrcFile) -> AppFile = rebar_app_utils:app_src_to_app(OutDir, AppSrcFile), ok = rebar_file_utils:write_file_if_contents_differ(AppFile, Spec), - %% Make certain that the ebin/ directory is available - %% on the code path - true = code:add_path(filename:absname(filename:dirname(AppFile))), - AppFile; {error, Reason} -> ?PRV_ERROR({file_read, AppSrcFile, Reason}) diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index 1d5806b..a398144 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -38,6 +38,9 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> ?INFO("Running Common Test suites...", []), + + code:add_paths(rebar_state:code_paths(State, all_deps)), + %% Run ct provider prehooks Providers = rebar_state:providers(State), Cwd = rebar_dir:get_cwd(), @@ -47,11 +50,14 @@ do(State) -> {ok, State1} = Result -> %% Run ct provider posthooks rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1), + rebar_utils:cleanup_code_path(rebar_state:code_paths(State1, default)), Result; ?PRV_ERROR(_) = Error -> + rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)), Error catch throw:{error, Reason} -> + rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)), ?PRV_ERROR(Reason) end. diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index f3edebc..25bda8c 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -31,6 +31,9 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> + DepsPaths = rebar_state:code_paths(State, all_deps), + code:add_paths(DepsPaths), + ProjectApps = rebar_state:project_apps(State), Providers = rebar_state:providers(State), Deps = rebar_state:deps_to_build(State), @@ -49,9 +52,14 @@ do(State) -> ProjectApps2 = build_apps(State, Providers, ProjectApps1), State2 = rebar_state:project_apps(State, ProjectApps2), + ProjAppsPaths = [filename:join(rebar_app_info:out_dir(X), "ebin") || X <- ProjectApps2], + State3 = rebar_state:code_paths(State2, all_deps, DepsPaths ++ ProjAppsPaths), + rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State2), - {ok, State2}. + rebar_utils:cleanup_code_path(rebar_state:code_paths(State3, default)), + + {ok, State3}. -spec format_error(any()) -> iolist(). format_error(Reason) -> @@ -80,7 +88,6 @@ build_app(State, Providers, AppInfo) -> AppInfo1 = compile(S, AppInfo), rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, S), - true = code:add_patha(rebar_app_info:ebin_dir(AppInfo1)), AppInfo1. compile(State, AppInfo) -> diff --git a/src/rebar_prv_cover.erl b/src/rebar_prv_cover.erl index 83fe012..b38c6b0 100644 --- a/src/rebar_prv_cover.erl +++ b/src/rebar_prv_cover.erl @@ -150,7 +150,7 @@ analysis(State, Task) -> {Mod, process(Answer), File} end, Mods), - true = code:set_path(OldPath), + true = rebar_utils:cleanup_code_path(OldPath), Analysis. restore_cover_paths(State) -> diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index ef6a64c..f7cdf3b 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/src/rebar_prv_dialyzer.erl @@ -64,6 +64,7 @@ short_desc() -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> ?INFO("Dialyzer starting, this may take a while...", []), + code:add_paths(rebar_state:code_paths(State, all_deps)), Plt = get_plt_location(State), Apps = rebar_state:project_apps(State), @@ -74,6 +75,8 @@ do(State) -> ?PRV_ERROR({error_processing_apps, Error}); throw:{dialyzer_warnings, Warnings} -> ?PRV_ERROR({dialyzer_warnings, Warnings}) + after + rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)) end. -spec format_error(any()) -> iolist(). diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index 0ea3ae8..3ee912d 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -37,6 +37,7 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> ?INFO("Performing EUnit tests...", []), + code:add_paths(rebar_state:code_paths(State, all_deps)), %% Run eunit provider prehooks Providers = rebar_state:providers(State), Cwd = rebar_dir:get_cwd(), @@ -48,11 +49,14 @@ do(State) -> {ok, State1} -> %% Run eunit provider posthooks rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1), + rebar_utils:cleanup_code_path(rebar_state:code_paths(State1, default)), {ok, State1}; Error -> + rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)), Error end; Error -> + rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)), Error end. diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 1884a9c..e87a09d 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -150,12 +150,12 @@ handle_deps(Profile, State0, Deps, Upgrade, Locks) -> AllDeps = lists:ukeymerge(2 ,lists:ukeysort(2, SrcApps) ,lists:ukeysort(2, Solved)), - %% Sort all apps to build order + State3 = rebar_state:all_deps(State2, AllDeps), CodePaths = [rebar_app_info:ebin_dir(A) || A <- AllDeps], - ok = code:add_pathsz(CodePaths), + State4 = rebar_state:code_paths(State3, all_deps, CodePaths), - {ok, AllDeps, State3}. + {ok, AllDeps, State4}. %% =================================================================== %% Internal functions diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl index ed75b30..b6a85ab 100644 --- a/src/rebar_prv_shell.erl +++ b/src/rebar_prv_shell.erl @@ -92,7 +92,9 @@ shell(State) -> %% times). removes at most the error_logger added by init and the %% error_logger added by the tty handler ok = remove_error_handler(3), - %% add test paths + %% Add deps to path + code:add_paths(rebar_state:code_paths(State, all_deps)), + %% add project app test paths ok = add_test_paths(State), %% this call never returns (until user quits shell) timer:sleep(infinity). @@ -121,10 +123,9 @@ wait_until_user_started(Timeout) -> add_test_paths(State) -> lists:foreach(fun(App) -> - AppDir = rebar_app_info:out_dir(App), - %% ignore errors resulting from non-existent directories - _ = code:add_path(filename:join([AppDir, "ebin"])), - _ = code:add_path(filename:join([AppDir, "test"])) - end, rebar_state:project_apps(State)), + AppDir = rebar_app_info:out_dir(App), + %% ignore errors resulting from non-existent directories + _ = code:add_path(filename:join([AppDir, "test"])) + end, rebar_state:project_apps(State)), _ = code:add_path(filename:join([rebar_dir:base_dir(State), "test"])), ok. diff --git a/src/rebar_prv_xref.erl b/src/rebar_prv_xref.erl index 67cd554..baec57f 100644 --- a/src/rebar_prv_xref.erl +++ b/src/rebar_prv_xref.erl @@ -36,7 +36,8 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> - {OriginalPath, XrefChecks} = prepare(State), + code:add_paths(rebar_state:code_paths(State, all_deps)), + XrefChecks = prepare(State), %% Run xref checks ?INFO("Running cross reference analysis...", []), @@ -45,9 +46,8 @@ do(State) -> %% Run custom queries QueryChecks = rebar_state:get(State, xref_queries, []), QueryResults = lists:foldl(fun check_query/2, [], QueryChecks), - - ok = cleanup(OriginalPath), - + stopped = xref:stop(xref), + rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)), case XrefResults =:= [] andalso QueryResults =:= [] of true -> {ok, State}; @@ -100,10 +100,6 @@ prepare(State) -> [{ok, _} = xref:add_directory(xref, rebar_app_info:ebin_dir(App)) || App <- rebar_state:project_apps(State)], - %% Save the code path prior to doing any further code path - %% manipulation - OriginalPath = code:get_path(), - %% Get list of xref checks we want to run ConfXrefChecks = rebar_state:get(State, xref_checks, [exports_not_used, @@ -112,15 +108,7 @@ prepare(State) -> XrefChecks = sets:to_list(sets:intersection( sets:from_list(?SUPPORTED_XREFS), sets:from_list(ConfXrefChecks))), - {OriginalPath, XrefChecks}. - -cleanup(Path) -> - %% Restore the code path using the provided path - true = rebar_utils:cleanup_code_path(Path), - - %% Stop xref - stopped = xref:stop(xref), - ok. + XrefChecks. xref_checks(XrefChecks) -> lists:foldl(fun run_xref_check/2, [], XrefChecks). diff --git a/src/rebar_state.erl b/src/rebar_state.erl index f922977..705f723 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -3,6 +3,8 @@ -export([new/0, new/1, new/2, new/3, get/2, get/3, set/3, + code_paths/2, code_paths/3, + opts/1, opts/2, default/1, default/2, @@ -40,6 +42,7 @@ -record(state_t, {dir :: file:name(), opts = dict:new() :: rebar_dict(), + code_paths = dict:new() :: rebar_dict(), default = dict:new() :: rebar_dict(), escript_path :: undefined | file:filename_all(), @@ -132,6 +135,17 @@ default(#state_t{default=Opts}) -> default(State, Opts) -> State#state_t{default=Opts}. +code_paths(#state_t{code_paths=CodePaths}, Key) -> + case dict:find(Key, CodePaths) of + {ok, CodePath} -> + CodePath; + _ -> + [] + end. + +code_paths(State=#state_t{code_paths=CodePaths}, Key, CodePath) -> + State#state_t{code_paths=dict:store(Key, CodePath, CodePaths)}. + opts(#state_t{opts=Opts}) -> Opts. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index bc2e4ac..49f7ad7 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -42,7 +42,6 @@ erl_to_mod/1, beams/1, find_executable/1, - expand_code_path/0, vcs_vsn/2, deprecated/3, deprecated/4, @@ -177,13 +176,6 @@ find_executable(Name) -> "\"" ++ filename:nativename(Path) ++ "\"" end. -%% Convert all the entries in the code path to absolute paths. -expand_code_path() -> - CodePath = lists:foldl(fun(Path, Acc) -> - [filename:absname(Path) | Acc] - end, [], code:get_path()), - code:set_path(lists:reverse(CodePath)). - deprecated(Old, New, Opts, When) when is_list(Opts) -> case lists:member(Old, Opts) of true -> diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 2fdf36d..ee262a1 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -102,10 +102,11 @@ build_checkout_deps(Config) -> Deps = [{list_to_atom(Name2), Vsn2, {git, "", ""}}], {ok, RebarConfig} = file:consult(rebar_test_utils:create_config(AppDir, [{deps, Deps}])), - rebar_test_utils:run_and_check( + {ok, State} = rebar_test_utils:run_and_check( Config, RebarConfig, ["compile"], {ok, [{app, Name1}, {checkout, Name2}]} ), + code:add_paths(rebar_state:code_paths(State, all_deps)), ok = application:load(list_to_atom(Name2)), Loaded = application:loaded_applications(), {_, _, Vsn2} = lists:keyfind(list_to_atom(Name2), 1, Loaded). @@ -307,10 +308,11 @@ deps_in_path(Config) -> ?assertEqual([], [Path || Path <- code:get_path(), {match, _} <- [re:run(Path, PkgName)]]), %% Build things - rebar_test_utils:run_and_check( + {ok, State} = rebar_test_utils:run_and_check( Config, RConf, ["compile"], {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]} ), + code:add_paths(rebar_state:code_paths(State, all_deps)), %% Find src name in there ?assertNotEqual([], [Path || Path <- code:get_path(), {match, _} <- [re:run(Path, DepName)]]), @@ -326,11 +328,12 @@ deps_in_path(Config) -> ?assertEqual([], [Path || Path <- code:get_path(), {match, _} <- [re:run(Path, PkgName)]]), %% Rebuild - rebar_test_utils:run_and_check( + {ok, State1} = rebar_test_utils:run_and_check( Config, RConf, ["compile"], {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]} ), %% Find src name in there + code:add_paths(rebar_state:code_paths(State1, all_deps)), ?assertNotEqual([], [Path || Path <- code:get_path(), {match, _} <- [re:run(Path, DepName)]]), %% find pkg name in there @@ -373,11 +376,11 @@ checkout_priority(Config) -> %% Rebuild and make sure the checkout apps are in path code:set_path(StartPaths), - rebar_test_utils:run_and_check( + {ok, State} = rebar_test_utils:run_and_check( Config, RConf, ["compile"], {ok, [{app, Name}, {checkout, DepName}, {checkout, PkgName}]} ), - + code:add_paths(rebar_state:code_paths(State, all_deps)), [DepPath] = [Path || Path <- code:get_path(), {match, _} <- [re:run(Path, DepName)]], [PkgPath] = [Path || Path <- code:get_path(), diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 6288053..72969d3 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -160,9 +160,12 @@ profiles_remain_applied_with_config_present(Config) -> rebar_test_utils:create_config(AppDir, RebarConfig), - rebar_test_utils:run_and_check(Config, RebarConfig, + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "not_ok", "compile"], {ok, [{app, Name}]}), + Path = filename:join([AppDir, "_build", "not_ok", "lib", Name, "ebin"]), + code:add_path(Path), + Mod = list_to_atom("not_a_real_src_" ++ Name), true = lists:member({d, not_ok}, proplists:get_value(options, Mod:module_info(compile), [])). @@ -196,7 +199,8 @@ test_profile_applied_before_compile(Config) -> RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:create_config(AppDir, RebarConfig), - rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}), + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}), + code:add_paths(rebar_state:code_paths(State, all_deps)), S = list_to_atom("not_a_real_src_" ++ Name), true = lists:member({d, 'TEST'}, proplists:get_value(options, S:module_info(compile), [])). @@ -211,7 +215,8 @@ test_profile_applied_before_eunit(Config) -> RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:create_config(AppDir, RebarConfig), - rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}), + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}), + code:add_paths(rebar_state:code_paths(State, all_deps)), T = list_to_atom("not_a_real_src_" ++ Name ++ "_tests"), true = lists:member({d, 'TEST'}, proplists:get_value(options, T:module_info(compile), [])). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index d245c82..f764146 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -56,7 +56,8 @@ run_and_check(Config, RebarConfig, Command, Expect) -> ?assertEqual({error, Reason}, Res); {ok, Expected} -> {ok, _} = Res, - check_results(AppDir, Expected); + check_results(AppDir, Expected), + Res; return -> Res end diff --git a/test/rebar_xref_SUITE.erl b/test/rebar_xref_SUITE.erl index b2438cf..75d6786 100644 --- a/test/rebar_xref_SUITE.erl +++ b/test/rebar_xref_SUITE.erl @@ -44,7 +44,7 @@ init_per_testcase(Case, Config) -> [{app_name, Name}, {rebar_config, RebarConfig} | UpdConfig]. -end_per_testcase(_, Config) -> +end_per_testcase(_, _Config) -> ok. all() -> @@ -112,7 +112,7 @@ verify_test_results(xref_test, AppName, XrefResults, _QueryResults) -> ok; verify_test_results(xref_ignore_test, AppName, XrefResults, _QueryResults) -> AppModules = ["behaviour1", "behaviour2", "mymod", "othermod", "somemod"], - [Behaviour1Mod, Behaviour2Mod, MyMod, OtherMod, SomeMod] = + [_Behaviour1Mod, _Behaviour2Mod, _MyMod, _OtherMod, SomeMod] = [list_to_atom(AppName ++ "_" ++ Mod) || Mod <- AppModules], UndefFuns = proplists:get_value(undefined_functions, XrefResults), ?assertNot(lists:keymember(undefined_function_calls, 1, XrefResults)), -- cgit v1.1