aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reltool/src/reltool_server.erl
diff options
context:
space:
mode:
authorHåkan Mattsson <[email protected]>2010-03-05 15:56:02 +0100
committerHåkan Mattsson <[email protected]>2010-04-19 13:17:32 +0200
commit2846d03cb026ec9f33ea32747b4a231e1239b1ae (patch)
treee1ef7c8daad4262d496f947def2b47b1c0119a07 /lib/reltool/src/reltool_server.erl
parent067785da7c85152aa8d2436935e77fef3efaaa2d (diff)
downloadotp-2846d03cb026ec9f33ea32747b4a231e1239b1ae.tar.gz
otp-2846d03cb026ec9f33ea32747b4a231e1239b1ae.tar.bz2
otp-2846d03cb026ec9f33ea32747b4a231e1239b1ae.zip
Improved handling of applications explicitly included releases
Applications that are listed in a release are now automatically included.
Diffstat (limited to 'lib/reltool/src/reltool_server.erl')
-rw-r--r--lib/reltool/src/reltool_server.erl420
1 files changed, 221 insertions, 199 deletions
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index a9985677ba..6a3122f879 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -138,11 +138,12 @@ do_init(Options) ->
proc_lib:init_ack(ParentPid,
{ok, self(), C, Sys#sys{apps = undefined}}),
{S2, Status2} = refresh(S, true, Status),
- {S3, Status3} = analyse(S2#state{old_sys = S2#state.sys}, Status2),
- case Status3 of
- {ok, _Warnings} ->
- loop(S3#state{status = Status3, old_status = {ok, []}});
- {error, Reason} ->
+ {S3, Status3} =
+ analyse(S2#state{old_sys = S2#state.sys}, Status2),
+ case Status3 of
+ {ok, _Warnings} -> % BUGBUG: handle warnings
+ loop(S3#state{status = Status3, old_status = {ok, []}});
+ {error, Reason} ->
exit(Reason)
end
end.
@@ -161,33 +162,27 @@ parse_options(Opts) ->
rels = reltool_utils:default_rels(),
emu_name = ?DEFAULT_EMU_NAME,
profile = ?DEFAULT_PROFILE,
- incl_sys_filters =
- reltool_utils:decode_regexps(incl_sys_filters,
- ?DEFAULT_INCL_SYS_FILTERS,
- []),
- excl_sys_filters =
- reltool_utils:decode_regexps(excl_sys_filters,
- ?DEFAULT_EXCL_SYS_FILTERS,
- []),
- incl_app_filters =
- reltool_utils:decode_regexps(incl_app_filters,
- ?DEFAULT_INCL_APP_FILTERS,
- []),
- excl_app_filters =
- reltool_utils:decode_regexps(excl_app_filters,
- ?DEFAULT_EXCL_APP_FILTERS,
- []),
+ incl_sys_filters = dec_re(incl_sys_filters,
+ ?DEFAULT_INCL_SYS_FILTERS,
+ []),
+ excl_sys_filters = dec_re(excl_sys_filters,
+ ?DEFAULT_EXCL_SYS_FILTERS,
+ []),
+ incl_app_filters = dec_re(incl_app_filters,
+ ?DEFAULT_INCL_APP_FILTERS,
+ []),
+ excl_app_filters = dec_re(excl_app_filters,
+ ?DEFAULT_EXCL_APP_FILTERS,
+ []),
relocatable = ?DEFAULT_RELOCATABLE,
app_type = ?DEFAULT_APP_TYPE,
app_file = ?DEFAULT_APP_FILE,
- incl_archive_filters =
- reltool_utils:decode_regexps(incl_archive_filters,
- ?DEFAULT_INCL_ARCHIVE_FILTERS,
- []),
- excl_archive_filters =
- reltool_utils:decode_regexps(excl_archive_filters,
- ?DEFAULT_EXCL_ARCHIVE_FILTERS,
- []),
+ incl_archive_filters = dec_re(incl_archive_filters,
+ ?DEFAULT_INCL_ARCHIVE_FILTERS,
+ []),
+ excl_archive_filters = dec_re(excl_archive_filters,
+ ?DEFAULT_EXCL_ARCHIVE_FILTERS,
+ []),
archive_opts = ?DEFAULT_ARCHIVE_OPTS,
debug_info = ?DEFAULT_DEBUG_INFO},
C2 = #common{sys_debug = [],
@@ -199,6 +194,9 @@ parse_options(Opts) ->
S = #state{options = Opts},
parse_options(Opts, S, C2, Sys, {ok, []}).
+dec_re(Key, Regexps, _Old) ->
+ reltool_utils:decode_regexps(Key, Regexps, _Old).
+
parse_options([{Key, Val} | KeyVals], S, C, Sys, Status) ->
case Key of
parent ->
@@ -261,6 +259,7 @@ loop(#state{common = C, sys = Sys} = S) ->
{ok, _Warnings} ->
S5#state{status = Status3, old_status = S#state.status};
{error, _} ->
+ %% Keep old state
S
end,
reltool_utils:reply(ReplyTo, Ref, Status3),
@@ -277,9 +276,9 @@ loop(#state{common = C, sys = Sys} = S) ->
Reply =
case lists:keysearch(RelName, #rel.name, Sys#sys.rels) of
{value, Rel} ->
- {ok, reltool_target:gen_rel(Rel, Sys)};
+ reltool_target:gen_rel(Rel, Sys);
false ->
- {error, "No such release"}
+ {error, "No such release: " ++ RelName}
end,
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S);
@@ -292,7 +291,7 @@ loop(#state{common = C, sys = Sys} = S) ->
Vars = [],
reltool_target:gen_script(Rel, Sys, PathFlag, Vars);
false ->
- {error, "No such release"}
+ {error, "No such release: " ++ RelName}
end,
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S);
@@ -312,7 +311,8 @@ loop(#state{common = C, sys = Sys} = S) ->
{value, App} ->
{ok, App};
false ->
- {error, enoent}
+ {error, "No such application: " ++
+ atom_to_list(AppName)}
end,
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S);
@@ -327,6 +327,7 @@ loop(#state{common = C, sys = Sys} = S) ->
reltool_utils:reply(ReplyTo, Ref, {ok, App2, Warnings}),
?MODULE:loop(S3);
{error, Reason} ->
+ %% Keep old state
reltool_utils:reply(ReplyTo, Ref, {error, Reason}),
?MODULE:loop(S)
end;
@@ -372,16 +373,20 @@ loop(#state{common = C, sys = Sys} = S) ->
(Sys2#sys.lib_dirs =/= Sys#sys.lib_dirs) orelse
(Sys2#sys.escripts =/= Sys#sys.escripts),
{S3, Status} = refresh(S2, Force, {ok, []}),
- {S4, Status2} = analyse(S3#state{old_sys = S#state.sys}, Status),
- S6 =
- case Status2 of
- {ok, _Warnings} ->
- S4#state{status = Status2, old_status = S#state.status};
- {error, _} ->
- S
- end,
- reltool_utils:reply(ReplyTo, Ref, Status2),
- ?MODULE:loop(S6);
+ {S4, Status2} =
+ analyse(S3#state{old_sys = S#state.sys}, Status),
+ {S5, Status3} =
+ case Status2 of
+ {ok, _Warnings} -> % BUGBUG: handle warnings
+ {S4#state{status = Status2,
+ old_status = S#state.status},
+ Status2};
+ {error, _} ->
+ %% Keep old state
+ {S, Status2}
+ end,
+ reltool_utils:reply(ReplyTo, Ref, Status3),
+ ?MODULE:loop(S5);
{call, ReplyTo, Ref, get_status} ->
reltool_utils:reply(ReplyTo, Ref, S#state.status),
?MODULE:loop(S);
@@ -427,7 +432,9 @@ do_set_app(#state{sys = Sys} = S, App, Status) ->
Sys2 = Sys#sys{apps = Apps2, escripts = Escripts},
{S#state{sys = Sys2}, Status2}.
-analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) ->
+analyse(#state{common = C,
+ sys = #sys{apps = Apps0, rels = Rels} = Sys} = S,
+ Status) ->
Apps = lists:keydelete(?MISSING_APP, #app.name, Apps0),
ets:delete_all_objects(C#common.app_tab),
ets:delete_all_objects(C#common.mod_tab),
@@ -435,7 +442,13 @@ analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) ->
MissingApp = default_app(?MISSING_APP, "missing"),
ets:insert(C#common.app_tab, MissingApp),
- Apps2 = lists:map(fun(App) -> app_init_is_included(C, Sys, App) end, Apps),
+ RelApps = apps_in_rels(Rels),
+ {Apps2, Status2} =
+ lists:mapfoldl(fun(App, Acc) ->
+ app_init_is_included(C, Sys, App, RelApps, Acc)
+ end,
+ Status,
+ Apps),
Apps3 =
case app_propagate_is_included(C, Sys, Apps2, []) of
[] ->
@@ -454,15 +467,23 @@ analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) ->
%% io:format("Missing app: ~p\n",
%% [lists:keysearch(?MISSING_APP, #app.name, Apps4)]),
Sys2 = Sys#sys{apps = Apps4},
- try
- Status2 = verify_config(Sys2, Status),
- {S#state{sys = Sys2}, Status2}
- catch
- throw:{error, Status3} ->
+ case verify_config(Sys2, Status2) of
+ {ok, _Warnings} = Status3 ->
+ {S#state{sys = Sys2}, Status3};
+ {error, _} = Status3 ->
{S, Status3}
end.
-app_init_is_included(C, Sys, #app{mods = Mods} = A) ->
+apps_in_rels(Rels) ->
+ [{RelName, AppName} || #rel{name = RelName, rel_apps = RelApps} <- Rels,
+ RA <- RelApps,
+ AppName <- [RA#rel_app.name | RA#rel_app.incl_apps]].
+
+app_init_is_included(C,
+ Sys,
+ #app{name = AppName, mods = Mods} = A,
+ RelApps,
+ Status) ->
AppCond =
case A#app.incl_cond of
undefined -> Sys#sys.incl_cond;
@@ -473,24 +494,37 @@ app_init_is_included(C, Sys, #app{mods = Mods} = A) ->
undefined -> Sys#sys.mod_cond;
_ -> A#app.mod_cond
end,
- IsIncl =
- case AppCond of
- include -> true;
- exclude -> false;
- derived -> undefined
+ Rels = [RelName || {RelName, AN} <- RelApps, AN =:= AppName],
+ {Default, IsPreIncl, IsIncl, Status2} =
+ case {AppCond, Rels} of
+ {include, _} ->
+ {undefined, true, true, Status};
+ {exclude, []} ->
+ {undefined, false, false, Status};
+ {exclude, [RelName | _]} -> % App is included in at least one rel
+ Text = lists:concat(["Application ", AppName, " is used "
+ "in release ", RelName, " and cannot "
+ "be excluded"]),
+ TmpStatus = reltool_utils:return_first_error(Status, Text),
+ {undefined, false, false, TmpStatus};
+ {derived, []} ->
+ {undefined, undefined, undefined, Status};
+ {derived, [_ | _]} -> % App is included in at least one rel
+ {true, undefined, true, Status}
end,
- A2 = A#app{is_pre_included = IsIncl, is_included = IsIncl},
+ A2 = A#app{is_pre_included = IsPreIncl,
+ is_included = IsIncl,
+ rels = Rels},
ets:insert(C#common.app_tab, A2),
lists:foreach(fun(Mod) ->
mod_init_is_included(C,
Mod,
ModCond,
AppCond,
- undefined)
+ Default)
end,
Mods),
- %%app_mod_init_is_included(C, AppName, Info, ModCond, AppCond),
- A2.
+ {A2, Status2}.
mod_init_is_included(C, M, ModCond, AppCond, Default) ->
%% print(M#mod.name, hipe, "incl_cond -> ~p\n", [AppCond]),
@@ -862,11 +896,15 @@ read_app_info(AppFileOrBin, AppFile, AppName, DefaultVsn, Status) ->
parse_app_info(AppFile, Info, AI, Status);
{ok, _BadApp} ->
Text = lists:concat([AppName,
- ": Illegal contents in app file ", AppFile]),
+ ": Illegal contents in app file ", AppFile,
+ ", application tuple with arity 3 expected."]),
{missing_app_info(DefaultVsn),
reltool_utils:add_warning(Status, Text)};
- {error, Text} when Text =:= EnoentText->
- {missing_app_info(DefaultVsn), Status};
+ {error, Text} when Text =:= EnoentText ->
+ Text2 = lists:concat([AppName,
+ ": Missing app file ", AppFile, "."]),
+ {missing_app_info(DefaultVsn),
+ reltool_utils:add_warning(Status, Text2)};
{error, Text} ->
Text2 = lists:concat([AppName,
": Cannot parse app file ",
@@ -1045,7 +1083,7 @@ do_get_config(S, InclDef, InclDeriv) ->
false -> shrink_sys(S);
true -> S
end,
- {ok, reltool_target:gen_config(S2#state.sys, InclDef)}.
+ reltool_target:gen_config(S2#state.sys, InclDef).
do_save_config(S, Filename, InclDef, InclDeriv) ->
{ok, Config} = do_get_config(S, InclDef, InclDeriv),
@@ -1072,6 +1110,7 @@ do_load_config(S, SysConfig) ->
{ok, _Warnings2} ->
S3#state{status = Status3, old_status = S#state.status};
{error, _} ->
+ %% Keep old state
S
end,
{S4, Status3};
@@ -1099,24 +1138,30 @@ read_config(OldSys, Filename, Status) when is_list(Filename) ->
end;
read_config(OldSys, {sys, KeyVals}, Status) ->
{NewSys, Status2} =
- try
- decode(OldSys#sys{apps = [], rels = []}, KeyVals, Status)
- catch
- throw:{error, Text} ->
- {OldSys, reltool_utils:return_first_error(Status, Text)}
- end,
- Apps = [A#app{mods = lists:sort(A#app.mods)} || A <- NewSys#sys.apps],
- case NewSys#sys.rels of
- [] -> Rels = reltool_utils:default_rels();
- Rels -> ok
- end,
- NewSys2 = NewSys#sys{apps = lists:sort(Apps), rels = lists:sort(Rels)},
- case lists:keysearch(NewSys2#sys.boot_rel, #rel.name, NewSys2#sys.rels) of
- {value, _} ->
- {NewSys2, Status2};
- false ->
- Text2 = "Missing rel: " ++ NewSys2#sys.boot_rel,
- {OldSys, reltool_utils:return_first_error(Status2, Text2)}
+ decode(OldSys#sys{apps = [], rels = []}, KeyVals, Status),
+ case Status2 of
+ {ok, _Warnings} -> % BUGBUG: handle warnings
+ Apps = [A#app{mods = lists:sort(A#app.mods)} ||
+ A <- NewSys#sys.apps],
+ case NewSys#sys.rels of
+ [] -> Rels = reltool_utils:default_rels();
+ Rels -> ok
+ end,
+ NewSys2 = NewSys#sys{apps = lists:sort(Apps),
+ rels = lists:sort(Rels)},
+ case lists:keysearch(NewSys2#sys.boot_rel,
+ #rel.name,
+ NewSys2#sys.rels) of
+ {value, _} ->
+ {NewSys2, Status2};
+ false ->
+ Text2 = lists:concat(["Release " ++ NewSys2#sys.boot_rel,
+ " is mandatory (used as boot_rel)"]),
+ {OldSys, reltool_utils:return_first_error(Status2, Text2)}
+ end;
+ {error, _} ->
+ %% Keep old state
+ {OldSys, Status2}
end;
read_config(OldSys, BadConfig, Status) ->
Text = lists:flatten(io_lib:format("~p", [BadConfig])),
@@ -1175,96 +1220,78 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
profile when Val =:= development ->
Val = ?DEFAULT_PROFILE, % assert,
{Sys#sys{profile = Val,
- incl_sys_filters =
- reltool_utils:decode_regexps(incl_sys_filters,
- ?DEFAULT_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters =
- reltool_utils:decode_regexps(excl_sys_filters,
- ?DEFAULT_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters =
- reltool_utils:decode_regexps(incl_app_filters,
- ?DEFAULT_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters =
- reltool_utils:decode_regexps(excl_app_filters,
- ?DEFAULT_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters = dec_re(incl_sys_filters,
+ ?DEFAULT_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters = dec_re(excl_sys_filters,
+ ?DEFAULT_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters = dec_re(incl_app_filters,
+ ?DEFAULT_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters = dec_re(excl_app_filters,
+ ?DEFAULT_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
profile when Val =:= embedded ->
{Sys#sys{profile = Val,
- incl_sys_filters =
- reltool_utils:decode_regexps(incl_sys_filters,
- ?EMBEDDED_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters =
- reltool_utils:decode_regexps(excl_sys_filters,
- ?EMBEDDED_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters =
- reltool_utils:decode_regexps(incl_app_filters,
- ?EMBEDDED_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters =
- reltool_utils:decode_regexps(excl_app_filters,
- ?EMBEDDED_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters = dec_re(incl_sys_filters,
+ ?EMBEDDED_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters = dec_re(excl_sys_filters,
+ ?EMBEDDED_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters = dec_re(incl_app_filters,
+ ?EMBEDDED_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters = dec_re(excl_app_filters,
+ ?EMBEDDED_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
profile when Val =:= standalone ->
{Sys#sys{profile = Val,
- incl_sys_filters =
- reltool_utils:decode_regexps(incl_sys_filters,
- ?STANDALONE_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters =
- reltool_utils:decode_regexps(excl_sys_filters,
- ?STANDALONE_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters =
- reltool_utils:decode_regexps(incl_app_filters,
- ?STANDALONE_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters =
- reltool_utils:decode_regexps(excl_app_filters,
- ?STANDALONE_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters = dec_re(incl_sys_filters,
+ ?STANDALONE_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters = dec_re(excl_sys_filters,
+ ?STANDALONE_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters = dec_re(incl_app_filters,
+ ?STANDALONE_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters = dec_re(excl_app_filters,
+ ?STANDALONE_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
incl_sys_filters ->
- {Sys#sys{incl_sys_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- Sys#sys.incl_sys_filters)},
+ {Sys#sys{incl_sys_filters = dec_re(Key,
+ Val,
+ Sys#sys.incl_sys_filters)},
Status};
excl_sys_filters ->
- {Sys#sys{excl_sys_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- Sys#sys.excl_sys_filters)},
+ {Sys#sys{excl_sys_filters = dec_re(Key,
+ Val,
+ Sys#sys.excl_sys_filters)},
Status};
incl_app_filters ->
- {Sys#sys{incl_app_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- Sys#sys.incl_app_filters)},
+ {Sys#sys{incl_app_filters = dec_re(Key,
+ Val,
+ Sys#sys.incl_app_filters)},
Status};
excl_app_filters ->
- {Sys#sys{excl_app_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- Sys#sys.excl_app_filters)},
+ {Sys#sys{excl_app_filters = dec_re(Key,
+ Val,
+ Sys#sys.excl_app_filters)},
Status};
incl_archive_filters ->
- {Sys#sys{incl_archive_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- Sys#sys.incl_archive_filters)},
+ {Sys#sys{incl_archive_filters = dec_re(Key,
+ Val,
+ Sys#sys.incl_archive_filters)},
Status};
excl_archive_filters ->
- {Sys#sys{excl_archive_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- Sys#sys.excl_archive_filters)},
+ {Sys#sys{excl_archive_filters = dec_re(Key,
+ Val,
+ Sys#sys.excl_archive_filters)},
Status};
archive_opts when is_list(Val) ->
{Sys#sys{archive_opts = Val}, Status};
@@ -1304,7 +1331,7 @@ decode(#app{} = App, [{Key, Val} | KeyVals], Status) ->
Val =:= strip ->
{App#app{debug_info = Val}, Status};
app_file when Val =:= keep;
- Val =:= strip,
+ Val =:= strip;
Val =:= all ->
{App#app{app_file = Val}, Status};
app_type when Val =:= permanent;
@@ -1314,28 +1341,24 @@ decode(#app{} = App, [{Key, Val} | KeyVals], Status) ->
Val =:= none ->
{App#app{app_type = Val}, Status};
incl_app_filters ->
- {App#app{incl_app_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- App#app.incl_app_filters)},
+ {App#app{incl_app_filters = dec_re(Key,
+ Val,
+ App#app.incl_app_filters)},
Status};
excl_app_filters ->
- {App#app{excl_app_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- App#app.excl_app_filters)},
+ {App#app{excl_app_filters = dec_re(Key,
+ Val,
+ App#app.excl_app_filters)},
Status};
incl_archive_filters ->
- {App#app{incl_archive_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- App#app.incl_archive_filters)},
+ {App#app{incl_archive_filters = dec_re(Key,
+ Val,
+ App#app.incl_archive_filters)},
Status};
excl_archive_filters ->
- {App#app{excl_archive_filters =
- reltool_utils:decode_regexps(Key,
- Val,
- App#app.excl_archive_filters)},
+ {App#app{excl_archive_filters = dec_re(Key,
+ Val,
+ App#app.excl_archive_filters)},
Status};
archive_opts when is_list(Val) ->
{App#app{archive_opts = Val}, Status};
@@ -1443,51 +1466,49 @@ merge_config(OldSys, NewSys, Force, Status) ->
verify_config(Sys, Status) ->
case lists:keymember(Sys#sys.boot_rel, #rel.name, Sys#sys.rels) of
true ->
- lists:foreach(fun(Rel)-> check_rel(Rel, Sys, Status) end,
- Sys#sys.rels),
- Status;
+ lists:foldl(fun(Rel, Acc)-> check_rel(Rel, Sys, Acc) end,
+ Status,
+ Sys#sys.rels);
false ->
- Text = lists:concat([Sys#sys.boot_rel, ": release is mandatory"]),
- Status2 = reltool_utils:return_first_error(Status, Text),
- throw({error, Status2})
+ Text = lists:concat(["Release ", Sys#sys.boot_rel,
+ " is mandatory (used as boot_rel)"]),
+ reltool_utils:return_first_error(Status, Text)
end.
check_rel(#rel{name = RelName, rel_apps = RelApps},
#sys{apps = Apps},
Status) ->
EnsureApp =
- fun(AppName) ->
+ fun(AppName, Acc) ->
case lists:keymember(AppName, #rel_app.name, RelApps) of
true ->
- ok;
+ Acc;
false ->
- Text = lists:concat([RelName, ": ", AppName,
- " is not included."]),
- Status2 =
- reltool_utils:return_first_error(Status, Text),
- throw({error, Status2})
+ Text = lists:concat(["Mandatory application ",
+ AppName,
+ " is not included in release ",
+ RelName]),
+ reltool_utils:return_first_error(Acc, Text)
end
end,
- EnsureApp(kernel),
- EnsureApp(stdlib),
+ Mandatory = [kernel, stdlib],
+ Status2 = lists:foldl(EnsureApp, Status, Mandatory),
CheckRelApp =
- fun(#rel_app{name = AppName}) ->
+ fun(#rel_app{name = AppName}, Acc) ->
case lists:keysearch(AppName, #app.name, Apps) of
{value, App} when App#app.is_pre_included ->
- ok;
+ Acc;
{value, App} when App#app.is_included ->
- ok;
+ Acc;
_ ->
- Text =
- lists:concat([RelName, ": uses application ",
- AppName, " that not is included."]),
- Status2 =
- reltool_utils:return_first_error(Status, Text),
- %% throw BUGBUG: add throw
- ({error, Status2})
+ Text = lists:concat(["Release ", RelName,
+ " uses non included application ",
+ AppName]),
+
+ reltool_utils:return_first_error(Acc, Text)
end
end,
- lists:foreach(CheckRelApp, RelApps).
+ lists:foldl(CheckRelApp, Status2, RelApps).
patch_erts_version(RootDir, Apps, Status) ->
AppName = erts,
@@ -1508,7 +1529,7 @@ patch_erts_version(RootDir, Apps, Status) ->
{Apps, Status}
end;
false ->
- Text = "erts cannnot be found in the root directory " ++ RootDir,
+ Text = "erts cannot be found in the root directory " ++ RootDir,
Status2 = reltool_utils:return_first_error(Status, Text),
{Apps, Status2}
end.
@@ -1814,7 +1835,8 @@ default_app(Name) ->
status = missing,
uses_mods = undefined,
is_pre_included = undefined,
- is_included = undefined}.
+ is_included = undefined,
+ rels = undefined}.
%% Assume that the application are sorted
refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status)