diff options
8 files changed, 163 insertions, 16 deletions
diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml index d7d7e12566..fbe29753be 100644 --- a/lib/reltool/doc/src/reltool.xml +++ b/lib/reltool/doc/src/reltool.xml @@ -51,8 +51,18 @@ defines library directories where additional applications may reside and it defaults to the directories listed by the operating system environment variable - <c>ERL_LIBS</c>. See the module <c>code</c> for more info. - Finally single modules and entire applications may be read from + <c>ERL_LIBS</c>. See the module <c>code</c> for more info.</p> + + <p>An application directory <c>AppDir</c> under a library + directory is recognized by the existence of an <c>AppDir/ebin</c> + directory. If this does not exist, <c>reltool</c> will not + consider <c>AppDir</c> at all when looking for applications.</p> + + <p>It is recommended that application directories are named as the + application, possibly followed by a dash and the version + number. For example <c>myapp</c> or <c>myapp-1.1</c>.</p> + + <p>Finally single modules and entire applications may be read from Escripts.</p> <p>Some configuration parameters control the behavior of Reltool @@ -372,6 +382,11 @@ <p>This parameter is mutual exclusive with <c>lib_dir</c>. If <c>vsn</c> and <c>lib_dir</c> are both omitted, the latest version will be chosen.</p> + <p>Note that in order for reltool to sort application versions + and thereby be able to select the latest, it is required that + the version id for the application consits of integers and + dots only, for example <c>1</c>, <c>2.0</c> or + <c>3.17.1</c>.</p> </item> <tag><c>lib_dir</c></tag> <item> @@ -383,6 +398,11 @@ <p>This parameter is mutual exclusive with <c>vsn</c>. If <c>vsn</c> and <c>lib_dir</c> are both omitted, the latest version will be chosen.</p> + <p>Note that in order for reltool to sort application versions + and thereby be able to select the latest, it is required that + the version id for the application consits of integers and + dots only, for example <c>1</c>, <c>2.0</c> or + <c>3.17.1</c>.</p> </item> <tag><c>mod</c></tag> <item> 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/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl index 3b5b2ff81c..c56e29152d 100644 --- a/lib/reltool/src/reltool_server.erl +++ b/lib/reltool/src/reltool_server.erl @@ -984,7 +984,7 @@ refresh_app(#app{name = AppName, %% Add info from .app file Base = get_base(AppName, ActiveDir), - {_, DefaultVsn} = reltool_utils:split_app_name(Base), + DefaultVsn = get_vsn_from_dir(AppName,Base), Ebin = filename:join([ActiveDir, "ebin"]), AppFile = filename:join([Ebin, @@ -1685,8 +1685,7 @@ app_dirs2([Lib | Libs], Acc) -> EbinDir = filename:join([AppDir, "ebin"]), case filelib:is_dir(EbinDir, erl_prim_loader) of true -> - {Name, _Vsn} = - reltool_utils:split_app_name(Base), + Name = find_app_name(Base,EbinDir), case Name of erts -> false; _ -> {true, {Name, AppDir}} @@ -1704,17 +1703,74 @@ app_dirs2([Lib | Libs], Acc) -> app_dirs2([], Acc) -> lists:sort(lists:append(Acc)). +find_app_name(Base,EbinDir) -> + {ok,EbinFiles} = erl_prim_loader:list_dir(EbinDir), + AppFile = + case [F || F <- EbinFiles, filename:extension(F)=:=".app"] of + [AF] -> + AF; + _ -> + undefined + end, + find_app_name1(Base,AppFile). + +find_app_name1(Base,undefined) -> + {Name,_} = reltool_utils:split_app_name(Base), + Name; +find_app_name1(_Base,AppFile) -> + list_to_atom(filename:rootname(AppFile)). + +get_vsn_from_dir(AppName,Base) -> + Prefix = atom_to_list(AppName) ++ "-", + case lists:prefix(Prefix,Base) of + true -> + lists:nthtail(length(Prefix),Base); + false -> + "" + end. + + escripts_to_apps([Escript | Escripts], Apps, Status) -> {EscriptAppName, _Label} = split_escript_name(Escript), Ext = code:objfile_extension(), + + %% First find all .app files and associate the app name to the app + %% label - this is in order to now which application a module + %% belongs to in the next round. + AppFun = fun(FullName, _GetInfo, _GetBin, AppFiles) -> + Components = filename:split(FullName), + case Components of + [AppLabel, "ebin", File] -> + case filename:extension(File) of + ".app" -> + [{AppLabel,File}|AppFiles]; + _ -> + AppFiles + end; + _ -> + AppFiles + end + end, + AppFiles = + case reltool_utils:escript_foldl(AppFun, [], Escript) of + {ok, AF} -> + AF; + {error, Reason1} -> + reltool_utils:throw_error("Illegal escript ~p: ~p", + [Escript,Reason1]) + end, + + %% Next, traverse all files... Fun = fun(FullName, _GetInfo, GetBin, {FileAcc, StatusAcc}) -> Components = filename:split(FullName), case Components of [AppLabel, "ebin", File] -> case filename:extension(File) of ".app" -> - {AppName, DefaultVsn} = - reltool_utils:split_app_name(AppLabel), + AppName = + list_to_atom(filename:rootname(File)), + DefaultVsn = + get_vsn_from_dir(AppName,AppLabel), AppFileName = filename:join([Escript, FullName]), {Info, StatusAcc2} = @@ -1727,8 +1783,9 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> {[{AppName, app, Dir, Info} | FileAcc], StatusAcc2}; E when E =:= Ext -> - {AppName, _} = - reltool_utils:split_app_name(AppLabel), + AppFile = + proplists:get_value(AppLabel,AppFiles), + AppName = find_app_name1(AppLabel,AppFile), Mod = init_mod(AppName, File, {File, GetBin()}, @@ -1765,6 +1822,7 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> {FileAcc, StatusAcc} end end, + case reltool_utils:escript_foldl(Fun, {[], Status}, Escript) of {ok, {Files, Status2}} -> EscriptApp = @@ -1779,8 +1837,9 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> Apps, Status2), escripts_to_apps(Escripts, Apps2, Status3); - {error, Reason} -> - reltool_utils:throw_error("Illegal escript ~p: ~p", [Escript,Reason]) + {error, Reason2} -> + reltool_utils:throw_error("Illegal escript ~p: ~p", + [Escript,Reason2]) end; escripts_to_apps([], Apps, Status) -> {Apps, Status}. @@ -1939,7 +1998,7 @@ ensure_app_info(#app{name = Name, fun(Dir, StatusAcc) -> Base = get_base(Name, Dir), Ebin = filename:join([Dir, "ebin"]), - {_, DefaultVsn} = reltool_utils:split_app_name(Base), + DefaultVsn = get_vsn_from_dir(Name,Base), AppFile = filename:join([Ebin, atom_to_list(Name) ++ ".app"]), read_app_info(AppFile, AppFile, Name, DefaultVsn, StatusAcc) end, diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index 8cff86d2a0..773b11583e 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -92,7 +92,8 @@ all() -> dependencies, mod_incl_cond_derived, use_selected_vsn, - use_selected_vsn_relative_path]. + use_selected_vsn_relative_path, + non_standard_vsn_id]. groups() -> []. @@ -107,6 +108,15 @@ end_per_group(_GroupName, Config) -> %% The test cases %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% A dummy break test case which is NOT in all(), but can be run +%% directly from the command line with ct_run. It just does a +%% test_server:break()... +break(_Config) -> + test_server:break(""), + ok. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Start a server process and check that it does not crash start_server(_Config) -> @@ -2287,6 +2297,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. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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. |