Complete implementation for simplistic .app.src processing.

This commit is contained in:
Dave Smith 2010-05-07 12:01:48 -06:00
parent 902e00fb93
commit 2af6dc84ae
3 changed files with 78 additions and 19 deletions

View file

@ -27,6 +27,8 @@
-module(rebar_app_utils). -module(rebar_app_utils).
-export([is_app_dir/0, is_app_dir/1, -export([is_app_dir/0, is_app_dir/1,
is_app_src/1,
app_src_to_app/1,
app_name/1, app_name/1,
app_applications/1, app_applications/1,
app_vsn/1]). app_vsn/1]).
@ -43,14 +45,31 @@ is_app_dir() ->
is_app_dir(rebar_util:get_cwd()). is_app_dir(rebar_util:get_cwd()).
is_app_dir(Dir) -> is_app_dir(Dir) ->
Fname = filename:join([Dir, "ebin/*.app"]), AppSrc = filename:join(Dir, "src/*.app.src"),
case filelib:wildcard(Fname) of case filelib:wildcard(AppSrc) of
[AppSrcFile] ->
?DEBUG("Found app.src: ~p\n", [AppSrcFile]),
{true, AppSrcFile};
_ ->
App = filename:join([Dir, "ebin/*.app"]),
case filelib:wildcard(App) of
[AppFile] -> [AppFile] ->
?DEBUG("Found .app: ~p\n", [AppFile]),
{true, AppFile}; {true, AppFile};
_ -> _ ->
false false
end
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) -> app_name(AppFile) ->
case load_app_file(AppFile) of case load_app_file(AppFile) of
{ok, AppName, _} -> {ok, AppName, _} ->
@ -79,7 +98,6 @@ app_vsn(AppFile) ->
end. end.
%% =================================================================== %% ===================================================================
%% Internal functions %% Internal functions
%% =================================================================== %% ===================================================================

View file

@ -27,6 +27,7 @@
-module(rebar_otp_app). -module(rebar_otp_app).
-export([compile/2, -export([compile/2,
clean/2,
install/2]). install/2]).
-include("rebar.hrl"). -include("rebar.hrl").
@ -36,12 +37,34 @@
%% =================================================================== %% ===================================================================
compile(_Config, File) -> compile(_Config, File) ->
%% Load the app name and version from the .app file and construct %% If we get an .app.src file, it needs to be pre-processed and
%% the app identifier %% written out as a ebin/*.app file. That resulting file will then
{ok, AppName, AppData} = rebar_app_utils:load_app_file(File), %% be validated as usual.
validate_name(AppName, File), case rebar_app_utils:is_app_src(File) of
validate_modules(AppName, proplists:get_value(modules, AppData)), true ->
ok. 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) -> install(Config, File) ->
@ -116,6 +139,25 @@ install_binaries([Bin | Rest], AppDir, BinDir) ->
rebar_file_utils:ln_sf(FqBin, BinDir), rebar_file_utils:ln_sf(FqBin, BinDir),
install_binaries(Rest, AppDir, 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) -> validate_name(AppName, File) ->
%% Convert the .app file name to an atom -- check it against the identifier within the 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) -> validate_modules(AppName, Mods) ->
%% Construct two sets -- one for the actual .beam files in ebin/ and one for the modules %% Construct two sets -- one for the actual .beam files in ebin/ and one for the modules
%% listed in the .app file %% 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), ModSet = ordsets:from_list(Mods),
%% Identify .beam files listed in the .app, but not present in ebin/ %% Identify .beam files listed in the .app, but not present in ebin/
@ -160,3 +202,6 @@ validate_modules(AppName, Mods) ->
[AppName, Msg2]), [AppName, Msg2]),
?FAIL ?FAIL
end. end.
ebin_modules() ->
lists:sort([rebar_utils:beam_to_mod("ebin", N) || N <- rebar_utils:beams("ebin")]).

View file

@ -352,12 +352,8 @@ so_specs(Config, AppFile, Bins) ->
undefined -> undefined ->
%% Ok, neither old nor new form is available. Use the app name and %% Ok, neither old nor new form is available. Use the app name and
%% generate a sensible default. %% generate a sensible default.
case rebar_app_utils:load_app_file(AppFile) of AppName = rebar_app_utils:app_name(AppFile),
{ok, AppName, _} ->
?FMT("priv/~s", [lists:concat([AppName, "_drv.so"])]); ?FMT("priv/~s", [lists:concat([AppName, "_drv.so"])]);
error ->
?FAIL
end;
AName -> AName ->
%% Old form is available -- use it %% Old form is available -- use it