summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rebar_app_discover.erl33
-rw-r--r--src/rebar_app_info.erl5
-rw-r--r--src/rebar_prv_compile.erl13
-rw-r--r--src/rebar_prv_install_deps.erl3
-rw-r--r--src/rebar_state.erl19
-rw-r--r--test/rebar_hooks_SUITE.erl30
6 files changed, 83 insertions, 20 deletions
diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl
index 332efb0..2eb9d91 100644
--- a/src/rebar_app_discover.erl
+++ b/src/rebar_app_discover.erl
@@ -20,19 +20,19 @@ do(State, LibDirs) ->
%% Sort apps so we get the same merged deps config everytime
SortedApps = rebar_utils:sort_deps(Apps),
lists:foldl(fun(AppInfo, StateAcc) ->
- Name = rebar_app_info:name(AppInfo),
- case enable(State, AppInfo) of
- true ->
- {AppInfo1, StateAcc1} = merge_deps(AppInfo, StateAcc),
- OutDir = filename:join(DepsDir, Name),
- AppInfo2 = rebar_app_info:out_dir(AppInfo1, OutDir),
- ProjectDeps1 = lists:delete(Name, ProjectDeps),
- rebar_state:project_apps(StateAcc1
- ,rebar_app_info:deps(AppInfo2, ProjectDeps1));
- false ->
- ?INFO("Ignoring ~s", [Name]),
- StateAcc
- end
+ Name = rebar_app_info:name(AppInfo),
+ case enable(State, AppInfo) of
+ true ->
+ {AppInfo1, StateAcc1} = merge_deps(AppInfo, StateAcc),
+ OutDir = filename:join(DepsDir, Name),
+ AppInfo2 = rebar_app_info:out_dir(AppInfo1, OutDir),
+ ProjectDeps1 = lists:delete(Name, ProjectDeps),
+ rebar_state:project_apps(StateAcc1
+ ,rebar_app_info:deps(AppInfo2, ProjectDeps1));
+ false ->
+ ?INFO("Ignoring ~s", [Name]),
+ StateAcc
+ end
end, State, SortedApps).
format_error({module_list, File}) ->
@@ -51,7 +51,8 @@ merge_deps(AppInfo, State) ->
rebar_state:apply_profiles(
rebar_state:new(reset_hooks(rebar_state:opts(State, Default)), C,
rebar_app_info:dir(AppInfo)), CurrentProfiles), Name),
- AppInfo1 = rebar_app_info:state(AppInfo, AppState),
+ AppState1 = rebar_state:set(AppState, artifacts, []),
+ AppInfo1 = rebar_app_info:state(AppInfo, AppState1),
State1 = lists:foldl(fun(Profile, StateAcc) ->
AppProfDeps = rebar_state:get(AppState, {deps, Profile}, []),
@@ -219,8 +220,8 @@ try_handle_app_src_file(_, _AppDir, Other, _Validate) ->
throw({error, {multiple_app_files, Other}}).
enable(State, AppInfo) ->
- not lists:member(to_atom(rebar_app_info:name(AppInfo)),
- rebar_state:get(State, excluded_apps, [])).
+ not lists:member(to_atom(rebar_app_info:name(AppInfo)),
+ rebar_state:get(State, excluded_apps, [])).
to_atom(Bin) ->
list_to_atom(binary_to_list(Bin)).
diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl
index 9db20e7..6e35b8f 100644
--- a/src/rebar_app_info.erl
+++ b/src/rebar_app_info.erl
@@ -286,8 +286,9 @@ is_checkout(#app_info_t{is_checkout=IsCheckout}) ->
IsCheckout.
-spec valid(t()) -> boolean().
-valid(AppInfo=#app_info_t{valid=undefined}) ->
- case rebar_app_utils:validate_application_info(AppInfo) of
+valid(AppInfo=#app_info_t{valid=undefined, state=State}) ->
+ case rebar_app_utils:validate_application_info(AppInfo)
+ andalso rebar_state:has_all_artifacts(State) =:= true of
true ->
true;
_ ->
diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl
index 2737827..6eb8a4f 100644
--- a/src/rebar_prv_compile.erl
+++ b/src/rebar_prv_compile.erl
@@ -8,6 +8,7 @@
-export([compile/3]).
+-include_lib("providers/include/providers.hrl").
-include("rebar.hrl").
-define(PROVIDER, compile).
@@ -60,12 +61,15 @@ do(State) ->
State3 = rebar_state:code_paths(State2, all_deps, DepsPaths ++ ProjAppsPaths),
rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State2),
+ has_all_artifacts(State3),
rebar_utils:cleanup_code_path(rebar_state:code_paths(State3, default)),
{ok, State3}.
-spec format_error(any()) -> iolist().
+format_error({missing_artifact, File}) ->
+ io_lib:format("Missing artifact ~s", [File]);
format_error(Reason) ->
io_lib:format("~p", [Reason]).
@@ -90,6 +94,7 @@ compile(State, Providers, AppInfo) ->
case rebar_otp_app:compile(State, AppInfo) of
{ok, AppInfo1} ->
rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, State),
+ has_all_artifacts(State),
AppInfo1;
Error ->
throw(Error)
@@ -99,6 +104,14 @@ compile(State, Providers, AppInfo) ->
%% Internal functions
%% ===================================================================
+has_all_artifacts(State) ->
+ case rebar_state:has_all_artifacts(State) of
+ {false, File} ->
+ throw(?PRV_ERROR({missing_artifact, File}));
+ true ->
+ true
+ end.
+
copy_app_dirs(State, OldAppDir, AppDir) ->
case ec_cnv:to_binary(filename:absname(OldAppDir)) =/=
ec_cnv:to_binary(filename:absname(AppDir)) of
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index d8b9000..61bbb62 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -666,7 +666,8 @@ warn_skip_pkg({Name, Source}, State) ->
not_needs_compile(App) ->
not(rebar_app_info:is_checkout(App))
- andalso rebar_app_info:valid(App).
+ andalso rebar_app_info:valid(App)
+ andalso rebar_state:has_all_artifacts(rebar_app_info:state(App)) =:= true.
get_package(Dep, State) ->
case rebar_state:registry(State) of
diff --git a/src/rebar_state.erl b/src/rebar_state.erl
index 96daf39..5b59eeb 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,
+ has_all_artifacts/1,
+
code_paths/2, code_paths/3, update_code_paths/3,
opts/1, opts/2,
@@ -149,6 +151,23 @@ default(#state_t{default=Opts}) ->
default(State, Opts) ->
State#state_t{default=Opts}.
+-spec has_all_artifacts(rebar_app_info:t()) -> true | providers:error().
+has_all_artifacts(State) ->
+ Artifacts = rebar_state:get(State, artifacts, []),
+ Dir = rebar_dir:base_dir(State),
+ all(Dir, Artifacts).
+
+all(_, []) ->
+ true;
+all(Dir, [File|Artifacts]) ->
+ case filelib:is_regular(filename:join(Dir, File)) of
+ false ->
+ ?DEBUG("Missing artifact ~s", [filename:join(Dir, File)]),
+ {false, File};
+ true ->
+ all(Dir, Artifacts)
+ end.
+
code_paths(#state_t{code_paths=CodePaths}, Key) ->
case dict:find(Key, CodePaths) of
{ok, CodePath} ->
diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl
index 7df4ea3..3908ca1 100644
--- a/test/rebar_hooks_SUITE.erl
+++ b/test/rebar_hooks_SUITE.erl
@@ -7,6 +7,7 @@
end_per_testcase/2,
all/0,
build_and_clean_app/1,
+ escriptize_artifacts/1,
run_hooks_once/1,
run_hooks_for_plugins/1,
deps_hook_namespace/1]).
@@ -31,7 +32,7 @@ end_per_testcase(_, _Config) ->
catch meck:unload().
all() ->
- [build_and_clean_app, run_hooks_once,
+ [build_and_clean_app, run_hooks_once, escriptize_artifacts,
run_hooks_for_plugins, deps_hook_namespace].
%% Test post provider hook cleans compiled project app, leaving it invalid
@@ -45,6 +46,33 @@ build_and_clean_app(Config) ->
rebar_test_utils:run_and_check(Config, [{provider_hooks, [{post, [{compile, clean}]}]}],
["compile"], {ok, [{app, Name, invalid}]}).
+escriptize_artifacts(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ Artifact = "bin/"++Name,
+ RConfFile =
+ rebar_test_utils:create_config(AppDir,
+ [
+ {escript_name, list_to_atom(Name)}
+ ,{artifacts, [Artifact]}
+ ]),
+ {ok, RConf} = file:consult(RConfFile),
+
+ try rebar_test_utils:run_and_check(Config, RConf, ["compile"], [])
+ catch
+ {error,
+ {rebar_prv_compile,
+ {missing_artifact, Artifact}}} ->
+ ok
+ end,
+ rebar_test_utils:run_and_check(Config, RConf++[{provider_hooks, [{post, [{compile, escriptize}]}]}],
+ ["compile"], {ok, [{app, Name, valid}
+ ,{file, filename:join([AppDir, "_build/default/", Artifact])}]}).
+
run_hooks_once(Config) ->
AppDir = ?config(apps, Config),