mirror of
https://github.com/correl/rebar.git
synced 2024-12-18 03:00:17 +00:00
Complete implementation for simplistic .app.src processing.
This commit is contained in:
parent
902e00fb93
commit
2af6dc84ae
3 changed files with 78 additions and 19 deletions
|
@ -27,6 +27,8 @@
|
|||
-module(rebar_app_utils).
|
||||
|
||||
-export([is_app_dir/0, is_app_dir/1,
|
||||
is_app_src/1,
|
||||
app_src_to_app/1,
|
||||
app_name/1,
|
||||
app_applications/1,
|
||||
app_vsn/1]).
|
||||
|
@ -43,14 +45,31 @@ is_app_dir() ->
|
|||
is_app_dir(rebar_util:get_cwd()).
|
||||
|
||||
is_app_dir(Dir) ->
|
||||
Fname = filename:join([Dir, "ebin/*.app"]),
|
||||
case filelib:wildcard(Fname) of
|
||||
[AppFile] ->
|
||||
{true, AppFile};
|
||||
AppSrc = filename:join(Dir, "src/*.app.src"),
|
||||
case filelib:wildcard(AppSrc) of
|
||||
[AppSrcFile] ->
|
||||
?DEBUG("Found app.src: ~p\n", [AppSrcFile]),
|
||||
{true, AppSrcFile};
|
||||
_ ->
|
||||
false
|
||||
App = filename:join([Dir, "ebin/*.app"]),
|
||||
case filelib:wildcard(App) of
|
||||
[AppFile] ->
|
||||
?DEBUG("Found .app: ~p\n", [AppFile]),
|
||||
{true, AppFile};
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
is_app_src(Filename) ->
|
||||
%% If removing the extension .app.src yields a shorter name,
|
||||
%% this is an .app.src file.
|
||||
Filename /= filename:rootname(Filename, ".app.src").
|
||||
|
||||
app_src_to_app(Filename) ->
|
||||
filename:join("ebin", filename:basename(Filename, ".app.src") ++ ".app").
|
||||
|
||||
app_name(AppFile) ->
|
||||
case load_app_file(AppFile) of
|
||||
{ok, AppName, _} ->
|
||||
|
@ -79,7 +98,6 @@ app_vsn(AppFile) ->
|
|||
end.
|
||||
|
||||
|
||||
|
||||
%% ===================================================================
|
||||
%% Internal functions
|
||||
%% ===================================================================
|
||||
|
|
|
@ -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")]).
|
||||
|
|
|
@ -352,12 +352,8 @@ so_specs(Config, AppFile, Bins) ->
|
|||
undefined ->
|
||||
%% Ok, neither old nor new form is available. Use the app name and
|
||||
%% generate a sensible default.
|
||||
case rebar_app_utils:load_app_file(AppFile) of
|
||||
{ok, AppName, _} ->
|
||||
?FMT("priv/~s", [lists:concat([AppName, "_drv.so"])]);
|
||||
error ->
|
||||
?FAIL
|
||||
end;
|
||||
AppName = rebar_app_utils:app_name(AppFile),
|
||||
?FMT("priv/~s", [lists:concat([AppName, "_drv.so"])]);
|
||||
|
||||
AName ->
|
||||
%% Old form is available -- use it
|
||||
|
|
Loading…
Reference in a new issue