diff options
Diffstat (limited to 'src/rebar_otp_app.erl')
-rw-r--r-- | src/rebar_otp_app.erl | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl index 8db1044..bcc13fd 100644 --- a/src/rebar_otp_app.erl +++ b/src/rebar_otp_app.erl @@ -27,6 +27,7 @@ -module(rebar_otp_app). -export([compile/2, + clean/2, install/2]). -include("rebar.hrl"). @@ -36,12 +37,34 @@ %% =================================================================== compile(_Config, File) -> - %% Load the app name and version from the .app file and construct - %% the app identifier - {ok, AppName, AppData} = rebar_app_utils:load_app_file(File), - validate_name(AppName, File), - validate_modules(AppName, proplists:get_value(modules, AppData)), - ok. + %% 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. + case rebar_app_utils:is_app_src(File) of + true -> + AppFile = preprocess(File); + false -> + AppFile = File + end, + + %% Load the app file and validate it. + case rebar_app_utils:load_app_file(AppFile) of + {ok, AppName, AppData} -> + validate_name(AppName, AppFile), + validate_modules(AppName, proplists:get_value(modules, AppData)); + {error, Reason} -> + ?ABORT("Failed to load app file ~s: ~p\n", [AppFile, Reason]) + end. + +clean(_Config, File) -> + %% If the app file is a .app.src, delete the generated .app file + case rebar_app_utils:is_app_src(File) of + true -> + file:delete(rebar_app_utils:app_src_to_app(File)), + ok; + false -> + ok + end. install(Config, File) -> @@ -116,6 +139,25 @@ install_binaries([Bin | Rest], AppDir, BinDir) -> rebar_file_utils:ln_sf(FqBin, BinDir), install_binaries(Rest, AppDir, BinDir). +preprocess(AppSrcFile) -> + case rebar_app_utils:load_app_file(AppSrcFile) of + {ok, AppName, AppData} -> + %% Get a list of all the modules available in ebin/ and update + %% the app data accordingly + A1 = lists:keystore(modules, 1, AppData, {modules, ebin_modules()}), + + %% Build the final spec as a string + Spec = io_lib:format("~p.\n", [{application, AppName, A1}]), + + %% Setup file .app filename and write new contents + AppFile = rebar_app_utils:app_src_to_app(AppSrcFile), + ok = file:write_file(AppFile, Spec), + AppFile; + + {error, Reason} -> + ?ABORT("Failed to read ~s for preprocessing: ~p\n", [AppSrcFile, Reason]) + end. + validate_name(AppName, File) -> %% Convert the .app file name to an atom -- check it against the identifier within the file @@ -136,7 +178,7 @@ validate_modules(AppName, undefined) -> validate_modules(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([rebar_utils:beam_to_mod("ebin", N) || N <- rebar_utils:beams("ebin")]), + EbinSet = ordsets:from_list(ebin_modules()), ModSet = ordsets:from_list(Mods), %% Identify .beam files listed in the .app, but not present in ebin/ @@ -160,3 +202,6 @@ validate_modules(AppName, Mods) -> [AppName, Msg2]), ?FAIL end. + +ebin_modules() -> + lists:sort([rebar_utils:beam_to_mod("ebin", N) || N <- rebar_utils:beams("ebin")]). |