diff options
Diffstat (limited to 'lib/reltool')
22 files changed, 697 insertions, 128 deletions
diff --git a/lib/reltool/doc/src/Makefile b/lib/reltool/doc/src/Makefile index 8bc1488f77..2373b5e507 100644 --- a/lib/reltool/doc/src/Makefile +++ b/lib/reltool/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009-2010. All Rights Reserved. +# Copyright Ericsson AB 2009-2012. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -97,13 +97,13 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(HTMLDIR)/* "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index 0aae128c2b..66ec7e9035 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2009</year> - <year>2011</year> + <year>2012</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -37,7 +37,28 @@ thus constitutes one section in this document. The title of each section is the version number of Reltool.</p> - <section><title>Reltool 0.6</title> + <section><title>Reltool 0.6.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new sys level configuration parameter + <c>{excl_lib,otp_root}</c> is added. When this is set, + the target system will not contain anything from + <c>$OTP_ROOT</c>. It will only contain a releases + directory with rel, script and boot files, and a lib + directory with applications found outside of + <c>$OTP_ROOT</c> (i.e. "your own" applications).</p> + <p> + Own Id: OTP-9743</p> + </item> + </list> + </section> + +</section> + +<section><title>Reltool 0.6</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml index 9a4e2d130e..fbe29753be 100644 --- a/lib/reltool/doc/src/reltool.xml +++ b/lib/reltool/doc/src/reltool.xml @@ -51,8 +51,18 @@ defines library directories where additional applications may reside and it defaults to the directories listed by the operating system environment variable - <c>ERL_LIBS</c>. See the module <c>code</c> for more info. - Finally single modules and entire applications may be read from + <c>ERL_LIBS</c>. See the module <c>code</c> for more info.</p> + + <p>An application directory <c>AppDir</c> under a library + directory is recognized by the existence of an <c>AppDir/ebin</c> + directory. If this does not exist, <c>reltool</c> will not + consider <c>AppDir</c> at all when looking for applications.</p> + + <p>It is recommended that application directories are named as the + application, possibly followed by a dash and the version + number. For example <c>myapp</c> or <c>myapp-1.1</c>.</p> + + <p>Finally single modules and entire applications may be read from Escripts.</p> <p>Some configuration parameters control the behavior of Reltool @@ -144,7 +154,7 @@ value <c>include</c> implies that all applications and escripts that do not have any explicit <c>incl_cond</c> setting will be included. <c>exclude</c> implies that all - applications and escripts) that do not have any explicit + applications and escripts that do not have any explicit <c>incl_cond</c> setting will be excluded.</p> </item> @@ -221,6 +231,52 @@ system.</p> </item> + <tag><c>excl_lib</c></tag> + <item> + <warning><p>This option is experimental.</p></warning> + <p>If the <c>excl_lib</c> option is set to <c>otp_root</c> + then reltool will not copy anything from the Erlang/OTP + installation ($OTP_ROOT) into the target structure. The goal + is to create a "slim" release which can be used together with + an existing Erlang/OTP installation. The target structure will + therefore only contain a <c>lib</c> directory with the + applications that were found outside of $OTP_ROOT (typically + your own applications), and a <c>releases</c> directory with + the generated <c>.rel,</c> <c>.script</c> and <c>.boot</c> + files.</p> + + <p>When starting this release, three things must be specified:</p> + <taglist> + <tag><b>Which <c>releases</c> directory to use</b></tag> + <item>Tell the release handler to use the <c>releases</c> + directory in our target structure instead of + <c>$OTP_ROOT/releases</c>. This is done by setting the SASL + environment variable <c>releases_dir</c>, either from the + command line (<c>-sasl releases_dir + <target-dir>/releases</c>) or in + <c>sys.config</c>.</item> + + <tag><b>Which boot file to use</b></tag> + <item>The default boot file is <c>$OTP_ROOT/bin/start</c>, + but in this case we need to specify a boot file from our + target structure, typically + <c><target-dir>/releases/<vsn>/<RelName></c>. This + is done with the <c>-boot</c> command line option to + <c>erl</c></item> + + <tag><b>The location of our applications</b></tag> + <item>The generated .script (and .boot) file uses the + environment variable <c>$RELTOOL_EXT_LIB</c> as prefix for + the paths to all applications. The <c>-boot_var</c> option + to <c>erl</c> can be used for specifying the value of this + variable, typically <c>-boot_var RELTOOL_EXT_LIB + <target-dir>/lib</c>.</item> + </taglist> + + <p>Example:</p> + <p><code>erl -sasl releases_dir \"mytarget/releases\" -boot mytarget/releases/1.0/myrel -boot_var RELTOOL_EXT_LIB mytarget/lib</code></p> + </item> + <tag><c>incl_sys_filters</c></tag> <item> <p>This parameter normally contains a list of regular @@ -326,6 +382,11 @@ <p>This parameter is mutual exclusive with <c>lib_dir</c>. If <c>vsn</c> and <c>lib_dir</c> are both omitted, the latest version will be chosen.</p> + <p>Note that in order for reltool to sort application versions + and thereby be able to select the latest, it is required that + the version id for the application consits of integers and + dots only, for example <c>1</c>, <c>2.0</c> or + <c>3.17.1</c>.</p> </item> <tag><c>lib_dir</c></tag> <item> @@ -337,6 +398,11 @@ <p>This parameter is mutual exclusive with <c>vsn</c>. If <c>vsn</c> and <c>lib_dir</c> are both omitted, the latest version will be chosen.</p> + <p>Note that in order for reltool to sort application versions + and thereby be able to select the latest, it is required that + the version id for the application consits of integers and + dots only, for example <c>1</c>, <c>2.0</c> or + <c>3.17.1</c>.</p> </item> <tag><c>mod</c></tag> <item> @@ -400,7 +466,7 @@ <tag><c>incl_cond</c></tag> <item> <p>This parameter controls whether the module is included or not. By - default the <c>mod_incl</c> parameter on application and system level + default the <c>mod_cond</c> parameter on application and system level will be used to control whether the module is included or not. The value of <c>incl_cond</c> overrides the module inclusion policy. <c>include</c> implies that the module is included, while @@ -452,6 +518,7 @@ app() = {vsn, app_vsn()} | {incl_cond, incl_cond()} | {debug_info, debug_info()} | {app_file, app_file()} + | {excl_lib, excl_lib()} | {incl_sys_filters, incl_sys_filters()} | {excl_sys_filters, excl_sys_filters()} | {incl_app_filters, incl_app_filters()} @@ -477,6 +544,7 @@ escript() = {incl_cond, incl_cond()} escript_file() = file() excl_app_filters() = regexps() excl_archive_filters() = regexps() +excl_lib() = otp_root excl_sys_filters() = regexps() file() = string() incl_app() = app_name() diff --git a/lib/reltool/doc/src/reltool_usage.xml b/lib/reltool/doc/src/reltool_usage.xml index d128e80a77..0041e60d8f 100644 --- a/lib/reltool/doc/src/reltool_usage.xml +++ b/lib/reltool/doc/src/reltool_usage.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2009</year> - <year>2011</year> + <year>2012</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -257,6 +257,11 @@ policy</c> part of the page. By default the latest version of the application is selected, but it is possible to override this by explicitly selecting another version.</p> + + <p>Note that in order for reltool to sort application versions and + thereby be able to select the latest, it is required that the + version id for the application consits of integers and dots only, + for example <c>1</c>, <c>2.0</c> or <c>3.17.1</c>.</p> <p>By default the <c>Application inclusion policy</c> on system level is used for all applications. Set the value to @@ -335,7 +340,7 @@ <p>There are two categories of modules on the <c>Module dependencies</c> page. If the module is used by other modules, - these are listed under <c>Modules used by others</c>. If the + these are listed under <c>Modules using this</c>. If the module uses other modules, these are listed under <c>Used modules</c>.</p> @@ -365,7 +370,7 @@ <p>There are two categories of modules on the <c>Dependencies</c> page. If the module is used by other modules, these are listed - under <c>Modules used by others</c>. If the module uses other + under <c>Modules using this</c>. If the module uses other modules, these are listed under <c>Used modules</c>.</p> <p>Double click on an module name to launch a module window.</p> diff --git a/lib/reltool/examples/Makefile b/lib/reltool/examples/Makefile index dacfd4e7d4..0b495b14b7 100644 --- a/lib/reltool/examples/Makefile +++ b/lib/reltool/examples/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009. All Rights Reserved. +# Copyright Ericsson AB 2009-2012. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -72,8 +72,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile index 4e6a112b7e..a7e34053f1 100644 --- a/lib/reltool/src/Makefile +++ b/lib/reltool/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009-2010. All Rights Reserved. +# Copyright Ericsson AB 2009-2012. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -97,11 +97,11 @@ $(TARGET_FILES): $(HRL_FILES) $(INTERNAL_HRL_FILES) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl index 26dcd82447..f0d8b38519 100644 --- a/lib/reltool/src/reltool.hrl +++ b/lib/reltool/src/reltool.hrl @@ -79,6 +79,7 @@ | {debug_info, debug_info()} | {app_file, app_file()} | {profile, profile()} + | {excl_lib, excl_lib()} | {incl_sys_filters, incl_sys_filters()} | {excl_sys_filters, excl_sys_filters()} | {incl_app_filters, incl_app_filters()} @@ -123,6 +124,7 @@ -type incl_defaults() :: boolean(). -type incl_derived() :: boolean(). -type status() :: missing | ok. +-type excl_lib() :: otp_root. -record(common, { @@ -233,6 +235,7 @@ rels :: [#rel{}], emu_name :: emu_name(), profile :: profile(), + excl_lib :: excl_lib(), incl_sys_filters :: [#regexp{}], excl_sys_filters :: [#regexp{}], incl_app_filters :: [#regexp{}], diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl index 034a42e1e2..c56e29152d 100644 --- a/lib/reltool/src/reltool_server.erl +++ b/lib/reltool/src/reltool_server.erl @@ -674,6 +674,8 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> true; exclude -> false; + derived -> + undefined; undefined -> %% print(M#mod.name, hipe, "mod_cond -> ~p\n", %% [ModCond]), @@ -693,6 +695,8 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> true; exclude -> false; + derived -> + undefined; undefined -> Default end @@ -783,9 +787,10 @@ mod_mark_is_included(#state{app_tab=AppTab, mod_tab=ModTab, sys=Sys} = S, M#mod{is_pre_included = true, is_included = true}; exclude -> - M#mod{is_pre_included = true, - is_included = true}; - undefined -> + M#mod{is_pre_included = false, + is_included = false}; + ModInclCond when ModInclCond==undefined; + ModInclCond==derived -> M#mod{is_included = true} end, ets:insert(ModTab, M2), @@ -979,7 +984,7 @@ refresh_app(#app{name = AppName, %% Add info from .app file Base = get_base(AppName, ActiveDir), - {_, DefaultVsn} = reltool_utils:split_app_name(Base), + DefaultVsn = get_vsn_from_dir(AppName,Base), Ebin = filename:join([ActiveDir, "ebin"]), AppFile = filename:join([Ebin, @@ -1408,6 +1413,8 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals]) -> ExclApp, Sys#sys.excl_app_filters), embedded_app_type = AppType}; + excl_lib when Val =:= otp_root -> + Sys#sys{excl_lib=Val}; incl_sys_filters -> Sys#sys{incl_sys_filters = dec_re(Key, Val, Sys#sys.incl_sys_filters)}; @@ -1678,8 +1685,7 @@ app_dirs2([Lib | Libs], Acc) -> EbinDir = filename:join([AppDir, "ebin"]), case filelib:is_dir(EbinDir, erl_prim_loader) of true -> - {Name, _Vsn} = - reltool_utils:split_app_name(Base), + Name = find_app_name(Base,EbinDir), case Name of erts -> false; _ -> {true, {Name, AppDir}} @@ -1697,17 +1703,74 @@ app_dirs2([Lib | Libs], Acc) -> app_dirs2([], Acc) -> lists:sort(lists:append(Acc)). +find_app_name(Base,EbinDir) -> + {ok,EbinFiles} = erl_prim_loader:list_dir(EbinDir), + AppFile = + case [F || F <- EbinFiles, filename:extension(F)=:=".app"] of + [AF] -> + AF; + _ -> + undefined + end, + find_app_name1(Base,AppFile). + +find_app_name1(Base,undefined) -> + {Name,_} = reltool_utils:split_app_name(Base), + Name; +find_app_name1(_Base,AppFile) -> + list_to_atom(filename:rootname(AppFile)). + +get_vsn_from_dir(AppName,Base) -> + Prefix = atom_to_list(AppName) ++ "-", + case lists:prefix(Prefix,Base) of + true -> + lists:nthtail(length(Prefix),Base); + false -> + "" + end. + + escripts_to_apps([Escript | Escripts], Apps, Status) -> {EscriptAppName, _Label} = split_escript_name(Escript), Ext = code:objfile_extension(), + + %% First find all .app files and associate the app name to the app + %% label - this is in order to now which application a module + %% belongs to in the next round. + AppFun = fun(FullName, _GetInfo, _GetBin, AppFiles) -> + Components = filename:split(FullName), + case Components of + [AppLabel, "ebin", File] -> + case filename:extension(File) of + ".app" -> + [{AppLabel,File}|AppFiles]; + _ -> + AppFiles + end; + _ -> + AppFiles + end + end, + AppFiles = + case reltool_utils:escript_foldl(AppFun, [], Escript) of + {ok, AF} -> + AF; + {error, Reason1} -> + reltool_utils:throw_error("Illegal escript ~p: ~p", + [Escript,Reason1]) + end, + + %% Next, traverse all files... Fun = fun(FullName, _GetInfo, GetBin, {FileAcc, StatusAcc}) -> Components = filename:split(FullName), case Components of [AppLabel, "ebin", File] -> case filename:extension(File) of ".app" -> - {AppName, DefaultVsn} = - reltool_utils:split_app_name(AppLabel), + AppName = + list_to_atom(filename:rootname(File)), + DefaultVsn = + get_vsn_from_dir(AppName,AppLabel), AppFileName = filename:join([Escript, FullName]), {Info, StatusAcc2} = @@ -1720,8 +1783,9 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> {[{AppName, app, Dir, Info} | FileAcc], StatusAcc2}; E when E =:= Ext -> - {AppName, _} = - reltool_utils:split_app_name(AppLabel), + AppFile = + proplists:get_value(AppLabel,AppFiles), + AppName = find_app_name1(AppLabel,AppFile), Mod = init_mod(AppName, File, {File, GetBin()}, @@ -1758,6 +1822,7 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> {FileAcc, StatusAcc} end end, + case reltool_utils:escript_foldl(Fun, {[], Status}, Escript) of {ok, {Files, Status2}} -> EscriptApp = @@ -1772,8 +1837,9 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> Apps, Status2), escripts_to_apps(Escripts, Apps2, Status3); - {error, Reason} -> - reltool_utils:throw_error("Illegal escript ~p: ~p", [Escript,Reason]) + {error, Reason2} -> + reltool_utils:throw_error("Illegal escript ~p: ~p", + [Escript,Reason2]) end; escripts_to_apps([], Apps, Status) -> {Apps, Status}. @@ -1932,7 +1998,7 @@ ensure_app_info(#app{name = Name, fun(Dir, StatusAcc) -> Base = get_base(Name, Dir), Ebin = filename:join([Dir, "ebin"]), - {_, DefaultVsn} = reltool_utils:split_app_name(Base), + DefaultVsn = get_vsn_from_dir(Name,Base), AppFile = filename:join([Ebin, atom_to_list(Name) ++ ".app"]), read_app_info(AppFile, AppFile, Name, DefaultVsn, StatusAcc) end, diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index e3a7b02143..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 @@ -342,9 +344,11 @@ do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, false -> {value, App} = lists:keysearch(Name, #app.name, Apps), MergedApp = merge_app(RelName, RA, RelAppType, App), - MoreNames = (MergedApp#app.info)#app_info.applications, + ReqNames = (MergedApp#app.info)#app_info.applications, + IncNames = (MergedApp#app.info)#app_info.incl_apps, Acc2 = [MergedApp | Acc], - do_merge_apps(RelName, MoreNames ++ RelApps, Apps, RelAppType, Acc2) + do_merge_apps(RelName, ReqNames ++ IncNames ++ RelApps, + Apps, RelAppType, Acc2) end; do_merge_apps(RelName, [Name | RelApps], Apps, RelAppType, Acc) -> case is_already_merged(Name, RelApps, Acc) of @@ -507,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 @@ -687,6 +741,8 @@ strip_name_ebin(Dir, Name, Vsn) -> case lists:reverse(Dir) of ["ebin", Name | D] -> {ok, lists:reverse(D)}; ["ebin", FullName | D] -> {ok, lists:reverse(D)}; + [Name | D] -> {ok, lists:reverse(D)}; + [FullName | D] -> {ok, lists:reverse(D)}; _ -> false end. @@ -733,8 +789,20 @@ do_spec_rel_files(#rel{name = RelName} = Rel, Sys) -> BootFile = RelName ++ ".boot", MergedApps = merge_apps(Rel, Sys), GenRel = do_gen_rel(Rel, Sys, MergedApps), + Variables = + case Sys#sys.excl_lib of + otp_root -> + %% All applications that are fetched from somewhere + %% other than $OTP_ROOT/lib will get $RELTOOL_EXT_LIB + %% as path prefix in the .script file. + [{"RELTOOL_EXT_LIB",LibDir} || LibDir <- Sys#sys.lib_dirs] ++ + [{"RELTOOL_EXT_LIB",filename:dirname(AppLibDir)} || + #app{active_dir=AppLibDir,use_selected_vsn=dir} + <- MergedApps]; + _ -> + [] + end, PathFlag = true, - Variables = [], {ok, Script} = do_gen_script(Rel, Sys, MergedApps, PathFlag, Variables), {ok, BootBin} = gen_boot(Script), Date = date(), @@ -771,29 +839,34 @@ gen_spec(Sys) -> end. do_gen_spec(#sys{root_dir = RootDir, + excl_lib = ExclLib, incl_sys_filters = InclRegexps, excl_sys_filters = ExclRegexps, relocatable = Relocatable, apps = Apps} = Sys) -> - {create_dir, _, SysFiles} = spec_dir(RootDir), - {ExclRegexps2, SysFiles2} = - strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps), RelFiles = spec_rel_files(Sys), - {InclRegexps2, BinFiles} = - spec_bin_files(Sys, SysFiles, SysFiles2, RelFiles, InclRegexps), + {SysFiles, InclRegexps2, ExclRegexps2, Mandatory} = + case ExclLib of + otp_root -> + {[],InclRegexps,ExclRegexps,["lib"]}; + _ -> + {create_dir, _, SF} = spec_dir(RootDir), + {ER2, SF2} = strip_sys_files(Relocatable, SF, Apps, ExclRegexps), + {IR2, BinFiles} = + spec_bin_files(Sys, SF, SF2, RelFiles, InclRegexps), + SF3 = [{create_dir, "bin", BinFiles}] ++ SF2, + {SF3,IR2,ER2,["bin","erts","lib"]} + end, LibFiles = spec_lib_files(Sys), {BootVsn, StartFile} = spec_start_file(Sys), - SysFiles3 = - [ - {create_dir, "releases", + SysFiles2 = + [{create_dir, "releases", [StartFile, - {create_dir,BootVsn, RelFiles}]}, - {create_dir, "bin", BinFiles} - ] ++ SysFiles2, - SysFiles4 = filter_spec(SysFiles3, InclRegexps2, ExclRegexps2), - SysFiles5 = SysFiles4 ++ [{create_dir, "lib", LibFiles}], - check_sys(["bin", "erts", "lib"], SysFiles5), - SysFiles5. + {create_dir,BootVsn, RelFiles}]}] ++ SysFiles, + SysFiles3 = filter_spec(SysFiles2, InclRegexps2, ExclRegexps2), + SysFiles4 = SysFiles3 ++ [{create_dir, "lib", LibFiles}], + check_sys(Mandatory, SysFiles4), + SysFiles4. strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) -> ExclRegexps2 = @@ -967,22 +1040,35 @@ safe_lookup_spec(Prefix, Specs) -> %% Specify applications %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec_lib_files(#sys{apps = Apps} = Sys) -> +spec_lib_files(#sys{root_dir = RootDir, + apps = Apps, + excl_lib = ExclLib} = Sys) -> Filter = fun(#app{is_escript = IsEscript, is_included = IsIncl, - is_pre_included = IsPre, name = Name}) -> + is_pre_included = IsPre, name = Name, + active_dir = ActiveDir}) -> if Name =:= ?MISSING_APP_NAME -> false; IsEscript =/= false -> false; IsIncl; IsPre -> - true; + case ExclLib of + otp_root -> + not lists:prefix(RootDir,ActiveDir); + _ -> + true + end; true -> false end end, SelectedApps = lists:filter(Filter, Apps), - check_apps([kernel, stdlib], SelectedApps), + case ExclLib of + otp_root -> + ok; + _ -> + check_apps([kernel, stdlib], SelectedApps) + end, lists:flatten([spec_app(App, Sys) || App <- SelectedApps]). check_apps([Mandatory | Names], Apps) -> @@ -1388,12 +1474,10 @@ do_install(RelName, TargetDir) -> BinDir = filename:join([TargetDir2, "bin"]), case os:type() of {win32, _} -> - NativeRootDir = filename:nativename(TargetDir2), - %% NativeBinDir = - %% filename:nativename(filename:join([BinDir, "win32"])), - NativeBinDir = filename:nativename(BinDir), + NativeRootDir = nativename(TargetDir2), + NativeErtsBinDir = nativename(ErtsBinDir), IniData = ["[erlang]\r\n", - "Bindir=", NativeBinDir, "\r\n", + "Bindir=", NativeErtsBinDir, "\r\n", "Progname=erl\r\n", "Rootdir=", NativeRootDir, "\r\n"], IniFile = filename:join([BinDir, "erl.ini"]), @@ -1413,6 +1497,15 @@ do_install(RelName, TargetDir) -> reltool_utils:throw_error("~s: Illegal data file syntax", [DataFile]) end. +nativename(Dir) -> + escape_backslash(filename:nativename(Dir)). +escape_backslash([$\\|T]) -> + [$\\,$\\|escape_backslash(T)]; +escape_backslash([H|T]) -> + [H|escape_backslash(T)]; +escape_backslash([]) -> + []. + subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> Fun = fun(Script) -> subst_src_script(Script, SrcDir, DestDir, Vars, Opts) diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile index d8a7adb837..52cdef44da 100644 --- a/lib/reltool/test/Makefile +++ b/lib/reltool/test/Makefile @@ -49,7 +49,7 @@ RELSYSDIR = $(RELEASE_PATH)/reltool_test # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -#ERL_COMPILE_FLAGS += +ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/reltool/ebin/ EBIN = . @@ -73,12 +73,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) reltool.spec reltool.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_SCRIPT) rtt $(INSTALL_PROGS) $(RELSYSDIR) - $(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) reltool.spec reltool.cover $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_SCRIPT) rtt $(INSTALL_PROGS) "$(RELSYSDIR)" + $(INSTALL_DATA) $(INSTALL_PROGS) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index 8a98dc36cf..8d71865508 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -67,6 +67,7 @@ all() -> create_standalone_app_clash, create_multiple_standalone, create_old_target, + create_slim, eval_target_spec, otp_9135, otp_9229_dupl_mod_exclude_app, @@ -89,8 +90,10 @@ all() -> gen_rel_files, save_config, dependencies, + mod_incl_cond_derived, use_selected_vsn, - use_selected_vsn_relative_path]. + use_selected_vsn_relative_path, + non_standard_vsn_id]. groups() -> []. @@ -105,6 +108,15 @@ end_per_group(_GroupName, Config) -> %% The test cases %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% A dummy break test case which is NOT in all(), but can be run +%% directly from the command line with ct_run. It just does a +%% test_server:break()... +break(_Config) -> + test_server:break(""), + ok. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Start a server process and check that it does not crash start_server(_Config) -> @@ -297,7 +309,6 @@ create_release(_Config) -> %% started before the including application. %% Circular dependencies shall also be detected and cause error. -create_release_sort(_Config) -> {skip, "Two bugs related to sorting"}; create_release_sort(Config) -> DataDir = ?config(data_dir,Config), %% Configure the server @@ -306,11 +317,12 @@ create_release_sort(Config) -> RelName3 = "Include-both", RelName4 = "Include-only-app", RelName5 = "Include-only-rel", - RelName6 = "Include-missing-app", + RelName6 = "Auto-add-missing-apps", RelName7 = "Circular", - RelName8 = "Include-both-missing-app", - RelName9 = "Include-overwrite", + RelName8 = "Include-rel-alter-order", + RelName9 = "Include-none-overwrite", RelName10= "Uses-order-as-rel", + RelName11= "Auto-add-dont-overwrite-load", RelVsn = "1.0", %% Application z (.app file): %% includes [tools, mnesia] @@ -325,11 +337,12 @@ create_release_sort(Config) -> {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]}, + {rel, RelName6, RelVsn, [z]}, {rel, RelName7, RelVsn, [stdlib, kernel, mnesia, y, sasl, x]}, - {rel, RelName8, RelVsn, [stdlib, kernel, {z,[tools]}]}, + {rel, RelName8, RelVsn, [stdlib, kernel, {z,[mnesia,tools]}]}, {rel, RelName9, RelVsn, [stdlib, kernel, {z,[]}]}, {rel, RelName10, RelVsn, [stdlib, kernel, {z,[]}, inets, sasl]}, + {rel, RelName11, RelVsn, [stdlib, kernel, z, {inets, load}]}, {incl_cond,exclude}, {mod_cond,app}, {app,kernel,[{incl_cond,include}]}, @@ -371,7 +384,6 @@ create_release_sort(Config) -> {mnesia, _}]}}, reltool:get_rel([{config, Sys}], RelName3)), - %%! BUG: same as OTP-4121, but for reltool???? Or revert tools and mnesia ?msym({ok, {release, {RelName4, RelVsn}, {erts, _}, [{kernel, _}, @@ -388,13 +400,29 @@ create_release_sort(Config) -> "in the app file: [tools]"}, reltool:get_rel([{config, Sys}], RelName5)), - ?m({error, "Undefined applications: [tools,mnesia]"}, + ?msym({ok, {release, {RelName6, RelVsn}, + {erts, _}, + [{kernel, _}, + {stdlib, _}, + {sasl, _}, + {inets, _}, + {tools, _}, + {mnesia, _}, + {z, _}]}}, reltool:get_rel([{config, Sys}], RelName6)), ?m({error,"Circular dependencies: [x,y]"}, reltool:get_rel([{config, Sys}], RelName7)), - ?m({error,"Undefined applications: [tools]"}, + ?msym({ok, {release, {RelName8, RelVsn}, + {erts, _}, + [{kernel, _}, + {stdlib, _}, + {sasl, _}, + {inets, _}, + {mnesia, _}, + {tools, _}, + {z, _, [mnesia,tools]}]}}, reltool:get_rel([{config, Sys}], RelName8)), ?msym({ok,{release,{RelName9,RelVsn}, @@ -406,7 +434,6 @@ create_release_sort(Config) -> {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,_}, @@ -416,6 +443,17 @@ create_release_sort(Config) -> {z,_,[]}]}}, reltool:get_rel([{config, Sys}], RelName10)), + ?msym({ok,{release,{RelName11,RelVsn}, + {erts,_}, + [{kernel,_}, + {stdlib,_}, + {sasl, _}, + {inets, _, load}, + {tools, _}, + {mnesia, _}, + {z,_}]}}, + reltool:get_rel([{config, Sys}], RelName11)), + ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -476,12 +514,16 @@ create_script_sort(Config) -> RelName3 = "Include-both", RelName4 = "Include-only-app", RelName5 = "Include-only-rel", - RelName6 = "Include-missing-app", + RelName6 = "Auto-add-missing-apps", RelName7 = "Circular", - RelName8 = "Include-both-missing-app", - RelName9 = "Include-overwrite", + RelName8 = "Include-rel-alter-order", + RelName9 = "Include-none-overwrite", + RelName10= "Uses-order-as-rel", RelVsn = "1.0", LibDir = filename:join(DataDir,"sort_apps"), + %% Application z (.app file): + %% includes [tools, mnesia] + %% uses [kernel, stdlib, sasl, inets] Sys = {sys, [ @@ -492,10 +534,11 @@ create_script_sort(Config) -> {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]}, + {rel, RelName6, RelVsn, [z]}, {rel, RelName7, RelVsn, [stdlib, kernel, mnesia, y, sasl, x]}, - {rel, RelName8, RelVsn, [stdlib, kernel, {z,[tools]}]}, + {rel, RelName8, RelVsn, [stdlib, kernel, {z,[mnesia,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}]}, @@ -552,8 +595,8 @@ create_script_sort(Config) -> [{kernel,KernelVsn}, {stdlib,StdlibVsn}, {z,"1.0"}, - {tools,ToolsVsn}, {mnesia,MnesiaVsn}, + {tools,ToolsVsn}, {sasl,SaslVsn}, {inets,InetsVsn}]}, FullName4 = filename:join(?WORK_DIR,RelName4), @@ -568,6 +611,10 @@ create_script_sort(Config) -> Rel6 = {release, {RelName6,RelVsn}, {erts,ErtsVsn}, [{kernel,KernelVsn}, {stdlib,StdlibVsn}, + {sasl,SaslVsn}, + {inets,InetsVsn}, + {tools,ToolsVsn}, + {mnesia,MnesiaVsn}, {z,"1.0"}]}, FullName6 = filename:join(?WORK_DIR,RelName6), ?m(ok, file:write_file(FullName6 ++ ".rel", io_lib:format("~p.\n", [Rel6]))), @@ -583,7 +630,11 @@ create_script_sort(Config) -> Rel8 = {release, {RelName8,RelVsn}, {erts,ErtsVsn}, [{kernel,KernelVsn}, {stdlib,StdlibVsn}, - {z,"1.0",[tools]}]}, + {z,"1.0",[mnesia,tools]}, + {sasl,SaslVsn}, + {inets,InetsVsn}, + {mnesia,MnesiaVsn}, + {tools,ToolsVsn}]}, FullName8 = filename:join(?WORK_DIR,RelName8), ?m(ok, file:write_file(FullName8 ++ ".rel", io_lib:format("~p.\n", [Rel8]))), Rel9 = {release, {RelName9,RelVsn}, {erts,ErtsVsn}, @@ -594,6 +645,14 @@ create_script_sort(Config) -> {inets,InetsVsn}]}, FullName9 = filename:join(?WORK_DIR,RelName9), ?m(ok, file:write_file(FullName9 ++ ".rel", io_lib:format("~p.\n", [Rel9]))), + Rel10 = {release, {RelName10,RelVsn}, {erts,ErtsVsn}, + [{kernel,KernelVsn}, + {stdlib,StdlibVsn}, + {z,"1.0",[]}, + {inets,InetsVsn}, + {sasl,SaslVsn}]}, + FullName10 = filename:join(?WORK_DIR,RelName10), + ?m(ok, file:write_file(FullName10 ++ ".rel", io_lib:format("~p.\n", [Rel10]))), %% Generate script files with systools and reltool and compare ZPath = filename:join([LibDir,"*",ebin]), @@ -625,26 +684,31 @@ create_script_sort(Config) -> "in the app file: [tools]"}, reltool:get_script(Pid, RelName5)), - ?msym({error,_,{undefined_applications,_}}, - systools_make_script(FullName6,ZPath)), - ?m({error, "Undefined applications: [tools,mnesia]"}, - reltool:get_script(Pid, RelName6)), + ?msym({ok,_,_}, systools_make_script(FullName6,ZPath)), + {ok, [SystoolsScript6]} = ?msym({ok,[_]}, file:consult(FullName6++".script")), + {ok, Script6} = ?msym({ok, _}, reltool:get_script(Pid, RelName6)), + ?m(equal, diff_script(SystoolsScript6, Script6)), ?msym({error,_,{circular_dependencies,_}}, systools_make_script(FullName7,ZPath)), ?m({error,"Circular dependencies: [x,y]"}, reltool:get_script(Pid, RelName7)), - ?msym({error,_,{undefined_applications,_}}, - systools_make_script(FullName8,ZPath)), - ?m({error, "Undefined applications: [tools]"}, - reltool:get_script(Pid, RelName8)), + ?msym({ok,_,_}, systools_make_script(FullName8,ZPath)), + {ok, [SystoolsScript8]} = ?msym({ok,[_]}, file:consult(FullName8++".script")), + {ok, Script8} = ?msym({ok, _}, reltool:get_script(Pid, RelName8)), + ?m(equal, diff_script(SystoolsScript8, Script8)), ?msym({ok,_,_}, systools_make_script(FullName9,ZPath)), {ok, [SystoolsScript9]} = ?msym({ok,[_]}, file:consult(FullName9++".script")), {ok, Script9} = ?msym({ok, _}, reltool:get_script(Pid, RelName9)), ?m(equal, diff_script(SystoolsScript9, Script9)), + ?msym({ok,_,_}, systools_make_script(FullName10,ZPath)), + {ok, [SystoolsScript10]} = ?msym({ok,[_]}, file:consult(FullName10++".script")), + {ok, Script10} = ?msym({ok, _}, reltool:get_script(Pid, RelName10)), + ?m(equal, diff_script(SystoolsScript10, Script10)), + %% Stop server ?m(ok, reltool:stop(Pid)), ok. @@ -950,8 +1014,6 @@ create_multiple_standalone(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Generate old type of target system - -create_old_target(_Config) -> {skip, "Old style of target"}; create_old_target(_Config) -> %% Configure the server @@ -974,8 +1036,7 @@ create_old_target(_Config) -> ?m(ok, reltool_utils:recursive_delete(TargetDir)), ?m(ok, file:make_dir(TargetDir)), ok = ?m(ok, reltool:create_target([{config, Config}], TargetDir)), - - %% io:format("Will fail on Windows (should patch erl.ini)\n", []), + ok = ?m(ok, reltool:install(RelName2, TargetDir)), Erl = filename:join([TargetDir, "bin", "erl"]), @@ -985,6 +1046,61 @@ create_old_target(_Config) -> ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate target system + +create_slim(Config) -> + %% Configure the server + RelName = "slim", + RelVsn = "1.0", + + DataDir = ?config(data_dir,Config), + LibDir = filename:join(DataDir,"slim"), + + Sys = + {sys, + [ + {root_dir, code:root_dir()}, + {lib_dirs, []}, + {boot_rel, RelName}, + {rel, RelName, RelVsn, [sasl, stdlib, kernel, a]}, + {app, sasl, [{incl_cond, include}]}, + {app, a, [{incl_cond, include}, + {lib_dir,filename:join(LibDir,"a-1.0")}]}, + {excl_lib,otp_root} + ]}, + + %% Generate target file + TargetDir = filename:absname(filename:join([?WORK_DIR, "target_slim"])), + ?m(ok, reltool_utils:recursive_delete(TargetDir)), + ?m(ok, file:make_dir(TargetDir)), + ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), + ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), + + TargetLibDir = filename:join(TargetDir,"lib"), + TargetRelDir = filename:join(TargetDir,"releases"), + TargetRelVsnDir = filename:join(TargetRelDir,RelVsn), + + {ok,["a-1.0.ez"]} = file:list_dir(TargetLibDir), + + RootDir = code:root_dir(), + Erl = filename:join([RootDir, "bin", "erl"]), + EscapedQuote = + case os:type() of + {win32,_} -> "\\\""; + _ -> "\"" + end, + Args = ["-boot_var", "RELTOOL_EXT_LIB", TargetLibDir, + "-boot", filename:join(TargetRelVsnDir,RelName), + "-sasl", "releases_dir", EscapedQuote++TargetRelDir++EscapedQuote], + {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl, Args)), + ?msym(RootDir, rpc:call(Node, code, root_dir, [])), + ?msym([{RelName,RelVsn,_,permanent}], + rpc:call(Node,release_handler,which_releases,[])), + ?msym(ok, stop_node(Node)), + + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Generate target system with eval_target_spec/3 eval_target_spec(_Config) -> @@ -1891,7 +2007,7 @@ save_config(Config) -> %% %% x-1.0: x1.erl x2.erl x3.erl %% \ / (x2 calls y1, x3 calls y2) -%% y-1.0: y1.erl y2.erl +%% y-1.0: y0.erl y1.erl y2.erl %% \ (y1 calls z1) %% z-1.0 z1.erl %% @@ -2021,6 +2137,47 @@ dependencies(Config) -> ok. +%% Test that incl_cond on mod level overwrites mod_cond on app level +%% Uses same test applications as dependencies/1 above +mod_incl_cond_derived(Config) -> + %% In app y: mod_cond=none means no module shall be included + %% but mod_cond is overwritten by incl_cond on mod level + Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, + {incl_cond, exclude}, + {app,kernel,[{incl_cond,include}]}, + {app,sasl,[{incl_cond,include}]}, + {app,stdlib,[{incl_cond,include}]}, + {app,x,[{incl_cond,include}]}, + {app,y,[{incl_cond,include}, + {mod_cond,none}, + {mod,y0,[{incl_cond,derived}]}, + {mod,y2,[{incl_cond,derived}]}]}]}, + {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), + + ?msym({ok,[#app{name=kernel}, + #app{name=sasl}, + #app{name=stdlib}, + #app{name=x,uses_apps=[y]}, + #app{name=y,uses_apps=[]}]}, + reltool_server:get_apps(Pid,whitelist)), + {ok, Der} = ?msym({ok,_},reltool_server:get_apps(Pid,derived)), + ?msym([], rm_missing_app(Der)), + ?msym({ok,[]}, reltool_server:get_apps(Pid,source)), + + %% 1. check that y0 is not included since it has + %% incl_cond=derived, but is not used by any other module. + ?msym({ok,#mod{is_included=undefined}}, reltool_server:get_mod(Pid,y0)), + + %% 2. check that y1 is excluded since it has undefined incl_cond + %% on mod level, so mod_cond on app level shall be used. + ?msym({ok,#mod{is_included=false}}, reltool_server:get_mod(Pid,y1)), + + %% 3. check that y2 is included since it has incl_cond=derived and + %% is used by x3. + ?msym({ok,#mod{is_included=true}}, reltool_server:get_mod(Pid,y2)), + + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% use_selected_vsn(Config) -> LibDir1 = filename:join(datadir(Config),"use_selected_vsn"), @@ -2145,6 +2302,39 @@ use_selected_vsn_relative_path(Config) -> ok = file:set_cwd(Cwd), ok. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Test that reltool recognizes an application with its real name even +%% though it uses non standard format for its version number (in the +%% directory name) +non_standard_vsn_id(Config) -> + LibDir = filename:join(datadir(Config),"non_standard_vsn_id"), + B1Dir = filename:join(LibDir,"b-first"), + B2Dir = filename:join(LibDir,"b-second"), + + %%----------------------------------------------------------------- + %% Default vsn of app b + Sys1 = {sys,[{lib_dirs,[LibDir]}, + {incl_cond, exclude}, + {app,kernel,[{incl_cond,include}]}, + {app,sasl,[{incl_cond,include}]}, + {app,stdlib,[{incl_cond,include}]}, + {app,b,[{incl_cond,include}]}]}, + {ok, Pid1} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), + ?msym({ok,#app{vsn="first",active_dir=B1Dir,sorted_dirs=[B1Dir,B2Dir]}}, + reltool_server:get_app(Pid1,b)), + + %%----------------------------------------------------------------- + %% Pre-selected vsn of app b + Sys2 = {sys,[{lib_dirs,[LibDir]}, + {incl_cond, exclude}, + {app,kernel,[{incl_cond,include}]}, + {app,sasl,[{incl_cond,include}]}, + {app,stdlib,[{incl_cond,include}]}, + {app,b,[{incl_cond,include},{vsn,"second"}]}]}, + {ok, Pid2} = ?msym({ok, _}, reltool:start_server([{config, Sys2}])), + ?msym({ok,#app{vsn="second",active_dir=B2Dir,sorted_dirs=[B1Dir,B2Dir]}}, + reltool_server:get_app(Pid2,b)), + ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2226,10 +2416,14 @@ mod_path(Node,Mod) -> %% Node handling start_node(Name, ErlPath) -> + start_node(Name, ErlPath, []). +start_node(Name, ErlPath, Args0) -> FullName = full_node_name(Name), - CmdLine = mk_node_cmdline(Name, ErlPath), - io:format("Starting node ~p: ~s~n", [FullName, CmdLine]), - case open_port({spawn, CmdLine}, []) of + Args = mk_node_args(Name, Args0), + io:format("Starting node ~p: ~s~n", + [FullName, lists:flatten([[X," "] || X <- [ErlPath|Args]])]), + %io:format("open_port({spawn_executable, ~p}, [{args,~p}])~n",[ErlPath,Args]), + case open_port({spawn_executable, ErlPath}, [{args,Args}]) of Port when is_port(Port) -> unlink(Port), erlang:port_close(Port), @@ -2246,29 +2440,21 @@ stop_node(Node) -> spawn(Node, fun () -> halt() end), receive {nodedown, Node} -> ok end. -mk_node_cmdline(Name) -> - Prog = case catch init:get_argument(progname) of - {ok,[[P]]} -> P; - _ -> exit(no_progname_argument_found) - end, - mk_node_cmdline(Name, Prog). - -mk_node_cmdline(Name, Prog) -> - Static = "-detached -noinput", +mk_node_args(Name, Args) -> Pa = filename:dirname(code:which(?MODULE)), NameSw = case net_kernel:longnames() of - false -> "-sname "; - true -> "-name "; + false -> "-sname"; + true -> "-name"; _ -> exit(not_distributed_node) end, {ok, Pwd} = file:get_cwd(), NameStr = atom_to_list(Name), - Prog ++ " " - ++ Static ++ " " - ++ NameSw ++ " " ++ NameStr ++ " " - ++ "-pa " ++ Pa ++ " " - ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr ++ " " - ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()). + ["-detached", "-noinput", + NameSw, NameStr, + "-pa", Pa, + "-env", "ERL_CRASH_DUMP", Pwd ++ "/erl_crash_dump." ++ NameStr, + "-setcookie", atom_to_list(erlang:get_cookie()) + | Args]. full_node_name(PreName) -> HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end, diff --git a/lib/reltool/test/reltool_server_SUITE_data/Makefile.src b/lib/reltool/test/reltool_server_SUITE_data/Makefile.src index 21410ceaa9..02846f42b6 100644 --- a/lib/reltool/test/reltool_server_SUITE_data/Makefile.src +++ b/lib/reltool/test/reltool_server_SUITE_data/Makefile.src @@ -22,7 +22,11 @@ SEL_VSN= \ use_selected_vsn/b-3.0/ebin/b.@EMULATOR@ \ use_selected_vsn/lib2/b-2.0/ebin/b.@EMULATOR@ -all: $(OTP9229) $(DEPENDENCIES) $(ESCRIPT) $(SEL_VSN) +SLIM= \ + slim/a-1.0/ebin/a_sup.@EMULATOR@ \ + slim/a-1.0/ebin/a.@EMULATOR@ + +all: $(OTP9229) $(DEPENDENCIES) $(ESCRIPT) $(SEL_VSN) $(SLIM) otp_9229/x-1.0/ebin/x.@EMULATOR@: otp_9229/x-1.0/src/x.erl erlc $(EFLAGS) -ootp_9229/x-1.0/ebin otp_9229/x-1.0/src/x.erl @@ -55,3 +59,8 @@ use_selected_vsn/b-3.0/ebin/b.@EMULATOR@: use_selected_vsn/b-3.0/src/b.erl erlc $(EFLAGS) -ouse_selected_vsn/b-3.0/ebin use_selected_vsn/b-3.0/src/b.erl use_selected_vsn/lib2/b-2.0/ebin/b.@EMULATOR@: use_selected_vsn/lib2/b-2.0/src/b.erl erlc $(EFLAGS) -ouse_selected_vsn/lib2/b-2.0/ebin use_selected_vsn/lib2/b-2.0/src/b.erl + +slim/a-1.0/ebin/a_sup.@EMULATOR@: slim/a-1.0/src/a_sup.erl + erlc $(EFLAGS) -oslim/a-1.0/ebin slim/a-1.0/src/a_sup.erl +slim/a-1.0/ebin/a.@EMULATOR@: slim/a-1.0/src/a.erl + erlc $(EFLAGS) -oslim/a-1.0/ebin slim/a-1.0/src/a.erl diff --git a/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/ebin/y.app b/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/ebin/y.app index d9dac371d7..39fdabeea4 100644 --- a/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/ebin/y.app +++ b/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/ebin/y.app @@ -2,6 +2,6 @@ {application, y, [{description, "Library application in reltool dependency test"}, {vsn, "1.0"}, - {modules, [y1,y2]}, + {modules, [y0,y1,y2]}, {registered, []}, {applications, [kernel, stdlib]}]}. diff --git a/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/src/y0.erl b/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/src/y0.erl new file mode 100644 index 0000000000..dc188ba7b6 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/src/y0.erl @@ -0,0 +1,5 @@ +-module(y0). +-compile(export_all). + +f() -> + ok. diff --git a/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/ebin/b.app b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/ebin/b.app new file mode 100644 index 0000000000..55550a8190 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/ebin/b.app @@ -0,0 +1,6 @@ +%% -*- erlang -*- +{application, b, + [{description, "Reltool test app for using selected version of app"}, + {vsn, "first"}, + {modules, [b]}, + {applications, [kernel, stdlib]}]}. diff --git a/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/src/b.erl b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/src/b.erl new file mode 100644 index 0000000000..a6b4ff1c05 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/src/b.erl @@ -0,0 +1,4 @@ +-module(b). +-compile(export_all). + +foo() -> ok. diff --git a/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/ebin/b.app b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/ebin/b.app new file mode 100644 index 0000000000..91e1365df7 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/ebin/b.app @@ -0,0 +1,6 @@ +%% -*- erlang -*- +{application, b, + [{description, "Reltool test app for using selected version of app"}, + {vsn, "second"}, + {modules, [b]}, + {applications, [kernel, stdlib]}]}. diff --git a/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/src/b.erl b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/src/b.erl new file mode 100644 index 0000000000..a6b4ff1c05 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/src/b.erl @@ -0,0 +1,4 @@ +-module(b). +-compile(export_all). + +foo() -> ok. diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app new file mode 100644 index 0000000000..3160e00da7 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app @@ -0,0 +1,7 @@ +{application, a, + [{description, "A CXC 138 11"}, + {vsn, "1.0"}, + {modules, [a, a_sup]}, + {registered, [a_sup]}, + {applications, [kernel, stdlib]}, + {mod, {a_sup, []}}]}. diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl new file mode 100644 index 0000000000..bb500bed69 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl @@ -0,0 +1,49 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a). + + +-behaviour(gen_server). + +-vsn(1). + +%% External exports +-export([start_link/0, a/0]). +%% Internal exports +-export([init/1, handle_call/3, handle_info/2, terminate/2]). + +start_link() -> gen_server:start_link({local, aa}, a, [], []). + +a() -> gen_server:call(aa, a). + +%%----------------------------------------------------------------- +%% Callback functions from gen_server +%%----------------------------------------------------------------- +init([]) -> + process_flag(trap_exit, true), + {ok, state}. + +handle_call(a, _From, State) -> + X = application:get_all_env(a), + {reply, X, State}. + +handle_info(_, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl new file mode 100644 index 0000000000..a141c1767b --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl @@ -0,0 +1,37 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a_sup). + + +-behaviour(supervisor). + +%% External exports +-export([start/2]). + +%% Internal exports +-export([init/1]). + +start(_, _) -> + supervisor:start_link({local, a_sup}, a_sup, []). + +init([]) -> + SupFlags = {one_for_one, 4, 3600}, + Config = {a, + {a, start_link, []}, + permanent, 2000, worker, [a]}, + {ok, {SupFlags, [Config]}}. diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index 3811d897c7..6872539b8c 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1 +1 @@ -RELTOOL_VSN = 0.6 +RELTOOL_VSN = 0.6.1 |