From d425b4e4baed1743cc2513d89423137371c68341 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 28 Nov 2018 14:28:20 -0500 Subject: [PATCH 1/4] Fix load order for custom project builders Due to building dependencies with potential artifacts such as parse transforms or macros, project builder plugins should be included in the path, but _after_ deps are loaded. Doing otherwise means that if any of the dependencies is required at compile time, those of a plugin might get used first. --- src/rebar_prv_compile.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index ee96d9fb..ad012eaa 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -201,7 +201,7 @@ build_app(AppInfo, State) -> case lists:keyfind(Type, 1, ProjectBuilders) of {_, Module} -> %% load plugins since thats where project builders would be - rebar_paths:set_paths([plugins, deps], State), + rebar_paths:set_paths([deps, plugins], State), Res = Module:build(AppInfo), rebar_paths:set_paths([deps], State), case Res of From 6aaa54c6d14f079213f1102243edeb02c3c4f52c Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 28 Nov 2018 14:59:56 -0500 Subject: [PATCH 2/4] Ensure the right deps are in path Compile time with parse transforms needs to have the deps first in scope before the plugins --- src/rebar_prv_compile.erl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index ad012eaa..cf2bcf28 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -195,6 +195,7 @@ build_app(AppInfo, State) -> case rebar_app_info:project_type(AppInfo) of Type when Type =:= rebar3 ; Type =:= undefined -> Compilers = rebar_state:compilers(State), + rebar_paths:set_paths([deps], State), rebar_compiler:compile_all(Compilers, AppInfo); Type -> ProjectBuilders = rebar_state:project_builders(State), From fc9b11afcadc1090f613eaef54873f17fc9020c5 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 29 Nov 2018 23:00:23 -0500 Subject: [PATCH 3/4] Clear app details cache before checking in paths The app data, when set by `rebar3_app_discover` basically does not include the modules if it was derived from the .app.src file, even if at a later point the modules were compiled. Since there is currently no clear way to add that information reliably across all compiler versions in all types of compilers, we simply clear the cache and re-derive the information when required. This might have a small performance cost, but is required for correctness whenever an application's first build is run. Specifically, this bug was detected when a plugin included lager's parse transform, and the application itself also required it, but two distinct versions were needed. This patch finalizes fixing this issue. --- src/rebar_paths.erl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rebar_paths.erl b/src/rebar_paths.erl index 82c02186..c49ed36d 100644 --- a/src/rebar_paths.erl +++ b/src/rebar_paths.erl @@ -111,7 +111,6 @@ purge_and_load([{_Group, Apps}|Rest], Seen) -> %% Shouldn't unload ourselves; rebar runs without ever %% being started and unloading breaks logging! AppName =/= <<"rebar">>], - %% 4) CandidateMods = lists:append( %% Start by asking the currently loaded app (if loaded) @@ -121,8 +120,10 @@ purge_and_load([{_Group, Apps}|Rest], Seen) -> Mods; undefined -> %% if not found, parse the app file on disk, in case - %% the app's modules are used without it being loaded - case rebar_app_info:app_details(App) of + %% the app's modules are used without it being loaded; + %% invalidate the cache in case we're proceeding during + %% compilation steps by setting the app details to `[]' + case rebar_app_info:app_details(rebar_app_info:app_details(App, [])) of [] -> []; Details -> proplists:get_value(modules, Details, []) end From c0957db49bdd0af80eb72a5a3c2c03796d959044 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 1 Dec 2018 13:04:48 -0500 Subject: [PATCH 4/4] Review comments addressed --- src/rebar_paths.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rebar_paths.erl b/src/rebar_paths.erl index c49ed36d..160f9fa2 100644 --- a/src/rebar_paths.erl +++ b/src/rebar_paths.erl @@ -122,7 +122,9 @@ purge_and_load([{_Group, Apps}|Rest], Seen) -> %% if not found, parse the app file on disk, in case %% the app's modules are used without it being loaded; %% invalidate the cache in case we're proceeding during - %% compilation steps by setting the app details to `[]' + %% compilation steps by setting the app details to `[]', which + %% is its empty value; the details will then be reloaded + %% from disk when found case rebar_app_info:app_details(rebar_app_info:app_details(App, [])) of [] -> []; Details -> proplists:get_value(modules, Details, [])