Skip to content

Commit

Permalink
[#83] Update .app file with modules after compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
jfacorro committed Jul 10, 2020
1 parent 8c543b0 commit 3142c32
Showing 1 changed file with 44 additions and 30 deletions.
74 changes: 44 additions & 30 deletions src/rebar3_clojerl_prv_compile.erl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ do(State) ->
Apps1 = compile_clojerl(Apps0, Config, Providers, State),
[compile(AppInfo, Config, Providers, State) || AppInfo <- Apps1],

%% Update .app file in all project apps
[update_app_file(rebar_app_info:ebin_dir(AppInfo)) || AppInfo <- Apps0],

%% Run top level post hooks
rebar_hooks:run_all_hooks(Cwd, post, ?NAMESPACE_PROVIDER, Providers, State)
after
Expand Down Expand Up @@ -117,24 +120,25 @@ backup_duplicates(DepsDirs, Config) ->
BeamFilepaths = rebar_utils:find_files(ProtoDir, ".beam$"),
BeamFilenames = [filename:basename(F) || F <- BeamFilepaths],

Dirs = DepsDirs -- [ProtoDir],
Dirs = DepsDirs -- [ProtoDir],
rebar_api:debug("Finding duplicates for:~n~p~nin~n~p", [BeamFilenames, Dirs]),
Deleted = [backup_duplicates_from_dir(BeamFilenames, Dir) || Dir <- Dirs],

ok = lists:foreach(fun update_app_file/1, Deleted).
Duplicates = [ {Dir, backup_duplicates_from_dir(BeamFilenames, Dir)}
|| Dir <- Dirs
],
%% Update .app files where there were duplicate modules detected
[update_app_file(Dir) || {Dir, Modules} <- Duplicates, Modules =/= []],
ok.

-spec backup_duplicates_from_dir([file:name()], file:name()) ->
{file:name(), [file:name()]}.
-spec backup_duplicates_from_dir([file:name()], file:name()) -> [file:name()].
backup_duplicates_from_dir(BeamFilenames, Dir) ->
Filepaths = [ begin
rebar_api:debug("Backup duplicate ~s", [F]),
ok = file:rename(F, F ++ ".backup"),
F
end
|| F <- rebar_utils:find_files(Dir, ".beam$"),
lists:member(filename:basename(F), BeamFilenames)
],
{Dir, Filepaths}.
[ begin
rebar_api:debug("Backup duplicate ~s", [F]),
ok = file:rename(F, F ++ ".backup"),
F
end
|| F <- rebar_utils:find_files(Dir, ".beam$"),
lists:member(filename:basename(F), BeamFilenames)
].

-spec restore_duplicates([file:name()]) -> ok.
restore_duplicates(Dirs) ->
Expand All @@ -148,28 +152,38 @@ restore_duplicates(Dirs) ->
],
ok.

-spec update_app_file({file:name(), [file:name()]}) -> ok.
update_app_file({_Dir, []}) ->
ok;
update_app_file({Dir, Filepaths}) ->
%% @doc Updates the list of modules in the .app file for the specified
%% directory.
%%
%% The .app file will be update to include all modules in its
%% `modules' entry. The modules listed are resolved by looking for all
%% files with the extension `.beam' in `Dir'.
-spec update_app_file(file:name()) -> ok.
update_app_file(Dir) ->
case rebar_utils:find_files(Dir, ".app$", false) of
[AppFile] ->
DeletedModules = [ list_to_atom(filename:basename(Path, ".beam"))
|| Path <- Filepaths
],
{ok, [{application, AppName, AppDetail0}]} = file:consult(AppFile),
rebar_api:debug("Updating app file for ~p", [AppName]),
rebar_api:debug("Removing modules:~n~p", [DeletedModules]),
AppModules0 = proplists:get_value(modules, AppDetail0, []),
AppModules1 = AppModules0 -- DeletedModules,

BeamPaths = rebar_utils:find_files(Dir, ".beam$", false),
Modules = [ list_to_atom(filename:basename(Path, ".beam"))
|| Path <- BeamPaths
],
AppDetail1 = lists:keyreplace( modules
, 1
, AppDetail0
, {modules, AppModules1}
, {modules, Modules}
),
Spec = io_lib:format("~p.\n", [{application, AppName, AppDetail1}]),
ok = rebar_file_utils:write_file_if_contents_differ(AppFile, Spec, utf8),
SpecBefore = io_lib:format("~p.\n", [{application, AppName, AppDetail0}]),
SpecAfter = io_lib:format("~p.\n", [{application, AppName, AppDetail1}]),

rebar_api:debug("Updating app file for ~p", [AppName]),
rebar_api:debug("~p.app (BEFORE):~n~p", [AppName, SpecBefore]),
rebar_api:debug("~p.app (AFTER):~n~s", [AppName, SpecAfter]),

ok = rebar_file_utils:write_file_if_contents_differ( AppFile
, SpecAfter
, utf8
),
ok;
[] -> ok
end.
Expand Down Expand Up @@ -364,7 +378,7 @@ clje_compile_first(AppInfo) ->
{Positions, _} = lists:foldl(Fun, {#{}, length(CljeFirst)}, CljeFirst),
Positions.

-spec src_to_target(file:name()) -> file:name().
-spec src_to_target(file:name()) -> file:filename_all().
src_to_target(Src) ->
SrcBin = iolist_to_binary(Src),
Filename0 = clj_utils:resource_to_ns(SrcBin),
Expand Down

0 comments on commit 3142c32

Please sign in to comment.