From 4a6edd6f6ffe820db595dfa1f2c43311f6581ca7 Mon Sep 17 00:00:00 2001
From: Siri Hansen
An application directory
It is recommended that application directories are named as the
+ application, possibly followed by a dash and the version
+ number. For example
Finally single modules and entire applications may be read from Escripts.
Some configuration parameters control the behavior of Reltool @@ -372,6 +382,11 @@
This parameter is mutual exclusive with
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
This parameter is mutual exclusive with
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
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
By default the
There are two categories of modules on the
There are two categories of modules on the
Double click on an module name to launch a module window.
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() -> []. @@ -106,6 +107,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 @@ -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. -- cgit v1.2.3