Skip to content

Commit

Permalink
add support for excluding applications from the release
Browse files Browse the repository at this point in the history
  • Loading branch information
tsloughter committed Jan 31, 2015
1 parent 3a6b643 commit 18d0db5
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 5 deletions.
11 changes: 9 additions & 2 deletions src/rlx_app_discovery.erl
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,10 @@ resolve_app_metadata(State, LibDirs) ->
end] of
[] ->
SkipApps = rlx_state:skip_apps(State),
AppMeta1 = [App || {ok, App} <- setup_overrides(State, AppMeta0),
not lists:keymember(rlx_app_info:name(App), 1, SkipApps)],
ExcludeApps = rlx_state:exclude_apps(State),
AppMeta1 = [rm_exclude_apps(App, ExcludeApps) ||
{ok, App} <- setup_overrides(State, AppMeta0),
not lists:keymember(rlx_app_info:name(App), 1, SkipApps++ExcludeApps)],
ec_cmd_log:debug(rlx_state:log(State),
fun() ->
["Resolved the following OTP Applications from the system: \n",
Expand All @@ -129,6 +131,11 @@ resolve_app_metadata(State, LibDirs) ->
Errors ->
?RLX_ERROR(Errors)
end.
%% Apps listed in {exclude_apps, [...]} must be removed from applications lists
rm_exclude_apps(App, ExcludeApps) ->
ActiveApps = lists:subtract(rlx_app_info:active_deps(App), ExcludeApps),
LibraryApps = lists:subtract(rlx_app_info:library_deps(App), ExcludeApps),
rlx_app_info:library_deps(rlx_app_info:active_deps(App, ActiveApps), LibraryApps).

app_name({warning, _}) ->
undefined;
Expand Down
2 changes: 2 additions & 0 deletions src/rlx_config.erl
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ load_terms({add_providers, Providers0}, {ok, State0}) ->
end;
load_terms({skip_apps, SkipApps0}, {ok, State0}) ->
{ok, rlx_state:skip_apps(State0, SkipApps0)};
load_terms({exclude_apps, ExcludeApps0}, {ok, State0}) ->
{ok, rlx_state:exclude_apps(State0, ExcludeApps0)};
load_terms({debug_info, DebugInfo}, {ok, State0}) ->
{ok, rlx_state:debug_info(State0, DebugInfo)};
load_terms({overrides, Overrides0}, {ok, State0}) ->
Expand Down
44 changes: 42 additions & 2 deletions src/rlx_prv_assembler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,49 @@ copy_app_(App, AppDir, TargetDir, IncludeSrc) ->
remove_symlink_or_directory(TargetDir),
case rlx_app_info:link(App) of
true ->
link_directory(AppDir, TargetDir);
link_directory(AppDir, TargetDir),
rewrite_app_file(App, AppDir);
false ->
copy_directory(AppDir, TargetDir, IncludeSrc)
copy_directory(AppDir, TargetDir, IncludeSrc),
rewrite_app_file(App, TargetDir)
end.

%% If excluded apps exist in this App's applications list we must write a new .app
rewrite_app_file(App, TargetDir) ->
Name = rlx_app_info:name(App),
ActiveDeps = rlx_app_info:active_deps(App),
IncludedDeps = rlx_app_info:library_deps(App),
AppFile = filename:join([TargetDir, "ebin", ec_cnv:to_list(Name) ++ ".app"]),

{ok, [{application, AppName, AppData}]} = file:consult(AppFile),
OldActiveDeps = proplists:get_value(applications, AppData, []),
OldIncludedDeps = proplists:get_value(included_applications, AppData, []),

case {OldActiveDeps, OldIncludedDeps} of
{ActiveDeps, IncludedDeps} ->
ok;
_ ->
AppData1 = lists:keyreplace(applications
,1
,AppData
,{applications, ActiveDeps}),
AppData2 = lists:keyreplace(included_applications
,1
,AppData1
,{included_applications, IncludedDeps}),
Spec = io_lib:format("~p.\n", [{application, AppName, AppData2}]),
write_file_if_contents_differ(AppFile, Spec)
end.

write_file_if_contents_differ(Filename, Bytes) ->
ToWrite = iolist_to_binary(Bytes),
case file:read_file(Filename) of
{ok, ToWrite} ->
ok;
{ok, _} ->
file:write_file(Filename, ToWrite);
{error, _} ->
file:write_file(Filename, ToWrite)
end.

remove_symlink_or_directory(TargetDir) ->
Expand Down
12 changes: 12 additions & 0 deletions src/rlx_state.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
overrides/2,
skip_apps/1,
skip_apps/2,
exclude_apps/1,
exclude_apps/2,
debug_info/1,
debug_info/2,
goals/1,
Expand Down Expand Up @@ -104,6 +106,7 @@
sys_config :: file:filename() | undefined,
overrides=[] :: [{AppName::atom(), Directory::file:filename()}],
skip_apps=[] :: [AppName::atom()],
exclude_apps=[] :: [AppName::atom()],
debug_info=keep :: keep | strip,
configured_releases :: releases(),
realized_releases :: releases(),
Expand Down Expand Up @@ -186,6 +189,15 @@ skip_apps(#state_t{skip_apps=Apps}) ->
skip_apps(State, SkipApps) ->
State#state_t{skip_apps=SkipApps}.

-spec exclude_apps(t()) -> [AppName::atom()].
exclude_apps(#state_t{exclude_apps=Apps}) ->
Apps.

%% @doc the application overrides for the system
-spec exclude_apps(t(), [AppName::atom()]) -> t().
exclude_apps(State, SkipApps) ->
State#state_t{exclude_apps=SkipApps}.

-spec debug_info(t()) -> keep | strip.
debug_info(#state_t{debug_info=DebugInfo}) ->
DebugInfo.
Expand Down
30 changes: 29 additions & 1 deletion test/rlx_release_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
make_scriptless_release/1,
make_overridden_release/1,
make_skip_app_release/1,
make_exclude_app_release/1,
make_auto_skip_empty_app_release/1,
make_app_type_none_release/1,
make_rerun_overridden_release/1,
Expand Down Expand Up @@ -68,7 +69,7 @@ init_per_testcase(_, Config) ->
all() ->
[make_release, make_extend_release, make_scriptless_release,
make_overridden_release, make_auto_skip_empty_app_release,
make_skip_app_release, make_app_type_none_release,
make_skip_app_release, make_exclude_app_release, make_app_type_none_release,
make_implicit_config_release, make_rerun_overridden_release,
overlay_release, make_goalless_release, make_depfree_release,
make_invalid_config_release, make_relup_release, make_relup_release2,
Expand Down Expand Up @@ -309,6 +310,33 @@ make_skip_app_release(Config) ->
?assertNot(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).

%% Test to ensure that an excluded app and its deps are not included in a release
make_exclude_app_release(Config) ->
LibDir1 = proplists:get_value(lib1, Config),

rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel, non_goal_1], []),
rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel, non_goal_2], []),
rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),

ConfigFile = filename:join([LibDir1, "relx.config"]),
rlx_test_utils:write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1]},
{exclude_apps, [non_goal_1]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
rlx_test_utils:create_random_name("relx-output")]),
{ok, Cwd} = file:get_cwd(),
{ok, State} = relx:do(Cwd, undefined, undefined, [], [LibDir1], 3,
OutputDir, [],
ConfigFile),
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assertNot(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
?assertNot(lists:member({non_goal_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)).

make_auto_skip_empty_app_release(Config) ->
DataDir = proplists:get_value(data_dir, Config),
EmptyAppDir1 = filename:join([DataDir, rlx_test_utils:create_random_name("skip_app_dir_")]),
Expand Down

0 comments on commit 18d0db5

Please sign in to comment.