summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar_app_discover.erl14
-rw-r--r--src/rebar_hooks.erl2
-rw-r--r--src/rebar_otp_app.erl148
-rw-r--r--src/rebar_prv_compile.erl9
-rw-r--r--src/rebar_prv_install_deps.erl4
5 files changed, 79 insertions, 98 deletions
diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl
index aad8985..8add9e7 100644
--- a/src/rebar_app_discover.erl
+++ b/src/rebar_app_discover.erl
@@ -1,12 +1,15 @@
-module(rebar_app_discover).
-export([do/2,
+ format_error/1,
find_unbuilt_apps/1,
find_apps/1,
find_apps/2,
find_app/2,
validate_application_info/1]).
+-include_lib("providers/include/providers.hrl").
+
do(State, LibDirs) ->
BaseDir = rebar_state:dir(State),
Dirs = [filename:join(BaseDir, LibDir) || LibDir <- LibDirs],
@@ -17,6 +20,11 @@ do(State, LibDirs) ->
rebar_state:project_apps(StateAcc, rebar_app_info:deps(AppInfo, ProjectDeps1))
end, State, Apps).
+format_error({module_list, File}) ->
+ io_lib:format("Error reading module list from ~p~n", [File]);
+format_error({missing_module, Module}) ->
+ io_lib:format("Module defined in app file missing: ~p~n", [Module]).
+
-spec all_app_dirs(list(file:name())) -> list(file:name()).
all_app_dirs(LibDirs) ->
lists:flatmap(fun(LibDir) ->
@@ -142,7 +150,7 @@ validate_application_info(AppInfo) ->
{ok, List} ->
has_all_beams(EbinDir, List);
_Error ->
- false
+ ?PRV_ERROR({modules_list, AppFile})
end
end.
@@ -158,7 +166,7 @@ get_modules_list(AppFile, AppDetail) ->
{ok, ModulesList}
end.
--spec has_all_beams(file:filename_all(), list()) -> boolean().
+-spec has_all_beams(file:filename_all(), list()) -> true | providers:error().
has_all_beams(EbinDir, [Module | ModuleList]) ->
BeamFile = filename:join([EbinDir,
ec_cnv:to_list(Module) ++ ".beam"]),
@@ -166,7 +174,7 @@ has_all_beams(EbinDir, [Module | ModuleList]) ->
true ->
has_all_beams(EbinDir, ModuleList);
false ->
- false
+ ?PRV_ERROR({missing_module, Module})
end;
has_all_beams(_, []) ->
true.
diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl
index fbc207e..a1a363e 100644
--- a/src/rebar_hooks.erl
+++ b/src/rebar_hooks.erl
@@ -4,7 +4,7 @@
run_compile_hooks(Dir, Type, Command, State) ->
Hooks = rebar_state:get(State, Type, []),
- Env = [{"REBAR_DEPS_DIR", rebar_dir:deps_dir(State)}],
+ Env = [{"REBAR_DEPS_DIR", filename:absname(rebar_dir:deps_dir(State))}],
lists:foreach(fun({_, C, _}=Hook) when C =:= Command ->
apply_hook(Dir, Env, Hook);
({C, _}=Hook) when C =:= Command ->
diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl
index e1a1eab..74b2988 100644
--- a/src/rebar_otp_app.erl
+++ b/src/rebar_otp_app.erl
@@ -27,51 +27,39 @@
-module(rebar_otp_app).
-export([compile/2,
+ format_error/1,
clean/2]).
-%% for internal use only
--export([info/2]).
-
-include("rebar.hrl").
+-include_lib("providers/include/providers.hrl").
%% ===================================================================
%% Public API
%% ===================================================================
-compile(Config, App) ->
+compile(State, App) ->
%% If we get an .app.src file, it needs to be pre-processed and
%% written out as a ebin/*.app file. That resulting file will then
%% be validated as usual.
Dir = ec_cnv:to_list(rebar_app_info:dir(App)),
- {Config2, App1} = case rebar_app_info:app_file_src(App) of
+ {State2, App1} = case rebar_app_info:app_file_src(App) of
undefined ->
- {Config, App};
+ {State, App};
AppFileSrc ->
- {Config1, File} = preprocess(Config, Dir, AppFileSrc),
- {Config1, rebar_app_info:app_file(App, File)}
+ {State1, File} = preprocess(State, Dir, AppFileSrc),
+ {State1, rebar_app_info:app_file(App, File)}
end,
%% Load the app file and validate it.
- AppFile = rebar_app_info:app_file(App1),
- case rebar_app_utils:load_app_file(Config2, AppFile) of
- {ok, Config3, AppName, AppData} ->
- AppVsn = proplists:get_value(vsn, AppData),
- validate_name(AppName, AppFile),
- %% In general, the list of modules is an important thing to validate
- %% for compliance with OTP guidelines and upgrade procedures.
- %% However, some people prefer not to validate this list.
- case rebar_state:get(Config3, validate_app_modules, true) of
- true ->
- Modules = proplists:get_value(modules, AppData),
- {validate_modules(Dir, AppName, Modules), rebar_app_info:original_vsn(App1, AppVsn)};
- false ->
- {ok, rebar_app_info:original_vsn(App1, AppVsn)}
- end;
- {error, Reason} ->
- ?ABORT("Failed to load app file ~s: ~p", [AppFile, Reason])
- end.
+ validate_app(State2, App1).
+
+
+format_error({file_read, File, Reason}) ->
+ io_lib:format("Failed to read ~s for processing: ~p", [File, Reason]);
+format_error({invalid_name, File, AppName}) ->
+ io_lib:format("Invalid ~s: name of application (~p) must match filename.", [File, AppName]).
-clean(_Config, File) ->
+clean(_State, File) ->
%% If the app file is a .app.src, delete the generated .app file
case rebar_app_utils:is_app_src(File) of
true ->
@@ -92,34 +80,48 @@ clean(_Config, File) ->
%% Internal functions
%% ===================================================================
-info(help, compile) ->
- info_help("Validate .app file");
-info(help, clean) ->
- info_help("Delete .app file if generated from .app.src").
-
-info_help(Description) ->
- ?CONSOLE(
- "~s.~n"
- "~n"
- "Valid rebar.config options:~n"
- " ~p",
- [
- Description,
- {validate_app_modules, true}
- ]).
-
-preprocess(Config, Dir, AppSrcFile) ->
- case rebar_app_utils:load_app_file(Config, AppSrcFile) of
- {ok, Config1, AppName, AppData} ->
+validate_app(State, App) ->
+ AppFile = rebar_app_info:app_file(App),
+ case rebar_app_utils:load_app_file(State, AppFile) of
+ {ok, State1, AppName, AppData} ->
+ case validate_name(AppName, AppFile) of
+ ok ->
+ validate_app_modules(State1, App, AppData);
+ Error ->
+ Error
+ end;
+ {error, Reason} ->
+ ?PRV_ERROR({file_read, AppFile, Reason})
+ end.
+
+validate_app_modules(State, App, AppData) ->
+ %% In general, the list of modules is an important thing to validate
+ %% for compliance with OTP guidelines and upgrade procedures.
+ %% However, some people prefer not to validate this list.
+ AppVsn = proplists:get_value(vsn, AppData),
+ case rebar_state:get(State, validate_app_modules, true) of
+ true ->
+ case rebar_app_discover:validate_application_info(App) of
+ true ->
+ {ok, rebar_app_info:original_vsn(App, AppVsn)};
+ Error ->
+ Error
+ end;
+ false ->
+ {ok, rebar_app_info:original_vsn(App, AppVsn)}
+ end.
+
+preprocess(State, Dir, AppSrcFile) ->
+ case rebar_app_utils:load_app_file(State, AppSrcFile) of
+ {ok, State1, AppName, AppData} ->
%% Look for a configuration file with vars we want to
%% substitute. Note that we include the list of modules available in
%% ebin/ and update the app data accordingly.
- AppVars = load_app_vars(Config1) ++ [{modules, ebin_modules(Dir)}],
+ AppVars = load_app_vars(State1) ++ [{modules, ebin_modules(Dir)}],
A1 = apply_app_vars(AppVars, AppData),
-
%% AppSrcFile may contain instructions for generating a vsn number
- {Config2, Vsn} = rebar_app_utils:app_vsn(Config1, AppSrcFile),
+ {State2, Vsn} = rebar_app_utils:app_vsn(State1, AppSrcFile),
A2 = lists:keystore(vsn, 1, A1, {vsn, Vsn}),
%% systools:make_relup/4 fails with {missing_param, registered}
@@ -137,14 +139,13 @@ preprocess(Config, Dir, AppSrcFile) ->
%% on the code path
true = code:add_path(filename:absname(filename:dirname(AppFile))),
- {Config2, AppFile};
+ {State2, AppFile};
{error, Reason} ->
- ?ABORT("Failed to read ~s for preprocessing: ~p",
- [AppSrcFile, Reason])
+ ?PRV_ERROR({file_read, AppSrcFile, Reason})
end.
-load_app_vars(Config) ->
- case rebar_state:get(Config, app_vars_file, undefined) of
+load_app_vars(State) ->
+ case rebar_state:get(State, app_vars_file, undefined) of
undefined ->
?DEBUG("No app_vars_file defined.", []),
[];
@@ -168,44 +169,7 @@ validate_name(AppName, File) ->
true ->
ok;
false ->
- ?ERROR("Invalid ~s: name of application (~p) "
- "must match filename.", [File, AppName]),
- ?FAIL
- end.
-
-validate_modules(_Dir, AppName, undefined) ->
- ?ERROR("Missing modules declaration in ~p.app", [AppName]),
- ?FAIL;
-
-validate_modules(Dir, AppName, Mods) ->
- %% Construct two sets -- one for the actual .beam files in ebin/
- %% and one for the modules
- %% listed in the .app file
- EbinSet = ordsets:from_list(ebin_modules(Dir)),
- ModSet = ordsets:from_list(Mods),
-
- %% Identify .beam files listed in the .app, but not present in ebin/
- case ordsets:subtract(ModSet, EbinSet) of
- [] ->
- ok;
- MissingBeams ->
- Msg1 = lists:flatten([io_lib:format("\t* ~p", [M]) ||
- M <- MissingBeams]),
- ?ERROR("One or more modules listed in ~p.app are not "
- "present in ebin/*.beam:~n~s", [AppName, Msg1]),
- ?FAIL
- end,
-
- %% Identify .beam files NOT list in the .app, but present in ebin/
- case ordsets:subtract(EbinSet, ModSet) of
- [] ->
- ok;
- MissingMods ->
- Msg2 = lists:flatten([io_lib:format("\t* ~p\n", [M]) ||
- M <- MissingMods]),
- ?ERROR("One or more .beam files exist that are not "
- "listed in ~p.app:\n~s", [AppName, Msg2]),
- ?FAIL
+ ?PRV_ERROR({invalid_name, File, AppName})
end.
ebin_modules(Dir) ->
diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl
index b247603..073394c 100644
--- a/src/rebar_prv_compile.erl
+++ b/src/rebar_prv_compile.erl
@@ -85,8 +85,13 @@ build_apps(State, Apps) ->
build(State, AppInfo) ->
?INFO("Compiling ~s", [rebar_app_info:name(AppInfo)]),
rebar_erlc_compiler:compile(State, ec_cnv:to_list(rebar_app_info:dir(AppInfo))),
- {ok, AppInfo1} = rebar_otp_app:compile(State, AppInfo),
- AppInfo1.
+ case rebar_otp_app:compile(State, AppInfo) of
+ {ok, AppInfo1} ->
+ AppInfo1;
+ Error ->
+ throw(Error)
+ end.
+
%% ===================================================================
%% Internal functions
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index 701ee2a..fc876bd 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -432,6 +432,10 @@ parse_dep({Name, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tupl
parse_dep({Name, _Vsn, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source) ->
Dep = new_dep(DepsDir, Name, [], Source, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
+parse_dep({Name, _Vsn, Source, Opts}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source) ->
+ ?WARN("Dependency option list ~p in ~p is not supported and will be ignored", [Opts, Name]),
+ Dep = new_dep(DepsDir, Name, [], Source, State),
+ {[Dep | SrcDepsAcc], PkgDepsAcc};
parse_dep({Name, Source, Level}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source)
, is_integer(Level) ->
Dep = new_dep(DepsDir, Name, [], Source, State),