diff options
-rw-r--r-- | lib/reltool/src/reltool.hrl | 2 | ||||
-rw-r--r-- | lib/reltool/src/reltool_server.erl | 30 | ||||
-rw-r--r-- | lib/reltool/src/reltool_target.erl | 72 | ||||
-rw-r--r-- | lib/reltool/src/reltool_utils.erl | 8 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE.erl | 95 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE_data/sort_apps/z-1.0/ebin/z.app | 4 |
6 files changed, 121 insertions, 90 deletions
diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl index fc0078715a..4e5c5b2849 100644 --- a/lib/reltool/src/reltool.hrl +++ b/lib/reltool/src/reltool.hrl @@ -206,7 +206,7 @@ { name :: app_name(), app_type :: app_type() | undefined, - incl_apps = [] :: [incl_app()] + incl_apps :: [incl_app()] | undefined }). -record(rel, diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl index 29df619955..c99180a613 100644 --- a/lib/reltool/src/reltool_server.erl +++ b/lib/reltool/src/reltool_server.erl @@ -560,10 +560,30 @@ apps_in_rels(Rels, Apps) -> apps_in_rel(#rel{name = RelName, rel_apps = RelApps}, Apps) -> Mandatory = [{RelName, kernel}, {RelName, stdlib}], - Other = [{RelName, AppName} || - RA <- RelApps, - AppName <- [RA#rel_app.name | RA#rel_app.incl_apps], - not lists:keymember(AppName, 2, Mandatory)], + Other = + [{RelName, AppName} || + RA <- RelApps, + AppName <- [RA#rel_app.name | + %% Included applications in rel shall overwrite included + %% applications in .app. I.e. included applications in + %% .app shall only be used if it is not defined in rel. + case RA#rel_app.incl_apps of + undefined -> + case lists:keyfind(RA#rel_app.name, + #app.name, + Apps) of + #app{info = #app_info{incl_apps = IA}} -> + IA; + false -> + reltool_utils:throw_error( + "Release ~p uses non existing " + "application ~p", + [RelName,RA#rel_app.name]) + end; + IA -> + IA + end], + not lists:keymember(AppName, 2, Mandatory)], more_apps_in_rels(Mandatory ++ Other, Apps, []). more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc) -> @@ -1505,7 +1525,7 @@ decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals]) -> {VT andalso VI, #rel_app{name = Name, app_type = Type, incl_apps = InclApps}}; _ -> - {false, #rel_app{incl_apps = []}} + {false, #rel_app{}} end, case ValidTypesAssigned of true -> diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index 40d1009733..3d83a77d99 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -208,10 +208,10 @@ do_gen_config(#rel_app{name = Name, incl_apps = InclApps}, _InclDefs) -> case {Type, InclApps} of - {undefined, []} -> Name; - {undefined, _} -> {Name, InclApps}; - {_, []} -> {Name, Type}; - {_, _} -> {Name, Type, InclApps} + {undefined, undefined} -> Name; + {undefined, _} -> {Name, InclApps}; + {_, undefined} -> {Name, Type}; + {_, _} -> {Name, Type, InclApps} end; do_gen_config({Tag, Val}, InclDefs) -> emit(Tag, Val, undefined, InclDefs); @@ -279,7 +279,7 @@ gen_rel(Rel, Sys) -> {error, Text} end. -do_gen_rel(#rel{name = RelName, vsn = RelVsn}, +do_gen_rel(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps}, #sys{apps = Apps}, MergedApps) -> ErtsName = erts, @@ -288,7 +288,7 @@ do_gen_rel(#rel{name = RelName, vsn = RelVsn}, {release, {RelName, RelVsn}, {ErtsName, Erts#app.vsn}, - [strip_rel_info(App) || App <- MergedApps]}; + [strip_rel_info(App, RelApps) || App <- MergedApps]}; false -> reltool_utils:throw_error("Mandatory application ~p is " "not included", @@ -298,13 +298,17 @@ do_gen_rel(#rel{name = RelName, vsn = RelVsn}, strip_rel_info(#app{name = Name, vsn = Vsn, app_type = Type, - info = #app_info{incl_apps = InclApps}}) - when Type =/= undefined -> - case {Type, InclApps} of - {permanent, []} -> {Name, Vsn}; - {permanent, _} -> {Name, Vsn, InclApps}; - {_, []} -> {Name, Vsn, Type}; - {_, _} -> {Name, Vsn, Type, InclApps} + info = #app_info{incl_apps = AppInclApps}}, + RelApps) when Type =/= undefined -> + RelInclApps = case lists:keyfind(Name,#rel_app.name,RelApps) of + #rel_app{incl_apps = RIA} when RIA =/= undefined -> RIA; + _ -> undefined + end, + case {Type, RelInclApps} of + {permanent, undefined} -> {Name, Vsn}; + {permanent, _} -> {Name, Vsn, AppInclApps}; + {_, undefined} -> {Name, Vsn, Type}; + {_, _} -> {Name, Vsn, Type, AppInclApps} end. merge_apps(#rel{name = RelName, @@ -323,7 +327,7 @@ 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(MergedApps3). + sort_apps(lists:reverse(MergedApps3)). do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, Acc) -> case is_already_merged(Name, RelApps, Acc) of @@ -341,25 +345,18 @@ do_merge_apps(RelName, [Name | RelApps], Apps, RelAppType, Acc) -> true -> do_merge_apps(RelName, RelApps, Apps, RelAppType, Acc); false -> - RelApp = init_rel_app(Name, Apps), + RelApp = #rel_app{name = Name}, do_merge_apps(RelName, [RelApp | RelApps], Apps, RelAppType, Acc) end; do_merge_apps(_RelName, [], _Apps, _RelAppType, Acc) -> - lists:reverse(Acc). - -init_rel_app(Name, Apps) -> - {value, App} = lists:keysearch(Name, #app.name, Apps), - Info = App#app.info, - #rel_app{name = Name, - app_type = undefined, - incl_apps = Info#app_info.incl_apps}. + Acc. merge_app(RelName, - #rel_app{name = Name, - app_type = Type, - incl_apps = InclApps}, - RelAppType, - App) -> + #rel_app{name = Name, + app_type = Type, + incl_apps = InclApps0}, + RelAppType, + App) -> Type2 = case {Type, App#app.app_type} of {undefined, undefined} -> RelAppType; @@ -367,6 +364,11 @@ merge_app(RelName, {_, _} -> Type end, Info = App#app.info, + InclApps = + case InclApps0 of + undefined -> Info#app_info.incl_apps; + _ -> InclApps0 + end, case InclApps -- Info#app_info.incl_apps of [] -> App#app{app_type = Type2, info = Info#app_info{incl_apps = InclApps}}; @@ -421,7 +423,10 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn}, Mandatory = mandatory_modules(), Early = Mandatory ++ Preloaded, {value, KernelApp} = lists:keysearch(kernel, #app.name, MergedApps), - InclApps = [I || #app{info = #app_info{incl_apps = I}} <- MergedApps], + InclApps = lists:flatmap(fun(#app{info = #app_info{incl_apps = I}}) -> + I + end, + MergedApps), %% Create the script DeepList = @@ -471,7 +476,7 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> Path = cr_path(App, PathFlag, Variables), PartNames = lists:sort([{packages:split(M),M} || - #mod{name = M} <- Mods, + #mod{name = M, is_included=true} <- Mods, not lists:member(M, Mand)]), SplitMods = lists:foldl( @@ -513,7 +518,12 @@ sort_apps([#app{name = Name, info = Info} = App | Apps], Circular, Visited) -> {Uses, Apps1, NotFnd1} = - find_all(Name, Info#app_info.applications, Apps, Visited, [], []), + find_all(Name, + lists:reverse(Info#app_info.applications), + Apps, + Visited, + [], + []), {Incs, Apps2, NotFnd2} = find_all(Name, lists:reverse(Info#app_info.incl_apps), diff --git a/lib/reltool/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl index 9cf9bd1418..3e50324011 100644 --- a/lib/reltool/src/reltool_utils.erl +++ b/lib/reltool/src/reltool_utils.erl @@ -126,18 +126,14 @@ prim_parse(Tokens, Acc) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% default_rels() -> - %%Kernel = #rel_app{name = kernel, incl_apps = []}, - %%Stdlib = #rel_app{name = stdlib, incl_apps = []}, - Sasl = #rel_app{name = sasl, incl_apps = []}, + %% kernel and stdlib are added automatically in every release [ #rel{name = ?DEFAULT_REL_NAME, vsn = "1.0", rel_apps = []}, - %%rel_apps = [Kernel, Stdlib]}, #rel{name = "start_sasl", vsn = "1.0", - rel_apps = [Sasl]} - %%rel_apps = [Kernel, Sasl, Stdlib]} + rel_apps = [#rel_app{name = sasl}]} ]. choose_default(Tag, Profile, InclDefs) diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index 57b04251d4..122880fca9 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -283,7 +283,7 @@ create_release(_Config) -> %% started before the including application. %% Circular dependencies shall also be detected and cause error. -create_release_sort(_Config) -> {skip, "Multiple known problems - see OTP-9792"}; +create_release_sort(_Config) -> {skip, "Two bugs related to sorting"}; create_release_sort(Config) -> DataDir = ?config(data_dir,Config), %% Configure the server @@ -296,7 +296,11 @@ create_release_sort(Config) -> RelName7 = "Circular", RelName8 = "Include-both-missing-app", RelName9 = "Include-overwrite", + RelName10= "Uses-order-as-rel", RelVsn = "1.0", + %% Application z (.app file): + %% includes [tools, mnesia] + %% uses [kernel, stdlib, sasl, inets] Sys = {sys, [ @@ -304,19 +308,21 @@ create_release_sort(Config) -> {boot_rel, RelName1}, {rel, RelName1, RelVsn, [stdlib, kernel, mnesia, sasl]}, {rel, RelName2, RelVsn, [stdlib, kernel, sasl, mnesia]}, - {rel, RelName3, RelVsn, [stdlib, kernel, {z,[tools]}, tools]}, - {rel, RelName4, RelVsn, [stdlib, kernel, z, tools]}, + {rel, RelName3, RelVsn, [stdlib, kernel, {z,[tools]}, tools, mnesia]}, + {rel, RelName4, RelVsn, [stdlib, kernel, z, mnesia, tools]}, {rel, RelName5, RelVsn, [stdlib, kernel, {sasl,[tools]}]}, - {rel, RelName6, RelVsn, [stdlib, kernel, z]}, %z includes tools in .app + {rel, RelName6, RelVsn, [stdlib, kernel, z]}, {rel, RelName7, RelVsn, [stdlib, kernel, mnesia, y, sasl, x]}, {rel, RelName8, RelVsn, [stdlib, kernel, {z,[tools]}]}, {rel, RelName9, RelVsn, [stdlib, kernel, {z,[]}]}, + {rel, RelName10, RelVsn, [stdlib, kernel, {z,[]}, inets, sasl]}, {incl_cond,exclude}, {mod_cond,app}, {app,kernel,[{incl_cond,include}]}, {app,stdlib,[{incl_cond,include}]}, {app,mnesia,[{incl_cond,include}]}, {app,sasl,[{incl_cond,include}]}, + {app,inets,[{incl_cond,include}]}, {app,x,[{incl_cond,include}]}, {app,y,[{incl_cond,include}]}, {app,z,[{incl_cond,include}]}, @@ -324,7 +330,6 @@ create_release_sort(Config) -> ]}, %% Generate release - %% BUG: reltool reverses the list of applications after kernel and stdlib ?msym({ok, {release, {RelName1, RelVsn}, {erts, _}, [{kernel, _}, @@ -333,7 +338,6 @@ create_release_sort(Config) -> {sasl, _}]}}, reltool:get_rel([{config, Sys}], RelName1)), - %% BUG: reltool reverses the list of applications after kernel and stdlib ?msym({ok, {release, {RelName2, RelVsn}, {erts, _}, [{kernel, _}, @@ -346,19 +350,21 @@ create_release_sort(Config) -> {erts, _}, [{kernel, _}, {stdlib, _}, + {sasl, _}, + {inets, _}, {tools, _}, - {z, _, [tools]}]}}, + {z, _, [tools]}, + {mnesia, _}]}}, reltool:get_rel([{config, Sys}], RelName3)), - %% BUG: reltool does not honor included applications in .app files - %% unless they are also mentioned in the 'rel' specification in - %% the reltool config. - %% => order of tools and z does not become correct in rel (tools - %% should be first since it is included in z) + %%! BUG: same as OTP-4121, but for reltool???? Or revert tools and mnesia ?msym({ok, {release, {RelName4, RelVsn}, {erts, _}, [{kernel, _}, {stdlib, _}, + {sasl, _}, + {inets, _}, + {mnesia, _}, {tools, _}, {z, _}]}}, reltool:get_rel([{config, Sys}], RelName4)), @@ -368,11 +374,7 @@ create_release_sort(Config) -> "in the app file: [tools]"}, reltool:get_rel([{config, Sys}], RelName5)), - %% BUG: reltool does not honor included applications in .app files - %% unless they are also mentioned in the 'rel' specification in - %% the reltool config. - %% => does not detect that tools (included in z) is missing - ?m({error, "Undefined applications: [tools]"}, + ?m({error, "Undefined applications: [tools,mnesia]"}, reltool:get_rel([{config, Sys}], RelName6)), ?m({error,"Circular dependencies: [x,y]"}, @@ -381,15 +383,25 @@ create_release_sort(Config) -> ?m({error,"Undefined applications: [tools]"}, reltool:get_rel([{config, Sys}], RelName8)), - %% BUG: Reltool looses the empty include list for z, which should - %% overwrite included_applications statement from the .app file. ?msym({ok,{release,{RelName9,RelVsn}, {erts,_}, [{kernel,_}, {stdlib,_}, + {sasl, _}, + {inets, _}, {z,_,[]}]}}, reltool:get_rel([{config, Sys}], RelName9)), + %%! BUG: same as OTP-9984, but for reltool???? Or revert inets and sasl? + ?msym({ok,{release,{RelName10,RelVsn}, + {erts,_}, + [{kernel,_}, + {stdlib,_}, + {inets, _}, + {sasl, _}, + {z,_,[]}]}}, + reltool:get_rel([{config, Sys}], RelName10)), + ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -442,7 +454,7 @@ create_script(_Config) -> %% Test creation of .script with different sorting of applications and %% included applications. %% Test that result is equal to what systools produces -create_script_sort(_Config) -> {skip, "Multiple known problems - see OTP-9792"}; +create_script_sort(_Config) -> {skip, "OTP-9984 - stdlib sort problem"}; create_script_sort(Config) -> DataDir = ?config(data_dir,Config), %% Configure the server @@ -464,10 +476,10 @@ create_script_sort(Config) -> {boot_rel, RelName1}, {rel, RelName1, RelVsn, [stdlib, kernel, mnesia, sasl]}, {rel, RelName2, RelVsn, [stdlib, kernel, sasl, mnesia]}, - {rel, RelName3, RelVsn, [stdlib, kernel, {z,[tools]}, tools]}, - {rel, RelName4, RelVsn, [stdlib, kernel, z, tools]}, + {rel, RelName3, RelVsn, [stdlib, kernel, {z,[tools]}, tools, mnesia]}, + {rel, RelName4, RelVsn, [stdlib, kernel, z, mnesia, tools]}, {rel, RelName5, RelVsn, [stdlib, kernel, {sasl,[tools]}]}, - {rel, RelName6, RelVsn, [stdlib, kernel, z]}, %z includes tools in .app + {rel, RelName6, RelVsn, [stdlib, kernel, z]}, {rel, RelName7, RelVsn, [stdlib, kernel, mnesia, y, sasl, x]}, {rel, RelName8, RelVsn, [stdlib, kernel, {z,[tools]}]}, {rel, RelName9, RelVsn, [stdlib, kernel, {z,[]}]}, @@ -477,6 +489,7 @@ create_script_sort(Config) -> {app,stdlib,[{incl_cond,include}]}, {app,mnesia,[{incl_cond,include}]}, {app,sasl,[{incl_cond,include}]}, + {app,inets,[{incl_cond,include}]}, {app,x,[{incl_cond,include}]}, {app,y,[{incl_cond,include}]}, {app,z,[{incl_cond,include}]}, @@ -487,11 +500,13 @@ create_script_sort(Config) -> %% Generate release files application:load(sasl), + application:load(inets), application:load(mnesia), application:load(tools), {ok,KernelVsn} = application:get_key(kernel,vsn), {ok,StdlibVsn} = application:get_key(stdlib,vsn), {ok,SaslVsn} = application:get_key(sasl,vsn), + {ok,InetsVsn} = application:get_key(inets,vsn), {ok,MnesiaVsn} = application:get_key(mnesia,vsn), {ok,ToolsVsn} = application:get_key(tools,vsn), ErtsVsn = erlang:system_info(version), @@ -514,14 +529,20 @@ create_script_sort(Config) -> [{kernel,KernelVsn}, {stdlib,StdlibVsn}, {z,"1.0",[tools]}, - {tools,ToolsVsn}]}, + {tools,ToolsVsn}, + {mnesia,MnesiaVsn}, + {sasl,SaslVsn}, + {inets,InetsVsn}]}, FullName3 = filename:join(?WORK_DIR,RelName3), ?m(ok, file:write_file(FullName3 ++ ".rel", io_lib:format("~p.\n", [Rel3]))), Rel4 = {release, {RelName4,RelVsn}, {erts,ErtsVsn}, [{kernel,KernelVsn}, {stdlib,StdlibVsn}, {z,"1.0"}, - {tools,ToolsVsn}]}, + {tools,ToolsVsn}, + {mnesia,MnesiaVsn}, + {sasl,SaslVsn}, + {inets,InetsVsn}]}, FullName4 = filename:join(?WORK_DIR,RelName4), ?m(ok, file:write_file(FullName4 ++ ".rel", io_lib:format("~p.\n", [Rel4]))), Rel5 = {release, {RelName5,RelVsn}, {erts,ErtsVsn}, @@ -555,42 +576,30 @@ create_script_sort(Config) -> Rel9 = {release, {RelName9,RelVsn}, {erts,ErtsVsn}, [{kernel,KernelVsn}, {stdlib,StdlibVsn}, - {z,"1.0",[]}]}, + {z,"1.0",[]}, + {sasl,SaslVsn}, + {inets,InetsVsn}]}, FullName9 = filename:join(?WORK_DIR,RelName9), ?m(ok, file:write_file(FullName9 ++ ".rel", io_lib:format("~p.\n", [Rel9]))), %% Generate script files with systools and reltool and compare ZPath = filename:join([LibDir,"*",ebin]), - %% BUG: reltool reverses the list of applications after kernel and stdlib - %% => mnesia and sasl are reverted ?msym({ok,_,_}, systools_make_script(FullName1,ZPath)), {ok, [SystoolsScript1]} = ?msym({ok,[_]}, file:consult(FullName1++".script")), {ok, Script1} = ?msym({ok, _}, reltool:get_script(Pid, RelName1)), ?m(equal, diff_script(SystoolsScript1, Script1)), - %% BUG: reltool reverses the list of applications after kernel and stdlib - %% => mnesia and sasl are reverted ?msym({ok,_,_}, systools_make_script(FullName2,ZPath)), {ok, [SystoolsScript2]} = ?msym({ok,[_]}, file:consult(FullName2++".script")), {ok, Script2} = ?msym({ok, _}, reltool:get_script(Pid, RelName2)), ?m(equal, diff_script(SystoolsScript2, Script2)), - %% BUG1: reltool loads all modules in the ebin dir of an application, - %% even if mod_cond is set to 'app'. - %% BUG2: reltool shall not start included applications!! ?msym({ok,_,_}, systools_make_script(FullName3,ZPath)), {ok, [SystoolsScript3]} = ?msym({ok,[_]}, file:consult(FullName3++".script")), {ok, Script3} = ?msym({ok, _}, reltool:get_script(Pid, RelName3)), ?m(equal, diff_script(SystoolsScript3, Script3)), - %% BUG1: reltool loads all modules in the ebin dir of an application, - %% even if mod_cond is set to 'app'. - %% BUG2: reltool does not honor included applications in .app files - %% unless they are also mentioned in the 'rel' specification in - %% the reltool config. - %% => faulty order of load instructions for tools and z. tools - %% should be first since it is included in z. ?msym({ok,_,_}, systools_make_script(FullName4,ZPath)), {ok, [SystoolsScript4]} = ?msym({ok,[_]}, file:consult(FullName4++".script")), {ok, Script4} = ?msym({ok, _}, reltool:get_script(Pid, RelName4)), @@ -603,13 +612,9 @@ create_script_sort(Config) -> "in the app file: [tools]"}, reltool:get_script(Pid, RelName5)), - %% BUG: reltool does not honor included applications in .app files - %% unless they are also mentioned in the 'rel' specification in - %% the reltool config. - %% => does not detect that tools (included in z) is missing ?msym({error,_,{undefined_applications,_}}, systools_make_script(FullName6,ZPath)), - ?m({error, "Undefined applications: [tools]"}, + ?m({error, "Undefined applications: [tools,mnesia]"}, reltool:get_script(Pid, RelName6)), ?msym({error,_,{circular_dependencies,_}}, diff --git a/lib/reltool/test/reltool_server_SUITE_data/sort_apps/z-1.0/ebin/z.app b/lib/reltool/test/reltool_server_SUITE_data/sort_apps/z-1.0/ebin/z.app index 1622975bf6..8608bc554b 100644 --- a/lib/reltool/test/reltool_server_SUITE_data/sort_apps/z-1.0/ebin/z.app +++ b/lib/reltool/test/reltool_server_SUITE_data/sort_apps/z-1.0/ebin/z.app @@ -4,5 +4,5 @@ {vsn, "1.0"}, {modules,[]}, {registered, []}, - {applications, [kernel, stdlib]}, - {included_applications, [tools]}]}. + {applications, [kernel, stdlib, sasl, inets]}, + {included_applications, [tools, mnesia]}]}. |