aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reltool
diff options
context:
space:
mode:
Diffstat (limited to 'lib/reltool')
-rw-r--r--lib/reltool/doc/src/notes.xml117
-rw-r--r--lib/reltool/doc/src/reltool.xml31
-rw-r--r--lib/reltool/doc/src/reltool_examples.xml5
-rw-r--r--lib/reltool/doc/src/reltool_usage.xml11
-rw-r--r--lib/reltool/examples/display_args5
-rw-r--r--lib/reltool/src/Makefile9
-rw-r--r--lib/reltool/src/reltool.erl4
-rw-r--r--lib/reltool/src/reltool_app_win.erl12
-rw-r--r--lib/reltool/src/reltool_fgraph_win.erl4
-rw-r--r--lib/reltool/src/reltool_mod_win.erl75
-rw-r--r--lib/reltool/src/reltool_server.erl215
-rw-r--r--lib/reltool/src/reltool_sys_win.erl132
-rw-r--r--lib/reltool/src/reltool_target.erl134
-rw-r--r--lib/reltool/src/reltool_utils.erl43
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl507
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/ebin/y.app2
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dependencies/y-1.0/src/y0.erl5
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl1
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/ebin/b.app6
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-first/src/b.erl4
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/ebin/b.app6
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/non_standard_vsn_id/b-second/src/b.erl4
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/unicode/ua-1.0/ebin/ua.app7
-rw-r--r--lib/reltool/test/reltool_test_lib.erl6
-rw-r--r--lib/reltool/vsn.mk2
25 files changed, 988 insertions, 359 deletions
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index 66ec7e9035..598d3333f8 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>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -37,7 +37,120 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.6.1</title>
+ <section><title>Reltool 0.6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix receive support in erl_eval with a BEAM module.
+ Thanks to Anthony Ramine.</p>
+ <p>
+ Own Id: OTP-11137</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Reltool used to fail if an application was mentioned in
+ the config file which was not found in the file system,
+ even if the application was explicitly excluded in the
+ config. This has been changed and will only produce a
+ warning. If the application is not explicitly excluded it
+ will still cause reltool to fail. Thanks to H�kan
+ Mattsson!</p>
+ <p>
+ Own Id: OTP-10988</p>
+ </item>
+ <item>
+ <p>
+ Fix possibly "not owner" error while file copy with
+ reltool. Thanks to Alexey Saltanov.</p>
+ <p>
+ Own Id: OTP-11099</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.6.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Some updates are made to reltool for handling unicode.</p>
+ <p>
+ Own Id: OTP-10781</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <list> <item> If <c>incl_cond</c> was set to
+ <c>derived</c> on module level, then reltool_server would
+ crash with a <c>case_clause</c>. This has been corrected.
+ <c>incl_cond</c> on module level now overwrites
+ <c>mod_cond</c> on app or sys level as described in the
+ documentation. </item> <item> If a <c>rel</c> spec in the
+ reltool config does not contain all applications that are
+ listed as <c>{applications,Applications}</c> in a
+ <c>.app</c> file, then these applications are
+ autmatically added when creating the <c>.rel</c> file.
+ For 'included_applications', the behaviour was not the
+ same. I.e. if a <c>rel</c> spec in the reltool config did
+ not contain all applications that are listed as
+ <c>{included_applications,InclApplications}</c> in a
+ <c>.app</c> file, then reltool would fail with reason
+ "Undefined applications" when creating the <c>.rel</c>
+ file. This has been corrected, so both
+ <c>applications</c> and <c>included_applications</c> are
+ now automatically added if not already in the <c>rel</c>
+ spec. </item> <item> The <c>rel</c> specification now
+ dictates the order in which included and used
+ applications (specified in the <c>.app</c> file as
+ <c>included_applications</c> and <c>applications</c>
+ respectively) are loaded/started by the boot file. If the
+ applications are not specified in the <c>rel</c> spec,
+ then the order from the <c>.app</c> file is used. This
+ was a bug earlier reported on systools, and is now also
+ implemented in reltool. </item> <item> Instead of only
+ looking at the directory name, reltool now first looks
+ for a <c>.app</c> file in order to figure out the name of
+ an application. </item> </list></p>
+ <p>
+ Own Id: OTP-10012 Aux Id: kunagi-171 [82] </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Some examples overflowing the width of PDF pages have
+ been corrected. </p>
+ <p>
+ Own Id: OTP-10665</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.6.1</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml
index 2567a72999..8437b7a623 100644
--- a/lib/reltool/doc/src/reltool.xml
+++ b/lib/reltool/doc/src/reltool.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -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
@@ -264,7 +274,8 @@
</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>
+ <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>
@@ -372,6 +383,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>
@@ -383,6 +399,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>
@@ -446,7 +467,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
diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml
index 19a3f37819..7dfe0cbff5 100644
--- a/lib/reltool/doc/src/reltool_examples.xml
+++ b/lib/reltool/doc/src/reltool_examples.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2011</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -261,7 +261,8 @@ Eshell V5.7.3 (abort with ^G)
8&gt; reltool:get_script(Server, "NAME").
{ok,{script,{"NAME","VSN"},
[{preLoaded,[erl_prim_loader,erlang,init,otp_ring0,
- prim_file,prim_inet,prim_zip,zlib]},
+ prim_eval,prim_file,prim_inet,prim_zip,
+ zlib]},
{progress,preloaded},
{path,["$ROOT/lib/kernel-2.13/ebin",
"$ROOT/lib/stdlib-1.16/ebin"]},
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/display_args b/lib/reltool/examples/display_args
index bf0994ab7c..a8882f7bda 100644
--- a/lib/reltool/examples/display_args
+++ b/lib/reltool/examples/display_args
@@ -1,8 +1,9 @@
#!/usr/bin/env escript
%% -*- erlang -*-
-%%! -smp disable
+%%! -emuarg emuvalue
main(Args) ->
+ {ok,[Emuvalue]} = init:get_argument(emuarg),
io:format("Root dir: ~s\n", [code:root_dir()]),
io:format("Script args: ~p\n", [Args]),
- io:format("Smp: ~p\n", [erlang:system_info(smp_support)]).
+ io:format("Emuarg: ~p\n", [Emuvalue]).
diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile
index a7e34053f1..b8387fff96 100644
--- a/lib/reltool/src/Makefile
+++ b/lib/reltool/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2012. All Rights Reserved.
+# Copyright Ericsson AB 2009-2013. 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
@@ -57,7 +57,8 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
ERL_COMPILE_FLAGS += +'{parse_transform,sys_pre_attributes}' \
- +'{attribute,insert,app_vsn,$(APP_VSN)}'
+ +'{attribute,insert,app_vsn,$(APP_VSN)}' \
+ -Werror
# ----------------------------------------------------
# Targets
@@ -79,10 +80,10 @@ docs:
# ----------------------------------------------------
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
# ----------------------------------------------------
# Dependencies
diff --git a/lib/reltool/src/reltool.erl b/lib/reltool/src/reltool.erl
index 2bdf222aa0..8ab2c2399e 100644
--- a/lib/reltool/src/reltool.erl
+++ b/lib/reltool/src/reltool.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -120,7 +120,7 @@ apply_fun(Pid, false, Fun) ->
apply_fun(Pid, true, Fun) ->
case get_status(Pid) of
{ok, Warnings} ->
- [io:format("~p: ~s\n", [?APPLICATION, W]) || W <- Warnings],
+ [io:format("~w: ~ts\n", [?APPLICATION, W]) || W <- Warnings],
apply_fun(Pid, false, Fun);
{error, _Reason} = Error ->
stop(Pid),
diff --git a/lib/reltool/src/reltool_app_win.erl b/lib/reltool/src/reltool_app_win.erl
index 6cd0d2f90b..81ab1687fb 100644
--- a/lib/reltool/src/reltool_app_win.erl
+++ b/lib/reltool/src/reltool_app_win.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -173,7 +173,7 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) ->
S#state.mod_wins)},
?MODULE:loop(S2);
Msg ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
+ error_logger:format("~w~w got unexpected message:\n\t~p\n",
[?MODULE, self(), Msg]),
?MODULE:loop(S)
end.
@@ -181,7 +181,7 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) ->
exit_warning({'EXIT', _Pid, shutdown}) ->
ok;
exit_warning({'EXIT', _Pid, _Reason} = Msg) ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
+ error_logger:format("~w~w got unexpected message:\n\t~p\n",
[?MODULE, self(), Msg]).
create_window(#state{app = App} = S) ->
@@ -627,7 +627,7 @@ handle_event(#state{sys = Sys, app = App} = S, Wx) ->
Items = reltool_utils:get_items(ListCtrl),
handle_mod_button(S, Items, Action);
_ ->
- error_logger:format("~p~p got unexpected app event from "
+ error_logger:format("~w~w got unexpected app event from "
"wx:\n\t~p\n",
[?MODULE, self(), Wx]),
S
@@ -674,8 +674,8 @@ move_mod(App, {_ItemNo, ModStr}, Action) ->
blacklist_del ->
undefined;
_ ->
- error_logger:format("~p~p got unexpected mod "
- "button event: ~p\n\t ~p\n",
+ error_logger:format("~w~w got unexpected mod "
+ "button event: ~w\n\t ~p\n",
[?MODULE, self(), ModName, Action]),
M#mod.incl_cond
end,
diff --git a/lib/reltool/src/reltool_fgraph_win.erl b/lib/reltool/src/reltool_fgraph_win.erl
index b0deb1bab2..66bc2b5ab3 100644
--- a/lib/reltool/src/reltool_fgraph_win.erl
+++ b/lib/reltool/src/reltool_fgraph_win.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -525,7 +525,7 @@ loop(S, G) ->
exit(Reason);
Other ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
+ error_logger:format("~w~w got unexpected message:\n\t~p\n",
[?MODULE, self(), Other]),
loop(S, G)
end.
diff --git a/lib/reltool/src/reltool_mod_win.erl b/lib/reltool/src/reltool_mod_win.erl
index 899423bb6d..b0193a2ae4 100644
--- a/lib/reltool/src/reltool_mod_win.erl
+++ b/lib/reltool/src/reltool_mod_win.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -130,7 +130,7 @@ do_init(Parent, WxEnv, Xref, RelPid, C, ModName) ->
loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) ->
receive
Msg ->
- %% io:format("~s~p -> ~p\n", [S#state.name, self(), Msg]),
+ %% io:format("~ts~w -> ~p\n", [S#state.name, self(), Msg]),
case Msg of
{system, From, SysMsg} ->
Dbg = C#common.sys_debug,
@@ -170,7 +170,7 @@ loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) ->
S2 = handle_event(S, Wx),
?MODULE:loop(S2);
_ ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
+ error_logger:format("~w~w got unexpected message:\n\t~p\n",
[?MODULE, self(), Msg]),
?MODULE:loop(S)
end
@@ -335,23 +335,37 @@ find_regular_bin(App, Mod) ->
SrcDir = filename:join([ActiveDir, "src"]),
ModStr = atom_to_list(Mod#mod.name),
Base = "^" ++ ModStr ++ "\\.erl$",
- Find = fun(F, _Acc) -> throw(file:read_file(F)) end,
+ Find = fun(F, _Acc) -> throw({file:read_file(F),epp:read_encoding(F)}) end,
case catch filelib:fold_files(SrcDir, Base, true, Find, {error, enoent}) of
- {ok, Bin} ->
- Bin;
+ {{ok, Bin},Encoding0} ->
+ Encoding =
+ case Encoding0 of
+ none -> epp:default_encoding();
+ _ -> Encoding0
+ end,
+ unicode:characters_to_binary(Bin,Encoding,utf8);
{error, enoent} ->
%% Reconstructing the source code from debug info if possible
BeamFile = filename:join([ActiveDir, "ebin", ModStr ++ ".beam"]),
- case beam_lib:chunks(BeamFile, [abstract_code]) of
- {ok,{_,[{abstract_code,{_,AC}}]}} ->
- IoList = erl_prettypr:format(erl_syntax:form_list(AC)),
- list_to_binary(IoList);
- _ ->
- list_to_binary(["%% Bad luck, cannot find any "
- "debug info in the file \"", BeamFile])
+ case source_from_beam(BeamFile) of
+ {ok,Source} ->
+ Source;
+ error ->
+ unicode:characters_to_binary(
+ ["%% Bad luck, cannot find any "
+ "debug info in the file \"", BeamFile])
end
end.
+source_from_beam(Beam) ->
+ case beam_lib:chunks(Beam, [abstract_code]) of
+ {ok,{_,[{abstract_code,{_,AC}}]}} ->
+ IoList = [erl_pp:form(F,[{encoding,utf8}]) || F <- AC],
+ {ok,unicode:characters_to_binary(IoList)};
+ _ ->
+ error
+ end.
+
find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
NotFound = false,
ModName = Mod#mod.name,
@@ -366,16 +380,10 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
case beam_lib:version(Bin) of
{ok,{M, _}} when M =:= ModName;
FullName =:= "." ->
- case beam_lib:chunks(Bin,
- [abstract_code]) of
- {ok,{_,[{abstract_code,{_,AC}}]}} ->
- Form =
- erl_syntax:form_list(AC),
- IoList =
- erl_prettypr:format(Form),
- {obj,
- list_to_binary(IoList)};
- _ ->
+ case source_from_beam(Bin) of
+ {ok,Source} ->
+ {obj,Source};
+ error ->
Acc
end;
_ ->
@@ -396,12 +404,9 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
case filename:split(FullName) of
[_AppName, "ebin", F]
when F =:= ObjFile, Acc =:= NotFound ->
- case beam_lib:chunks(GetBin(),
- [abstract_code]) of
- {ok,{_,[{abstract_code,{_,AC}}]}} ->
- Form = erl_syntax:form_list(AC),
- IoList = erl_prettypr:format(Form),
- {obj, list_to_binary(IoList)};
+ case source_from_beam(GetBin()) of
+ {ok,Source} ->
+ {obj,Source};
_ ->
Acc
end;
@@ -420,13 +425,15 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
{ok, {obj, Bin}} ->
Bin;
_ ->
- list_to_binary(["%% Bad luck, cannot find the "
- "code in the escript ", Escript, "."])
+ unicode:characters_to_binary(
+ ["%% Bad luck, cannot find the "
+ "code in the escript ", Escript, "."])
end
catch
throw:Reason when is_list(Reason) ->
- list_to_binary(["%% Bad luck, cannot find the code "
- "in the escript ", Escript, ": ", Reason])
+ unicode:characters_to_binary(
+ ["%% Bad luck, cannot find the code "
+ "in the escript ", Escript, ": ", Reason])
end.
create_config_page(S) ->
@@ -478,7 +485,7 @@ handle_event(#state{xref_pid = Xref} = S, Wx) ->
wxWindow:setFocus(ObjRef),
S;
_ ->
- error_logger:format("~p~p got unexpected mod event from "
+ error_logger:format("~w~w got unexpected mod event from "
"wx:\n\t~p\n",
[?MODULE, self(), Wx]),
S
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index 3d1d7e54bf..97785ca7f8 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -399,12 +399,12 @@ loop(#state{sys = Sys} = S) ->
{'EXIT', Pid, Reason} when Pid =:= S#state.parent_pid ->
exit(Reason);
{call, ReplyTo, Ref, Msg} when is_pid(ReplyTo), is_reference(Ref) ->
- error_logger:format("~p~p got unexpected call:\n\t~p\n",
+ error_logger:format("~w~w got unexpected call:\n\t~p\n",
[?MODULE, self(), Msg]),
reltool_utils:reply(ReplyTo, Ref, {error, {invalid_call, Msg}}),
?MODULE:loop(S);
Msg ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
+ error_logger:format("~w~w got unexpected message:\n\t~p\n",
[?MODULE, self(), Msg]),
?MODULE:loop(S)
end.
@@ -422,7 +422,7 @@ do_set_apps(#state{sys = Sys} = S, ChangedApps) ->
%% 2) removing #app records if no configurable fields are set
%% 3) keeping #app records that are not changed
app_update_config([#app{name=Name,is_escript={inlined,Escript}}|_],_SysApps) ->
- reltool_utils:throw_error("Application ~p is inlined in ~p. Can not change "
+ reltool_utils:throw_error("Application ~w is inlined in ~w. Can not change "
"configuration for an inlined application.",
[Name,Escript]);
app_update_config([Config|Configs],SysApps) ->
@@ -580,8 +580,8 @@ apps_in_rel(#rel{name = RelName, rel_apps = RelApps}, Apps) ->
IA;
false ->
reltool_utils:throw_error(
- "Release ~p uses non existing "
- "application ~p",
+ "Release ~tp uses non existing "
+ "application ~w",
[RelName,RA#rel_app.name])
end;
IA ->
@@ -602,7 +602,7 @@ more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc) ->
more_apps_in_rels(RelApps, Apps, Acc2);
false ->
reltool_utils:throw_error(
- "Release ~p uses non existing application ~p",
+ "Release ~tp uses non existing application ~w",
[RelName,AppName])
end
end;
@@ -640,7 +640,7 @@ app_init_is_included(#state{app_tab = AppTab, mod_tab = ModTab, sys=Sys},
{undefined, false, false, Status};
{exclude, [RelName | _]} -> % App is included in at least one rel
reltool_utils:throw_error(
- "Application ~p is used in release ~p and cannot be excluded",
+ "Application ~w is used in release ~tp and cannot be excluded",
[AppName,RelName]);
{derived, []} ->
{undefined, undefined, undefined, Status};
@@ -665,7 +665,7 @@ app_init_is_included(#state{app_tab = AppTab, mod_tab = ModTab, sys=Sys},
Status3.
mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) ->
- %% print(M#mod.name, hipe, "incl_cond -> ~p\n", [AppCond]),
+ %% print(M#mod.name, hipe, "incl_cond -> ~w\n", [AppCond]),
IsIncl =
case AppCond of
include ->
@@ -674,8 +674,10 @@ 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",
+ %% print(M#mod.name, hipe, "mod_cond -> ~w\n",
%% [ModCond]),
case ModCond of
all -> true;
@@ -693,6 +695,8 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) ->
true;
exclude ->
false;
+ derived ->
+ undefined;
undefined ->
Default
end
@@ -707,23 +711,23 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) ->
{false,_} ->
ets:insert(ModTab, M2),
reltool_utils:add_warning(
- "Module ~p exists in applications ~p and ~p. "
- "Using module from application ~p.",
+ "Module ~w exists in applications ~w and ~w. "
+ "Using module from application ~w.",
[M#mod.name, Existing#mod.app_name,
M#mod.app_name, M#mod.app_name],
Status);
{_,false} ->
%% Don't insert in ModTab - using Existing
reltool_utils:add_warning(
- "Module ~p exists in applications ~p and ~p. "
- "Using module from application ~p.",
+ "Module ~w exists in applications ~w and ~w. "
+ "Using module from application ~w.",
[M#mod.name, Existing#mod.app_name,
M#mod.app_name,Existing#mod.app_name],
Status);
{_,_} ->
reltool_utils:throw_error(
- "Module ~p potentially included by two different "
- "applications: ~p and ~p.",
+ "Module ~w potentially included by two different "
+ "applications: ~w and ~w.",
[M#mod.name,Existing#mod.app_name,M#mod.app_name])
end;
[] ->
@@ -731,7 +735,7 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) ->
Status
end,
- %% print(M#mod.name, hipe, "~p -> ~p\n", [M2, IsIncl]),
+ %% print(M#mod.name, hipe, "~p -> ~w\n", [M2, IsIncl]),
{M2,Status2}.
false_to_undefined(Bool) ->
@@ -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),
@@ -883,7 +888,7 @@ mod_recap_dependencies(S, A, [#mod{name = ModName}=M1 | Mods], Acc, IsIncl) ->
case ets:lookup(S#state.mod_tab, ModName) of
[M2] when M2#mod.app_name=:=A#app.name ->
ModStatus = do_get_status(M2),
- %% print(M2#mod.name, hipe, "status -> ~p\n", [ModStatus]),
+ %% print(M2#mod.name, hipe, "status -> ~w\n", [ModStatus]),
{IsIncl2, M3} =
case M2#mod.is_included of
true ->
@@ -905,8 +910,8 @@ mod_recap_dependencies(S, A, [#mod{name = ModName}=M1 | Mods], Acc, IsIncl) ->
%% A module is potensially included by multiple
%% applications. This is not allowed!
reltool_utils:throw_error(
- "Module ~p potentially included by two different applications: "
- "~p and ~p", [ModName,A#app.name, " and ", M2#mod.app_name, "."])
+ "Module ~w potentially included by two different applications: "
+ "~w and ~w.", [ModName,A#app.name, M2#mod.app_name])
end;
mod_recap_dependencies(_S, _A, [], Acc, IsIncl) ->
{lists:reverse(Acc), IsIncl}.
@@ -934,7 +939,7 @@ verify_config(#state{app_tab=AppTab, sys=#sys{boot_rel = BootRel, rels = Rels}},
Rels);
false ->
reltool_utils:throw_error(
- "Release ~p is mandatory (used as boot_rel)",[BootRel])
+ "Release ~tp is mandatory (used as boot_rel)",[BootRel])
end.
check_app(AppTab, {RelName, AppName}, Status) ->
@@ -944,7 +949,7 @@ check_app(AppTab, {RelName, AppName}, Status) ->
Status;
_ ->
reltool_utils:throw_error(
- "Release ~p uses non included application ~p",[RelName,AppName])
+ "Release ~tp uses non included application ~w",[RelName,AppName])
end.
check_rel(RelName, RelApps, Status) ->
@@ -955,8 +960,8 @@ check_rel(RelName, RelApps, Status) ->
Acc;
false ->
reltool_utils:throw_error(
- "Mandatory application ~p is not included in "
- "release ~p", [AppName,RelName])
+ "Mandatory application ~w is not included in "
+ "release ~tp", [AppName,RelName])
end
end,
Mandatory = [kernel, stdlib],
@@ -968,7 +973,8 @@ refresh_app(#app{name = AppName,
is_escript = IsEscript,
active_dir = ActiveDir,
label = OptLabel,
- mods = Mods} = App,
+ mods = Mods,
+ status = AppStatus} = App,
Force,
Status) ->
if
@@ -979,7 +985,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,
@@ -988,6 +994,8 @@ refresh_app(#app{name = AppName,
read_app_info(AppFile,
AppFile,
AppName,
+ ActiveDir,
+ AppStatus,
DefaultVsn,
Status),
@@ -1010,8 +1018,8 @@ refresh_app(#app{name = AppName,
lists:foldl(
fun(M,S) ->
reltool_utils:add_warning(
- "Module ~p duplicated in app file for "
- "application ~p.", [M, AppName], S)
+ "Module ~w duplicated in app file for "
+ "application ~w.", [M, AppName], S)
end,
Status3,
DuplicatedMods)
@@ -1059,9 +1067,11 @@ refresh_app(#app{name = AppName,
missing_app_info(Vsn) ->
#app_info{vsn = Vsn}.
-read_app_info(_AppFileOrBin, _AppFile, erts, DefaultVsn, Status) ->
+read_app_info(_AppFileOrBin, _AppFile, erts, _ActiveDir, _AppStatus, DefaultVsn, Status) ->
{missing_app_info(DefaultVsn), Status};
-read_app_info(AppFileOrBin, AppFile, AppName, DefaultVsn, Status) ->
+read_app_info(_AppFileOrBin, _AppFile, _AppName, undefined, missing, DefaultVsn, Status) ->
+ {missing_app_info(DefaultVsn), Status};
+read_app_info(AppFileOrBin, AppFile, AppName, _ActiveDir, _AppStatus, DefaultVsn, Status) ->
EnoentText = file:format_error(enoent),
case reltool_utils:prim_consult(AppFileOrBin) of
{ok, [{application, AppName, Info}]} ->
@@ -1069,18 +1079,18 @@ read_app_info(AppFileOrBin, AppFile, AppName, DefaultVsn, Status) ->
parse_app_info(AppFile, Info, AI, Status);
{ok, _BadApp} ->
{missing_app_info(DefaultVsn),
- reltool_utils:add_warning("~p: Illegal contents in app file ~p, "
+ reltool_utils:add_warning("~w: Illegal contents in app file ~tp, "
"application tuple with arity 3 expected.",
[AppName,AppFile],
Status)};
{error, Text} when Text =:= EnoentText ->
{missing_app_info(DefaultVsn),
- reltool_utils:add_warning("~p: Missing app file ~p.",
- [AppName,AppFile],
- Status)};
+ reltool_utils:add_warning("~w: Missing app file ~tp.",
+ [AppName,AppFile],
+ Status)};
{error, Text} ->
{missing_app_info(DefaultVsn),
- reltool_utils:add_warning("~p: Cannot parse app file ~p (~p).",
+ reltool_utils:add_warning("~w: Cannot parse app file ~tp (~tp).",
[AppName,AppFile,Text],
Status)}
end.
@@ -1117,7 +1127,7 @@ parse_app_info(File, [{Key, Val} | KeyVals], AI, Status) ->
Status);
_ ->
Status2 =
- reltool_utils:add_warning("Unexpected item ~p in app file ~p.",
+ reltool_utils:add_warning("Unexpected item ~p in app file ~tp.",
[Key,File],
Status),
parse_app_info(File, KeyVals, AI, Status2)
@@ -1207,7 +1217,7 @@ wait_for_processto_die(Ref, Pid, File) ->
{'DOWN', Ref, _Type, _Object, _Info} ->
ok
after timer:seconds(30) ->
- error_logger:error_msg("~p(~p): Waiting for process ~p to die ~p\n",
+ error_logger:error_msg("~w(~w): Waiting for process ~w to die ~tp\n",
[?MODULE, ?LINE, Pid, File]),
wait_for_processto_die(Ref, Pid, File)
end.
@@ -1218,7 +1228,7 @@ add_missing_mods(AppName, EbinMods, AppModNames) ->
[missing_mod(ModName, AppName) || ModName <- MissingModNames].
missing_mod(ModName, AppName) ->
- %% io:format("Missing: ~p -> ~p\n", [AppName, ModName]),
+ %% io:format("Missing: ~w -> ~w\n", [AppName, ModName]),
#mod{name = ModName,
app_name = AppName,
incl_cond = undefined,
@@ -1318,7 +1328,7 @@ read_config(OldSys, Filename) when is_list(Filename) ->
{ok, Content} ->
reltool_utils:throw_error("Illegal file content: ~p",[Content]);
{error, Reason} ->
- reltool_utils:throw_error("Illegal config file ~p: ~s",
+ reltool_utils:throw_error("Illegal config file ~tp: ~ts",
[Filename,file:format_error(Reason)])
end;
read_config(OldSys, {sys, KeyVals}) ->
@@ -1336,7 +1346,7 @@ read_config(OldSys, {sys, KeyVals}) ->
NewSys2;
false ->
reltool_utils:throw_error(
- "Release ~p is mandatory (used as boot_rel)",
+ "Release ~tp is mandatory (used as boot_rel)",
[NewSys2#sys.boot_rel])
end;
read_config(_OldSys, BadConfig) ->
@@ -1505,7 +1515,7 @@ decode(#app{} = App, [{Key, Val} | KeyVals]) ->
active_dir = Dir,
sorted_dirs = [Dir]};
false ->
- reltool_utils:throw_error("Illegal lib dir for ~p: ~p",
+ reltool_utils:throw_error("Illegal lib dir for ~w: ~p",
[App#app.name, Val])
end;
SelectVsn when SelectVsn=:=vsn; SelectVsn=:=lib_dir ->
@@ -1637,7 +1647,7 @@ patch_erts_version(RootDir, Apps, Status) ->
end;
false ->
reltool_utils:throw_error(
- "erts cannot be found in the root directory ~p", [RootDir])
+ "erts cannot be found in the root directory ~tp", [RootDir])
end.
libs_to_dirs(RootDir, LibDirs) ->
@@ -1664,10 +1674,10 @@ libs_to_dirs(RootDir, LibDirs) ->
lists:prefix("erts", F)],
app_dirs2(AllLibDirs, [ErtsFiles]);
[Duplicate | _] ->
- reltool_utils:throw_error("Duplicate library: ~p",[Duplicate])
+ reltool_utils:throw_error("Duplicate library: ~tp",[Duplicate])
end;
{error, Reason} ->
- reltool_utils:throw_error("Missing root library ~p: ~s",
+ reltool_utils:throw_error("Missing root library ~tp: ~ts",
[RootDir,file:format_error(Reason)])
end.
@@ -1680,8 +1690,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}}
@@ -1693,37 +1702,97 @@ app_dirs2([Lib | Libs], Acc) ->
Files2 = lists:zf(Filter, Files),
app_dirs2(Libs, [Files2 | Acc]);
{error, Reason} ->
- reltool_utils:throw_error("Illegal library ~p: ~s",
+ reltool_utils:throw_error("Illegal library ~tp: ~ts",
[Lib, file:format_error(Reason)])
end;
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 ~tp: ~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]),
+ Dir = filename:join([Escript, AppName]),
{Info, StatusAcc2} =
read_app_info(GetBin(),
AppFileName,
AppName,
+ Dir,
+ ok,
DefaultVsn,
Status),
- Dir = filename:join([Escript, AppName]),
{[{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()},
@@ -1760,6 +1829,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 =
@@ -1774,8 +1844,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 ~tp: ~p",
+ [Escript,Reason2])
end;
escripts_to_apps([], Apps, Status) ->
{Apps, Status}.
@@ -1837,7 +1908,7 @@ init_escript_app(AppName, EscriptAppName, Dir, Info, Mods, Apps, Status) ->
case lists:keymember(AppName, #app.name, Apps) of
true ->
reltool_utils:throw_error(
- "~p: Application name clash. Escript ~p contains application ~p.",
+ "~w: Application name clash. Escript ~tp contains application ~tp.",
[AppName,Dir,AppName]);
false ->
{App2, Status}
@@ -1915,28 +1986,36 @@ refresh_apps(ConfigApps, [New | NewApps], Acc, Force, Status) ->
refresh_apps(_ConfigApps, [], Acc, _Force, Status) ->
{lists:reverse(Acc), Status}.
-
ensure_app_info(#app{is_escript = IsEscript, active_dir = Dir, info = Info},
Status)
when IsEscript=/=false ->
%% Escript or application which is inlined in an escript
{Info, Dir, Status};
-ensure_app_info(#app{name = Name, sorted_dirs = []}, _Status) ->
- reltool_utils:throw_error("~p: : Missing application directory.",[Name]);
+ensure_app_info(#app{name = Name, sorted_dirs = []} = App, Status) ->
+ Reason = "~w: Missing application directory.",
+ case App of
+ #app{incl_cond = exclude, status = missing, active_dir = Dir} ->
+ Status2 = reltool_utils:add_warning(Reason, [Name], Status),
+ {missing_app_info(""), Dir, Status2};
+ _ ->
+ reltool_utils:throw_error(Reason, [Name])
+ end;
ensure_app_info(#app{name = Name,
vsn = Vsn,
use_selected_vsn = UseSelectedVsn,
active_dir = ActiveDir,
sorted_dirs = Dirs,
- info = undefined},
+ info = undefined,
+ status = AppStatus},
Status) ->
ReadInfo =
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)
+ read_app_info(AppFile, AppFile, Name, ActiveDir,
+ AppStatus, DefaultVsn, StatusAcc)
end,
{AllInfo, Status2} = lists:mapfoldl(ReadInfo, Status, Dirs),
AllVsns = [I#app_info.vsn || I <- AllInfo],
@@ -1947,8 +2026,8 @@ ensure_app_info(#app{name = Name,
Status2;
[BadVsn | _] ->
reltool_utils:throw_error(
- "~p: Application version clash. "
- "Multiple directories contains version ~p.",
+ "~w: Application version clash. "
+ "Multiple directories contains version ~tp.",
[Name,BadVsn])
end,
FirstInfo = hd(AllInfo),
@@ -1970,8 +2049,8 @@ ensure_app_info(#app{name = Name,
{Info, VsnDir, Status3};
false ->
reltool_utils:throw_error(
- "~p: No application directory contains "
- "selected version ~p", [Name,Vsn])
+ "~w: No application directory contains "
+ "selected version ~tp", [Name,Vsn])
end
end;
true ->
diff --git a/lib/reltool/src/reltool_sys_win.erl b/lib/reltool/src/reltool_sys_win.erl
index 0c0b295db1..b5d54e6d3e 100644
--- a/lib/reltool/src/reltool_sys_win.erl
+++ b/lib/reltool/src/reltool_sys_win.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -49,7 +49,6 @@
rel_book,
lib_tree,
status_bar,
- popup_menu,
source,
whitelist,
blacklist,
@@ -136,6 +135,7 @@ init(Options) ->
do_init(Options)
catch
error:Reason ->
+ io:format("~p: ~p~n",[Reason, erlang:get_stacktrace()]),
exit({Reason, erlang:get_stacktrace()})
end.
@@ -181,7 +181,7 @@ do_init([{safe_config, Safe}, {parent, Parent} | Options]) ->
end.
restart_server_safe_config(true,Parent,Reason) ->
- io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
+ io:format("~w(~w): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
proc_lib:init_ack(Parent, {error,Reason});
restart_server_safe_config(false,Parent,Reason) ->
wx:new(),
@@ -198,7 +198,7 @@ restart_server_safe_config(false,Parent,Reason) ->
?wxID_OK ->
do_init([{safe_config,true},{parent,Parent},?safe_config]);
?wxID_CANCEL ->
- io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
+ io:format("~w(~w): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
proc_lib:init_ack(Parent,{error,Reason})
end.
@@ -211,7 +211,7 @@ exit_dialog(Warnings) ->
?wxID_OK ->
ok;
?wxID_CANCEL ->
- io:format("~p(~p): <ERROR> ~s\n", [?MODULE, ?LINE, Details]),
+ io:format("~w(~w): <ERROR> ~ts\n", [?MODULE, ?LINE, Details]),
exit(Details)
end.
@@ -249,7 +249,7 @@ loop(S) ->
WWs2 = lists:delete(ObjRef, WWs),
?MODULE:loop(S#state{warning_wins = WWs2});
false ->
- error_logger:format("~p~p got unexpected "
+ error_logger:format("~w~w got unexpected "
"message:\n\t~p\n",
[?MODULE, self(), Msg]),
?MODULE:loop(S)
@@ -291,7 +291,7 @@ loop(S) ->
S#state.app_wins),
?MODULE:loop(S#state{fgraph_wins = FWs, app_wins = AWs});
Msg ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
+ error_logger:format("~w~w got unexpected message:\n\t~p\n",
[?MODULE, self(), Msg]),
?MODULE:loop(S)
end.
@@ -315,7 +315,7 @@ handle_child_exit({'EXIT', Pid, _Reason} = Exit, FWs, AWs) ->
msg_warning({'EXIT', _Pid, shutdown}, Type) when Type =/= unknown ->
ok;
msg_warning(Exit, Type) ->
- error_logger:format("~p~p got unexpected message (~p):\n\t~p\n",
+ error_logger:format("~w~w got unexpected message (~w):\n\t~p\n",
[?MODULE, self(), Type, Exit]).
create_window(S) ->
@@ -403,8 +403,6 @@ create_menubar(Frame) ->
wxEvtHandler:connect(Frame,
command_menu_selected,
[{userData, main_window}]),
- wxEvtHandler:connect(File, menu_close),
- wxEvtHandler:connect(Help, menu_close),
MenuBar.
create_app_page(#state{book = Book} = S) ->
@@ -780,15 +778,12 @@ root_popup(S, Root, Tree, Item) ->
wxMenu:appendSeparator(PopupMenu),
wxMenu:append(PopupMenu, 1, "Edit"),
Choices = [edit],
- wxEvtHandler:connect(PopupMenu, command_menu_selected),
- wxEvtHandler:connect(PopupMenu, menu_close),
+ Popup = #root_popup{dir = Root, choices = Choices,
+ tree = Tree, item = Item},
+ wxEvtHandler:connect(PopupMenu, command_menu_selected, [{userData, {popup, Popup}}]),
wxWindow:popupMenu(S#state.frame, PopupMenu),
- Popup = #root_popup{dir = Root,
- choices = Choices,
- tree = Tree,
- item = Item},
- S#state{popup_menu = Popup}.
+ S.
lib_popup(S, Lib, Tree, Item) ->
PopupMenu = wxMenu:new(),
@@ -804,12 +799,10 @@ lib_popup(S, Lib, Tree, Item) ->
wxMenu:append(PopupMenu, 3, "Delete"),
[add, edit, delete]
end,
- wxEvtHandler:connect(PopupMenu, command_menu_selected),
- wxEvtHandler:connect(PopupMenu, menu_close),
- wxWindow:popupMenu(S#state.frame, PopupMenu),
-
Popup = #lib_popup{dir = Lib, choices = Choices, tree = Tree, item = Item},
- S#state{popup_menu = Popup}.
+ wxEvtHandler:connect(PopupMenu, command_menu_selected, [{userData, {popup, Popup}}]),
+ wxWindow:popupMenu(S#state.frame, PopupMenu),
+ S.
escript_popup(S, File, Tree, Item) ->
PopupMenu = wxMenu:new(),
@@ -825,15 +818,11 @@ escript_popup(S, File, Tree, Item) ->
wxMenu:append(PopupMenu, 3, "Delete"),
[add, edit, delete]
end,
- wxEvtHandler:connect(PopupMenu, command_menu_selected),
- wxEvtHandler:connect(PopupMenu, menu_close),
+ Popup = #escript_popup{file = File, choices = Choices,
+ tree = Tree, item = Item},
+ wxEvtHandler:connect(PopupMenu, command_menu_selected, [{userData, {popup, Popup}}]),
wxWindow:popupMenu(S#state.frame, PopupMenu),
-
- Popup = #escript_popup{file = File,
- choices = Choices,
- tree = Tree,
- item = Item},
- S#state{popup_menu = Popup}.
+ S.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -903,11 +892,13 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} =
wxMessageDialog:showModal(MD),
wxMessageDialog:destroy(MD),
S;
- #wxMenu{type = menu_close} ->
- S#state{popup_menu = undefined};
- #wxCommand{type = command_menu_selected = Type, cmdString = Str}
- when S#state.popup_menu =/= undefined ->
- handle_popup_event(S, Type, Id, ObjRef, UserData, Str);
+ #wxCommand{type = command_menu_selected = Type, cmdString = Str} ->
+ case UserData of
+ {popup, Popup} ->
+ handle_popup_event(S, Type, Id, ObjRef, Popup, Str);
+ true ->
+ S
+ end;
#wxMouse{type = enter_window} ->
%% The following is commented out because it raises the
%% main system window on top of popup windows.
@@ -1028,11 +1019,9 @@ warning_popup_position(#state{frame=MF,warning_list=WL},{WFW,WFH}) ->
{X,Y}.
handle_popup_event(S, _Type, 0, _ObjRef, _UserData, _Str) ->
- S#state{popup_menu = undefined};
-handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir,
- choices = Choices},
- sys = Sys} = S,
- _Type, Pos, _ObjRef, _UserData, _Str) ->
+ S;
+handle_popup_event(#state{sys = Sys} = S, _Type, Pos, _ObjRef,
+ #root_popup{dir = OldDir, choices = Choices}, _Str) ->
case lists:nth(Pos, Choices) of
edit ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
@@ -1042,18 +1031,16 @@ handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir,
Style) of
{ok, NewDir} when NewDir =:= OldDir ->
%% Same dir.Ignore.
- S#state{popup_menu = undefined};
+ S;
{ok, NewDir} ->
Sys2 = Sys#sys{root_dir = NewDir},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2});
+ do_set_sys(S#state{sys = Sys2});
cancel ->
- S#state{popup_menu = undefined}
+ S
end
end;
-handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir,
- choices = Choices},
- sys = Sys} = S,
- _Type, Pos, _ObjRef, _UserData, _Str) ->
+handle_popup_event(#state{sys = Sys} = S, _Type, Pos, _ObjRef,
+ #lib_popup{dir = OldDir, choices = Choices}, _Str) ->
case lists:nth(Pos, Choices) of
add ->
{ok, Cwd} = file:get_cwd(),
@@ -1063,15 +1050,14 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir,
case lists:member(NewDir, Sys#sys.lib_dirs) of
true ->
%% Ignore duplicate. Keep old.
- S#state{popup_menu = undefined};
+ S;
false ->
LibDirs = Sys#sys.lib_dirs ++ [NewDir],
Sys2 = Sys#sys{lib_dirs = LibDirs},
- do_set_sys(S#state{popup_menu = undefined,
- sys = Sys2})
+ do_set_sys(S#state{sys = Sys2})
end;
cancel ->
- S#state{popup_menu = undefined}
+ S
end;
edit ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
@@ -1083,28 +1069,25 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir,
case lists:member(NewDir, Sys#sys.lib_dirs) of
true ->
%% Ignore duplicate. Keep old.
- S#state{popup_menu = undefined};
+ S;
false ->
Pred = fun(E) -> E =/= OldDir end,
{Before, [_| After]} =
lists:splitwith(Pred, Sys#sys.lib_dirs),
LibDirs2 = Before ++ [NewDir | After],
Sys2 = Sys#sys{lib_dirs = LibDirs2},
- do_set_sys(S#state{popup_menu = undefined,
- sys = Sys2})
+ do_set_sys(S#state{sys = Sys2})
end;
cancel ->
- S#state{popup_menu = undefined}
+ S
end;
delete ->
LibDirs = Sys#sys.lib_dirs -- [OldDir],
Sys2 = Sys#sys{lib_dirs = LibDirs},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{sys = Sys2})
end;
-handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile,
- choices = Choices},
- sys = Sys} = S,
- _Type, Pos, _ObjRef, _UserData, _Str) ->
+handle_popup_event(#state{sys = Sys} = S, _Type, Pos, _ObjRef,
+ #escript_popup{file = OldFile, choices = Choices}, _Str) ->
case lists:nth(Pos, Choices) of
add ->
OldFile2 =
@@ -1124,14 +1107,14 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile,
case lists:member(NewFile, Sys#sys.escripts) of
true ->
%% Ignore duplicate. Keep old.
- S#state{popup_menu = undefined};
+ S;
false ->
Escripts = Sys#sys.escripts ++ [NewFile],
Sys2 = Sys#sys{escripts = Escripts},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{sys = Sys2})
end;
cancel ->
- S#state{popup_menu = undefined}
+ S
end;
edit ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
@@ -1143,23 +1126,22 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile,
case lists:member(NewFile, Sys#sys.escripts) of
true ->
%% Ignore duplicate. Keep old.
- S#state{popup_menu = undefined};
+ S;
false ->
Pred = fun(E) -> E =/= OldFile end,
{Before, [_| After]} =
lists:splitwith(Pred, Sys#sys.escripts),
Escripts2 = Before ++ [NewFile | After],
Sys2 = Sys#sys{escripts = Escripts2},
- do_set_sys(S#state{popup_menu = undefined,
- sys = Sys2})
+ do_set_sys(S#state{sys = Sys2})
end;
cancel ->
- S#state{popup_menu = undefined}
+ S
end;
delete ->
Escripts = Sys#sys.escripts -- [OldFile],
Sys2 = Sys#sys{escripts = Escripts},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{sys = Sys2})
end.
handle_system_event(#state{sys = Sys} = S,
@@ -1179,7 +1161,7 @@ handle_system_event(#state{sys = Sys} = S,
Sys2 = Sys#sys{incl_cond = AppCond},
do_set_sys(S#state{sys = Sys2});
handle_system_event(S, Event, ObjRef, UserData) ->
- error_logger:format("~p~p got unexpected wx sys event to ~p "
+ error_logger:format("~w~w got unexpected wx sys event to ~p "
"with user data: ~p\n\t ~p\n",
[?MODULE, self(), ObjRef, UserData, Event]),
S.
@@ -1195,13 +1177,13 @@ handle_source_event(S,
_UserData) ->
case wxTreeCtrl:getItemData(ObjRef, Item) of
#root_data{dir = _Dir} ->
- %% io:format("Root dialog: ~p\n", [Dir]),
+ %% io:format("Root dialog: ~tp\n", [Dir]),
S;
#lib_data{dir = _Dir} ->
- %% io:format("Lib dialog: ~p\n", [Dir]),
+ %% io:format("Lib dialog: ~tp\n", [Dir]),
S;
#escript_data{file = _File} ->
- %% io:format("Escript dialog: ~p\n", [File]),
+ %% io:format("Escript dialog: ~tp\n", [File]),
S;
#app_data{name = Name} ->
do_open_app(S, Name);
@@ -1221,7 +1203,7 @@ handle_source_event(S,
#escript_data{file = File} ->
wx:batch(fun() -> escript_popup(S, File, Tree, Item) end);
#app_data{name = Name} ->
- io:format("App menu: ~p\n", [Name]),
+ io:format("App menu: ~tp\n", [Name]),
S;
undefined ->
S
@@ -1241,7 +1223,7 @@ handle_app_event(S,
Items = reltool_utils:get_items(ListCtrl),
handle_app_button(S, Items, Action);
handle_app_event(S, Event, ObjRef, UserData) ->
- error_logger:format("~p~p got unexpected wx app event to "
+ error_logger:format("~w~w got unexpected wx app event to "
"~p with user data: ~p\n\t ~p\n",
[?MODULE, self(), ObjRef, UserData, Event]),
S.
@@ -1285,7 +1267,7 @@ move_app(S, {_ItemNo, AppBase}, Action) ->
blacklist_del ->
undefined;
_ ->
- error_logger:format("~p~p got unexpected app "
+ error_logger:format("~w~w got unexpected app "
"button event: ~p ~p\n",
[?MODULE, self(), Action, AppBase]),
OldApp#app.incl_cond
diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl
index c39ed0ecd5..9cda5dabd3 100644
--- a/lib/reltool/src/reltool_target.erl
+++ b/lib/reltool/src/reltool_target.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -296,7 +296,7 @@ do_gen_rel(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps},
{ErtsName, Erts#app.vsn},
[strip_rel_info(App, RelApps) || App <- MergedApps]};
false ->
- reltool_utils:throw_error("Mandatory application ~p is "
+ reltool_utils:throw_error("Mandatory application ~w is "
"not included",
[ErtsName])
end.
@@ -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
@@ -379,8 +383,8 @@ merge_app(RelName,
[] ->
App#app{app_type = Type2, info = Info#app_info{incl_apps = InclApps}};
BadIncl ->
- reltool_utils:throw_error("~p: These applications are "
- "used by release ~s but are "
+ reltool_utils:throw_error("~w: These applications are "
+ "used by release ~ts but are "
"missing as included_applications "
"in the app file: ~p",
[Name, RelName, BadIncl])
@@ -478,33 +482,62 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn},
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) ->
+load_app_mods(#app{mods = Mods0} = App, Mand, PathFlag, Variables) ->
Path = cr_path(App, PathFlag, Variables),
- PartNames =
- lists:sort([{packages:split(M),M} ||
- #mod{name = M, is_included=true} <- Mods,
- not lists:member(M, Mand)]),
- SplitMods =
- lists:foldl(
- fun({Parts,M}, [{Last, Acc}|Rest]) ->
- [_|Tail] = lists:reverse(Parts),
- case lists:reverse(Tail) of
- Subs when Subs == Last ->
- [{Last,[M|Acc]}|Rest];
- Subs ->
- [{Subs, [M]}|[{Last,Acc}|Rest]]
- end
- end,
- [{[],
- []}],
- PartNames),
- lists:foldl(
- fun({Subs,Ms}, Cmds) ->
- [{path, [filename:join([Path | Subs])]},
- {primLoad, lists:sort(Ms)} | Cmds]
- end,
- [],
- SplitMods).
+ Mods = [M || #mod{name = M, is_included=true} <- Mods0,
+ not lists:member(M, Mand)],
+ [{path, [filename:join([Path])]},
+ {primLoad, lists:sort(Mods)}].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 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})
@@ -832,7 +865,7 @@ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) ->
case File of
"erts" ->
reltool_utils:throw_error("This system is not installed. "
- "The directory ~s is missing.",
+ "The directory ~ts is missing.",
[Erts#app.label]);
_ when File =:= Erts#app.label ->
replace_dyn_erl(Relocatable, Spec);
@@ -954,7 +987,7 @@ check_sys(Mandatory, SysFiles) ->
do_check_sys(Prefix, Specs) ->
case lookup_spec(Prefix, Specs) of
[] ->
- reltool_utils:throw_error("Mandatory system directory ~s "
+ reltool_utils:throw_error("Mandatory system directory ~ts "
"is not included",
[Prefix]);
_ ->
@@ -975,8 +1008,8 @@ lookup_spec(Prefix, Specs) ->
safe_lookup_spec(Prefix, Specs) ->
case lookup_spec(Prefix, Specs) of
[] ->
- %% io:format("lookup fail ~s:\n\t~p\n", [Prefix, Specs]),
- reltool_utils:throw_error("Mandatory system file ~s is "
+ %% io:format("lookup fail ~ts:\n\t~p\n", [Prefix, Specs]),
+ reltool_utils:throw_error("Mandatory system file ~ts is "
"not included", [Prefix]);
Match ->
Match
@@ -1020,7 +1053,7 @@ spec_lib_files(#sys{root_dir = RootDir,
check_apps([Mandatory | Names], Apps) ->
case lists:keymember(Mandatory, #app.name, Apps) of
false ->
- reltool_utils:throw_error("Mandatory application ~p is "
+ reltool_utils:throw_error("Mandatory application ~w is "
"not included in ~p",
[Mandatory, Apps]);
true ->
@@ -1111,13 +1144,13 @@ spec_dir(Dir) ->
Base,
[spec_dir(filename:join([Dir, F])) || F <- Files]};
error ->
- reltool_utils:throw_error("list dir ~s failed", [Dir])
+ reltool_utils:throw_error("list dir ~ts failed", [Dir])
end;
{ok, #file_info{type = regular}} ->
%% Plain file
{copy_file, Base};
_ ->
- reltool_utils:throw_error("read file info ~s failed", [Dir])
+ reltool_utils:throw_error("read file info ~ts failed", [Dir])
end.
spec_mod(Mod, DebugInfo) ->
@@ -1251,7 +1284,7 @@ do_eval_spec({archive, Archive, Options, Files},
{ok, _} ->
ok;
{error, Reason} ->
- reltool_utils:throw_error("create archive ~s failed: ~p",
+ reltool_utils:throw_error("create archive ~ts failed: ~p",
[ArchiveFile, Reason])
end;
do_eval_spec({copy_file, File}, _OrigSourceDir, SourceDir, TargetDir) ->
@@ -1420,12 +1453,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"]),
@@ -1442,9 +1473,18 @@ do_install(RelName, TargetDir) ->
ok = release_handler:create_RELEASES(TargetDir2, RelFile),
ok;
_ ->
- reltool_utils:throw_error("~s: Illegal data file syntax", [DataFile])
+ reltool_utils:throw_error("~ts: 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/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl
index 6149d6ef06..9af8f6bae8 100644
--- a/lib/reltool/src/reltool_utils.erl
+++ b/lib/reltool/src/reltool_utils.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -106,7 +106,7 @@ normalize_dir([], Path) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
prim_consult(Bin) when is_binary(Bin) ->
- case erl_scan:string(binary_to_list(Bin)) of
+ case erl_scan:string(unicode:characters_to_list(Bin,encoding(Bin))) of
{ok, Tokens, _EndLine} ->
prim_parse(Tokens, []);
{error, {_ErrorLine, Module, Reason}, _EndLine} ->
@@ -120,6 +120,14 @@ prim_consult(FullName) when is_list(FullName) ->
{error, file:format_error(enoent)}
end.
+encoding(Bin) when is_binary(Bin) ->
+ case epp:read_encoding_from_binary(Bin) of
+ none ->
+ epp:default_encoding();
+ E ->
+ E
+ end.
+
prim_parse(Tokens, Acc) ->
case lists:splitwith(fun(T) -> element(1,T) =/= dot end, Tokens) of
{[], []} ->
@@ -423,7 +431,7 @@ scroll_size(ObjRef) ->
safe_keysearch(Key, Pos, List, Mod, Line) ->
case lists:keysearch(Key, Pos, List) of
false ->
- io:format("~p(~p): lists:keysearch(~p, ~p, ~p) -> false\n",
+ io:format("~w(~w): lists:keysearch(~p, ~w, ~p) -> false\n",
[Mod, Line, Key, Pos, List]),
erlang:error({Mod, Line, lists, keysearch, [Key, Pos, List]});
{value, Val} ->
@@ -455,7 +463,7 @@ create_dir(Dir) ->
ok;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("create dir ~s: ~s", [Dir, Text])
+ throw_error("create dir ~ts: ~ts", [Dir, Text])
end.
list_dir(Dir) ->
@@ -464,7 +472,7 @@ list_dir(Dir) ->
Files;
error ->
Text = file:format_error(enoent),
- throw_error("list dir ~s: ~s", [Dir, Text])
+ throw_error("list dir ~ts: ~ts", [Dir, Text])
end.
read_file_info(File) ->
@@ -473,7 +481,7 @@ read_file_info(File) ->
Info;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("read file info ~s: ~s", [File, Text])
+ throw_error("read file info ~ts: ~ts", [File, Text])
end.
write_file_info(File, Info) ->
@@ -482,7 +490,7 @@ write_file_info(File, Info) ->
ok;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("write file info ~s: ~s", [File, Text])
+ throw_error("write file info ~ts: ~ts", [File, Text])
end.
read_file(File) ->
@@ -491,7 +499,7 @@ read_file(File) ->
Bin;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("read file ~s: ~s", [File, Text])
+ throw_error("read file ~ts: ~ts", [File, Text])
end.
write_file(File, IoList) ->
@@ -500,7 +508,7 @@ write_file(File, IoList) ->
ok;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("write file ~s: ~s", [File, Text])
+ throw_error("write file ~ts: ~ts", [File, Text])
end.
recursive_delete(Dir) ->
@@ -516,7 +524,7 @@ recursive_delete(Dir) ->
ok;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("delete file ~s: ~s\n", [Dir, Text])
+ throw_error("delete file ~ts: ~ts\n", [Dir, Text])
end;
false ->
delete(Dir, regular)
@@ -530,7 +538,7 @@ delete(File, Type) ->
ok;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("delete file ~s: ~s\n", [File, Text])
+ throw_error("delete file ~ts: ~ts\n", [File, Text])
end.
do_delete(File, regular) ->
@@ -564,16 +572,16 @@ copy_file(From, To) ->
FromMode = FromInfo#file_info.mode,
ToMode = ToInfo#file_info.mode,
ToMode2 = FromMode bor ToMode,
- FileInfo = FromInfo#file_info{mode = ToMode2},
+ FileInfo = ToInfo#file_info{mode = ToMode2},
write_file_info(To, FileInfo),
ok;
{error, Reason} ->
Text = file:format_error(Reason),
- throw_error("copy file ~s -> ~s: ~s\n", [From, To, Text])
+ throw_error("copy file ~ts -> ~ts: ~ts\n", [From, To, Text])
end;
error ->
Text = file:format_error(enoent),
- throw_error("copy file ~s -> ~s: ~s\n", [From, To, Text])
+ throw_error("copy file ~ts -> ~ts: ~ts\n", [From, To, Text])
end.
throw_error(Format, Args) ->
@@ -586,13 +594,10 @@ decode_regexps(Key, {add, Regexps}, Old) when is_list(Regexps) ->
decode_regexps(_Key, {del, Regexps}, Old) when is_list(Regexps) ->
[Re || Re <- Old, not lists:member(Re#regexp.source, Regexps)];
decode_regexps(Key, Regexps, _Old) when is_list(Regexps) ->
- do_decode_regexps(Key, Regexps, []);
-decode_regexps(Key, Regexps, _Old) when is_list(Regexps) ->
- Text = lists:flatten(io_lib:format("~p", [{Key, Regexps}])),
- throw({error, "Illegal option: " ++ Text}).
+ do_decode_regexps(Key, Regexps, []).
do_decode_regexps(Key, [Regexp | Regexps], Acc) ->
- case catch re:compile(Regexp, []) of
+ case catch re:compile(Regexp, [unicode]) of
{ok, MP} ->
do_decode_regexps(Key,
Regexps,
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index f29f6049a5..752037042d 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -1,7 +1,8 @@
+%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -27,6 +28,7 @@
-include_lib("reltool/src/reltool.hrl").
-include("reltool_test_lib.hrl").
-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/file.hrl").
-define(NODE_NAME, '__RELTOOL__TEMPORARY_TEST__NODE__').
-define(WORK_DIR, "reltool_work_dir").
@@ -35,17 +37,63 @@
%% Initialization functions.
init_per_suite(Config) ->
+ {ok,Cwd} = file:get_cwd(),
?ignore(file:make_dir(?WORK_DIR)),
- reltool_test_lib:init_per_suite(Config).
+ [{cwd,Cwd}|reltool_test_lib:init_per_suite(Config)].
end_per_suite(Config) ->
reltool_test_lib:end_per_suite(Config).
init_per_testcase(Func,Config) ->
+ Node = full_node_name(?NODE_NAME),
+ case net_adm:ping(Node) of
+ pong -> stop_node(Node);
+ pang -> ok
+ end,
reltool_test_lib:init_per_testcase(Func,Config).
-end_per_testcase(Func,Config) ->
+end_per_testcase(Func,Config) ->
+ ok = file:set_cwd(filename:join(?config(cwd,Config),?WORK_DIR)),
+ {ok,All} = file:list_dir("."),
+ Files = [F || F <- All, false == lists:prefix("save.",F)],
+ case ?config(tc_status,Config) of
+ ok ->
+ ok;
+ _Fail ->
+ SaveDir = "save."++atom_to_list(Func),
+ ok = file:make_dir(SaveDir),
+ save_test_result(Files,SaveDir)
+ end,
+ rm_files(Files),
+ ok = file:set_cwd(?config(cwd,Config)),
reltool_test_lib:end_per_testcase(Func,Config).
+
+save_test_result(Files,DestDir) ->
+ Tar = "copy.tar",
+ ok = erl_tar:create(Tar, Files),
+ ok = erl_tar:extract(Tar, [{cwd,DestDir}]),
+ ok = file:delete(Tar),
+ ok.
+
+rm_files([F | Fs]) ->
+ case file:read_file_info(F) of
+ {ok,#file_info{type=directory}} ->
+ rm_dir(F);
+ {ok,_Regular} ->
+ ok = file:delete(F)
+ end,
+ rm_files(Fs);
+rm_files([]) ->
+ ok.
+
+rm_dir(Dir) ->
+ {ok,Files} = file:list_dir(Dir),
+ rm_files([filename:join(Dir, F) || F <- Files]),
+ ok = file:del_dir(Dir).
+
+
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% SUITE specification
@@ -60,6 +108,7 @@ all() ->
create_script,
create_script_sort,
create_target,
+ create_target_unicode,
create_embedded,
create_standalone,
create_standalone_beam,
@@ -73,6 +122,8 @@ all() ->
otp_9229_dupl_mod_exclude_app,
otp_9229_dupl_mod_exclude_mod,
dupl_mod_in_app_file,
+ include_non_existing_app,
+ exclude_non_existing_app,
get_apps,
get_mod,
get_sys,
@@ -90,8 +141,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() ->
[].
@@ -106,6 +159,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) ->
@@ -298,7 +360,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
@@ -307,11 +368,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]
@@ -326,11 +388,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}]},
@@ -372,7 +435,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, _},
@@ -389,13 +451,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},
@@ -407,7 +485,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,_},
@@ -417,6 +494,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.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -460,7 +548,7 @@ create_script(_Config) ->
%% ?m(OrigScript2, Script2),
?m(equal, diff_script(OrigScript, Script)),
-
+
%% Stop server
?m(ok, reltool:stop(Pid)),
ok.
@@ -477,12 +565,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,
[
@@ -493,10 +585,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}]},
@@ -553,8 +646,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),
@@ -569,6 +662,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]))),
@@ -584,7 +681,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},
@@ -595,6 +696,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]),
@@ -626,26 +735,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.
@@ -683,7 +797,73 @@ create_target(_Config) ->
Erl = filename:join([TargetDir, "bin", "erl"]),
{ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
?msym(ok, stop_node(Node)),
-
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate target system
+
+create_target_unicode(Config) ->
+ DataDir = ?config(data_dir,Config),
+
+ %% If file name translation mode is unicode, then use unicode
+ %% characters release name (which will be used as file name for
+ %% .rel, .script and .boot)
+ RelNamePrefix =
+ case file:native_name_encoding() of
+ utf8 ->
+ "Unicode test αβ";
+ latin1 ->
+ "Unicode test"
+ end,
+
+ %% Configure the server
+ RelName1 = RelNamePrefix,
+ RelName2 = RelNamePrefix ++ " with SASL",
+ RelVsn = "1.0",
+ Sys =
+ {sys,
+ [
+ {root_dir, code:root_dir()},
+ {lib_dirs, [filename:join(DataDir,"unicode")]},
+ {app_file, all},
+ {incl_cond,exclude},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel, ua]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel, ua]},
+ {app, kernel, [{incl_cond, include}]},
+ {app, stdlib, [{incl_cond, include}]},
+ {app, sasl, [{incl_cond, include}]},
+ {app, ua, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = filename:join([?WORK_DIR, "target_unicode"]),
+ ?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)),
+
+ %% Start a node
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+
+
+ %% The ua application has a unicode string as description - check
+ %% that it is translated correctly.
+ wait_for_app(Node,ua,50),
+ Apps = rpc:call(Node,application,which_applications,[]),
+ ?m({ua,"Application for testing unicode in reltool - αβ","1.0"},
+ lists:keyfind(ua,1,Apps)),
+
+ %% Check that the release name is correct (really only
+ %% insteresting if file name translation mode is utf8)
+ [{RelName,_,_,_}] =
+ ?msym([{_,_,_,_}],rpc:call(Node,release_handler,which_releases,[])),
+ ?m(true,lists:prefix(RelNamePrefix,RelName)),
+
+ ?msym(ok, stop_node(Node)),
+
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -747,11 +927,11 @@ create_standalone(_Config) ->
?msym(ok, stop_node(Node)),
%% Execute escript
- Expected = iolist_to_binary(["Root dir: ", RootDir, "\n"
- "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
- "Smp: false\n",
- "ExitCode:0"]),
- io:format("Expected: ~s\n", [Expected]),
+ Expected = s2b(["Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "Emuarg: [\"emuvalue\"]\n",
+ "ExitCode:0"]),
+ io:format("Expected: ~ts\n", [Expected]),
?m(Expected, run(BinDir, EscriptName, "-arg1 arg2 arg3")),
ok.
@@ -794,10 +974,11 @@ create_standalone_beam(Config) ->
?msym(ok, stop_node(Node)),
%% Execute escript
- Expected = iolist_to_binary(["Root dir: ", RootDir, "\n"
- "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
- "ExitCode:0"]),
- io:format("Expected: ~s\n", [Expected]),
+ Expected = s2b(["Module: mymod\n"
+ "Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "ExitCode:0"]),
+ io:format("Expected: ~ts\n", [Expected]),
?m(Expected, run(BinDir, EscriptName, "-arg1 arg2 arg3")),
ok.
@@ -846,10 +1027,11 @@ create_standalone_app(Config) ->
?msym(ok, stop_node(Node)),
%% Execute escript
- Expected = iolist_to_binary(["Root dir: ", RootDir, "\n"
- "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
- "ExitCode:0"]),
- io:format("Expected: ~s\n", [Expected]),
+ Expected = s2b(["Module: mymod\n"
+ "Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "ExitCode:0"]),
+ io:format("Expected: ~ts\n", [Expected]),
?m(Expected, run(BinDir, EscriptName, "-arg1 arg2 arg3")),
ok.
@@ -932,27 +1114,26 @@ create_multiple_standalone(Config) ->
?msym(ok, stop_node(Node)),
%% Execute escript1
- Expected1 = iolist_to_binary(["Root dir: ", RootDir, "\n"
- "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
- "Smp: false\n",
- "ExitCode:0"]),
- io:format("Expected1: ~s\n", [Expected1]),
+ Expected1 = s2b(["Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "Emuarg: [\"emuvalue\"]\n",
+ "ExitCode:0"]),
+ io:format("Expected1: ~ts\n", [Expected1]),
?m(Expected1, run(BinDir, EscriptName1, "-arg1 arg2 arg3")),
%% Execute escript2
- Expected2 = iolist_to_binary(["Root dir: ", RootDir, "\n"
- "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
- "ExitCode:0"]),
- io:format("Expected2: ~s\n", [Expected2]),
+ Expected2 = s2b(["Module: mymod\n"
+ "Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "ExitCode:0"]),
+ io:format("Expected2: ~ts\n", [Expected2]),
?m(Expected2, run(BinDir, EscriptName2, "-arg1 arg2 arg3")),
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generate old type of target system
-
-create_old_target(_Config) -> {skip, "Old style of target"};
create_old_target(_Config) ->
%% Configure the server
@@ -975,8 +1156,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"]),
@@ -1024,11 +1204,17 @@ create_slim(Config) ->
RootDir = code:root_dir(),
Erl = filename:join([RootDir, "bin", "erl"]),
- Args = "-boot_var RELTOOL_EXT_LIB " ++ TargetLibDir ++
- " -boot " ++ filename:join(TargetRelVsnDir,RelName) ++
- " -sasl releases_dir \\\"" ++ TargetRelDir ++ "\\\"",
+ 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, [])),
+ wait_for_app(Node,sasl,50),
?msym([{RelName,RelVsn,_,permanent}],
rpc:call(Node,release_handler,which_releases,[])),
?msym(ok, stop_node(Node)),
@@ -1171,7 +1357,6 @@ otp_9229_dupl_mod_exclude_mod(Config) ->
ok.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test that if a module is duplicated in a .app file, then a warning
%% is produced, but target can still be created.
@@ -1204,6 +1389,56 @@ dupl_mod_in_app_file(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test that a reasonable error message is returned if an application
+%% is missing
+include_non_existing_app(_Config) ->
+ %% Configure the server
+ Sys =
+ {sys,
+ [
+ {incl_cond,exclude},
+ {app,foobar,[{incl_cond,include}]},
+ {app,kernel,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = filename:join([?WORK_DIR, "target_include_non_existing_app"]),
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]),
+ ?m({error,"foobar: Missing application directory."},
+ reltool:get_status([{config, Sys}])),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test that if a missing application is explicitly excluded a warning
+%% should be issued.
+exclude_non_existing_app(_Config) ->
+ %% Configure the server
+ Sys =
+ {sys,
+ [
+ {incl_cond,exclude},
+ {app,foobar,[{incl_cond,exclude}]},
+ {app,kernel,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = filename:join([?WORK_DIR, "target_exclude_non_existing_app"]),
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]),
+ ?m({ok,["foobar: Missing application directory."]},
+ reltool:get_status([{config, Sys}])),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test the interface used by the GUI:
%% get_app
%% get_apps
@@ -1942,7 +2177,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
%%
@@ -2072,6 +2307,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"),
@@ -2196,6 +2472,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.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2278,14 +2587,16 @@ mod_path(Node,Mod) ->
start_node(Name, ErlPath) ->
start_node(Name, ErlPath, []).
-start_node(Name, ErlPath, Args) ->
+start_node(Name, ErlPath, Args0) ->
FullName = full_node_name(Name),
- CmdLine = mk_node_cmdline(Name, ErlPath, Args),
- 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: ~ts~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),
+ %% no need to close port since node is detached (see
+ %% mk_node_args) so port will be closed anyway.
case ping_node(FullName, 50) of
ok -> {ok, FullName};
Other -> exit({failed_to_start_node, FullName, Other})
@@ -2295,27 +2606,35 @@ start_node(Name, ErlPath, Args) ->
end.
stop_node(Node) ->
- monitor_node(Node, true),
- spawn(Node, fun () -> halt() end),
- receive {nodedown, Node} -> ok end.
+ rpc:call(Node,erlang,halt,[]),
+ wait_for_node_down(Node,50).
+
+wait_for_node_down(Node,0) ->
+ test_server:fail({cant_terminate_node,Node});
+wait_for_node_down(Node,N) ->
+ case net_adm:ping(Node) of
+ pong ->
+ timer:sleep(1000),
+ wait_for_node_down(Node,N-1);
+ pang ->
+ ok
+ end.
-mk_node_cmdline(Name, Prog, Args) ->
- 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())
- ++ " " ++ Args.
+ ["-detached",
+ 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,
@@ -2346,6 +2665,22 @@ wait_for_process(Node, Name, N) when is_integer(N), N > 0 ->
ok
end.
+wait_for_app(_Node, Name, 0) ->
+ {error, Name};
+wait_for_app(Node, Name, N) when is_integer(N), N > 0 ->
+ case rpc:call(Node,application,which_applications,[]) of
+ {badrpc,Reason} ->
+ test_server:fail({failed_to_get_applications,Reason});
+ Apps ->
+ case lists:member(Name,Apps) of
+ false ->
+ timer:sleep(1000),
+ wait_for_app(Node, Name, N-1);
+ true ->
+ ok
+ end
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Run escript
@@ -2374,7 +2709,7 @@ do_run(Dir, Cmd) ->
Res = get_data(Port, []),
receive
{Port,{exit_status,ExitCode}} ->
- iolist_to_binary([Res,"ExitCode:"++integer_to_list(ExitCode)])
+ s2b([Res,"ExitCode:"++integer_to_list(ExitCode)])
end.
get_data(Port, SoFar) ->
@@ -2398,3 +2733,9 @@ expected_output([], _) ->
[];
expected_output(Bin, _) when is_binary(Bin) ->
Bin.
+
+%% Convert the given list to a binary with the same encoding as the
+%% file name translation mode
+s2b(List) ->
+ Enc = file:native_name_encoding(),
+ unicode:characters_to_binary(List,Enc,Enc).
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/escript/someapp-1.0/src/mymod.erl b/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl
index b6c71c666d..c315f926d3 100644
--- a/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl
+++ b/lib/reltool/test/reltool_server_SUITE_data/escript/someapp-1.0/src/mymod.erl
@@ -22,5 +22,6 @@
%%%-----------------------------------------------------------------
%%% escript main function
main(Args) ->
+ io:format("Module: ~w\n", [?MODULE]),
io:format("Root dir: ~s\n", [code:root_dir()]),
io:format("Script args: ~p\n", [Args]).
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/unicode/ua-1.0/ebin/ua.app b/lib/reltool/test/reltool_server_SUITE_data/unicode/ua-1.0/ebin/ua.app
new file mode 100644
index 0000000000..6f571b7179
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/unicode/ua-1.0/ebin/ua.app
@@ -0,0 +1,7 @@
+% -*- coding: utf-8 -*-
+{application, ua,
+ [{description, "Application for testing unicode in reltool - αβ"},
+ {vsn, "1.0"},
+ {modules,[]},
+ {registered, []},
+ {applications, [kernel, stdlib]}]}.
diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl
index 61f783190c..3485365ed9 100644
--- a/lib/reltool/test/reltool_test_lib.erl
+++ b/lib/reltool/test/reltool_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2013. 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
@@ -25,7 +25,7 @@
init_per_suite(Config) when is_list(Config)->
global:register_name(reltool_global_logger, group_leader()),
- incr_timetrap(Config, 5).
+ incr_timetrap(Config, 10).
end_per_suite(Config) when is_list(Config)->
global:unregister_name(reltool_global_logger),
@@ -51,7 +51,7 @@ set_kill_timer(Config) ->
Time =
case lookup_config(tc_timeout, Config) of
[] ->
- timer:minutes(5);
+ timer:minutes(10);
ConfigTime when is_integer(ConfigTime) ->
ConfigTime
end,
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 6872539b8c..412e78f49f 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.6.1
+RELTOOL_VSN = 0.6.4