mirror of
https://github.com/correl/rebar.git
synced 2024-12-18 11:06:20 +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).
|
-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
|
||||||
%% ===================================================================
|
%% ===================================================================
|
||||||
|
|
|
@ -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")]).
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue