diff options
author | Siri Hansen <[email protected]> | 2012-09-17 12:27:05 +0200 |
---|---|---|
committer | Siri Hansen <[email protected]> | 2012-09-17 12:27:05 +0200 |
commit | 04c6b9a40f782099ece28dbde39c35f25dd2e37b (patch) | |
tree | f580dc9c18dbb948d771cbda65c1da57a9170a52 /lib/reltool/src/reltool_target.erl | |
parent | 6a40b71e364fd0ac7f68bebfdd51c80f9f66730a (diff) | |
download | otp-04c6b9a40f782099ece28dbde39c35f25dd2e37b.tar.gz otp-04c6b9a40f782099ece28dbde39c35f25dd2e37b.tar.bz2 otp-04c6b9a40f782099ece28dbde39c35f25dd2e37b.zip |
[reltool] Keep order from rel spec when sorting used and included applications
The rel specification now dictates the order in which included and
used applications are loaded/started by the boot file. If the
applications are not specified in the rel spec, then the order from
the .app file is used. This was a bug earlier reported on systools,
and is now also implemented in reltool.
Example:
If a .app file specified
{applications,[x,y]}
{included_applications,[b,c]}
And the reltool.config has
{rel, "myrel", "1.0", [a,y,x,c,b]}
Then the boot file will load/start y before x and c before b. Earlier
x would always be started before y and b always before c due to the
order in the .app file.
Diffstat (limited to 'lib/reltool/src/reltool_target.erl')
-rw-r--r-- | lib/reltool/src/reltool_target.erl | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index a47da75c63..6cb7ba0163 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -333,7 +333,9 @@ merge_apps(#rel{name = RelName, A#app.name =/= ?MISSING_APP_NAME, not lists:keymember(A#app.name, #app.name, MergedApps2)], MergedApps3 = do_merge_apps(RelName, Embedded, Apps, EmbAppType, MergedApps2), - sort_apps(lists:reverse(MergedApps3)). + RevMerged = lists:reverse(MergedApps3), + MergedSortedUsedAndIncs = sort_used_and_incl_apps(RevMerged,RevMerged), + sort_apps(MergedSortedUsedAndIncs). do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, Acc) -> case is_already_merged(Name, RelApps, Acc) of @@ -509,6 +511,56 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> SplitMods). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% sort_used_and_incl_apps(Apps, OrderedApps) -> Apps +%% Apps = [#app{}] +%% OrderedApps = [#app{}] +%% +%% OTP-4121, OTP-9984 +%% (Tickets are written for systools, but needs to be implemented here +%% as well.) +%% Make sure that used and included applications are given in the same +%% order as in the release resource file (.rel). Otherwise load and +%% start instructions in the boot script, and consequently release +%% upgrade instructions in relup, may end up in the wrong order. + +sort_used_and_incl_apps([#app{info=Info} = App|Apps], OrderedApps) -> + Incls2 = + case Info#app_info.incl_apps of + Incls when length(Incls)>1 -> + sort_appl_list(Incls, OrderedApps); + Incls -> + Incls + end, + Uses2 = + case Info#app_info.applications of + Uses when length(Uses)>1 -> + sort_appl_list(Uses, OrderedApps); + Uses -> + Uses + end, + App2 = App#app{info=Info#app_info{incl_apps=Incls2, applications=Uses2}}, + [App2|sort_used_and_incl_apps(Apps, OrderedApps)]; +sort_used_and_incl_apps([], _OrderedApps) -> + []. + +sort_appl_list(List, Order) -> + IndexedList = find_pos(List, Order), + SortedIndexedList = lists:keysort(1, IndexedList), + lists:map(fun({_Index,Name}) -> Name end, SortedIndexedList). + +find_pos([Name|Incs], OrderedApps) -> + [find_pos(1, Name, OrderedApps)|find_pos(Incs, OrderedApps)]; +find_pos([], _OrderedApps) -> + []. + +find_pos(N, Name, [#app{name=Name}|_OrderedApps]) -> + {N, Name}; +find_pos(N, Name, [_OtherAppl|OrderedApps]) -> + find_pos(N+1, Name, OrderedApps). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function: sort_apps(Apps) -> {ok, Apps'} | throw({error, Error}) %% Types: Apps = {{Name, Vsn}, #application}] %% Purpose: Sort applications according to dependencies among |