Mercurial > hg > octave-nkf
changeset 19379:b54093acb8fe
ver.m: Overhaul function.
Add ability to call "ver PKG_NAME". Add ability to call "pkg list PKG_NAME".
* ver.m: Redo docstring. Rename output variable to retval rather than
unnecessary use of varargout. Add ability to call "ver PKG_NAME" by passing
PKG_NAME to 'pkg list' command.
* pkg.m: Redo docstring for 'list' to explain new ability to supply a PKG_NAME.
Use numel() rather than length() for clarity. Use isempty() rather than
length() == 0 for clarity.
* installed_packages.m: Add additional input argument pkgname. Use unique()
rather than double for loop to uniquify package list. Add code to report
only on package pkgname if given. Use numel() rather than length() for
clarity. Replace for loops with cellfun calls to determine max length of
string entries.
* version.m: Add seealso reference to ver in docstring.
author | Rik <rik@octave.org> |
---|---|
date | Tue, 30 Sep 2014 08:29:16 -0700 |
parents | 1111d2d5ff95 |
children | c3611856cdd4 |
files | scripts/miscellaneous/ver.m scripts/miscellaneous/version.m scripts/pkg/pkg.m scripts/pkg/private/installed_packages.m |
diffstat | 4 files changed, 170 insertions(+), 162 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/miscellaneous/ver.m +++ b/scripts/miscellaneous/ver.m @@ -17,19 +17,21 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} ver () -## @deftypefnx {Function File} {v =} ver () -## @deftypefnx {Function File} {v =} ver ("Octave") -## @deftypefnx {Function File} {v =} ver (@var{package}) +## @deftypefn {Function File} {} ver +## @deftypefnx {Function File} {} ver Octave +## @deftypefnx {Function File} {} ver @var{package} +## @deftypefnx {Function File} {v =} ver (@dots{}) ## ## Display a header containing the current Octave version number, license -## string, and operating system followed by a list of installed packages, -## versions, and installation directories. +## string, and operating system. The header is followed by a list of installed +## packages, versions, and installation directories. ## -## @code{v = ver ()} +## Use the package name @var{package} or Octave to limit the listing to a +## desired component. ## -## Return a vector of structures describing Octave and each installed package. -## The structure includes the following fields. +## When called with an output argument, return a vector of structures +## describing Octave and each installed package. The structure includes the +## following fields. ## ## @table @code ## @item Name @@ -45,71 +47,67 @@ ## Date of the version/revision. ## @end table ## -## @code{v = ver ("Octave")} -## -## Return version information for Octave only. -## -## @code{v = ver (@var{package})} -## -## Return version information for @var{package}. -## -## @seealso{version, octave_config_info} +## @seealso{version, octave_config_info, pkg} ## @end deftypefn ## Author: William Poetra Yoga Hadisoeseno <williampoetra@gmail.com> -function varargout = ver (package = "") +function retval = ver (package = "") if (nargin > 1) print_usage (); endif - ## Start with the version info for Octave - ret = struct ("Name", "Octave", "Version", version, - "Release", [], "Date", []); + if (nargout == 0) + [unm, err] = uname (); - ## Add the installed packages - lst = pkg ("list"); - for i = 1:length (lst) - ret(end+1) = struct ("Name", lst{i}.name, "Version", lst{i}.version, - "Release", [], "Date", lst{i}.date); - endfor - - if (nargout == 0) - octave_license = license (); - - [unm, status] = uname (); - - if (status < 0) + if (err) os_string = "unknown"; else - os_string = sprintf ("%s %s %s %s", unm.sysname, unm.release, - unm.version, unm.machine); + os_string = sprintf ("%s %s %s %s", + unm.sysname, unm.release, unm.version, unm.machine); endif hbar(1:70) = "-"; - ver_line1 = "GNU Octave Version "; - ver_line2 = "GNU Octave License: "; - ver_line3 = "Operating System: "; + desc = {hbar + ["GNU Octave Version: " OCTAVE_VERSION] + ["GNU Octave License: " license] + ["Operating System: " os_string] + hbar}; + + printf ("%s\n", desc{:}); - ver_desc = sprintf ("%s\n%s%s\n%s%s\n%s%s\n%s\n", hbar, ver_line1, version, - ver_line2, octave_license, ver_line3, os_string, hbar); - - puts (ver_desc); - - pkg ("list"); + if (isempty (package)) + pkg ("list"); + elseif (strcmpi (package, "Octave")) + ## Nothing to do, Octave version was already reported + else + pkg ("list", package); + endif else - if (! isempty (package)) - n = []; - for r = 1:numel (ret) - if (strcmpi (ret(r).Name, package)) - n = r; - break; - endif + ## Get the installed packages + if (isempty (package)) + lst = pkg ("list"); + ## Start with the version info for Octave + retval = struct ("Name", "Octave", "Version", version, + "Release", [], "Date", []); + for i = 1:numel (lst) + retval(end+1) = struct ("Name", lst{i}.name, "Version", lst{i}.version, + "Release", [], "Date", lst{i}.date); endfor - ret = ret(n); + elseif (strcmpi (package, "Octave")) + retval = struct ("Name", "Octave", "Version", version, + "Release", [], "Date", []); + else + lst = pkg ("list", package); + if (isempty (lst)) + retval = struct ("Name", "", "Version", [], + "Release", [], "Date", []); + else + retval = struct ("Name", lst{1}.name, "Version", lst{1}.version, + "Release", [], "Date", lst{1}.date); + endif endif - varargout{1} = ret; endif endfunction
--- a/scripts/miscellaneous/version.m +++ b/scripts/miscellaneous/version.m @@ -18,11 +18,11 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} version () -## Return the version number of Octave, as a string. +## Return the version number of Octave as a string. ## ## This is an alias for the function @w{@env{OCTAVE_VERSION}} provided for ## compatibility. -## @seealso{OCTAVE_VERSION} +## @seealso{OCTAVE_VERSION, ver} ## @end deftypefn ## Author: jwe
--- a/scripts/pkg/pkg.m +++ b/scripts/pkg/pkg.m @@ -21,8 +21,9 @@ ## -*- texinfo -*- ## @deftypefn {Command} {} pkg @var{command} @var{pkg_name} ## @deftypefnx {Command} {} pkg @var{command} @var{option} @var{pkg_name} -## Manage packages (groups of add-on functions) for Octave. Different actions -## are available depending on the value of @var{command}. +## Manage packages (groups of add-on functions) for Octave. +## +## Different actions are available depending on the value of @var{command}. ## ## Available commands: ## @@ -123,11 +124,25 @@ ## Show the list of currently installed packages. For example, ## ## @example -## installed_packages = pkg ("list") +## pkg list ## @end example ## ## @noindent -## returns a cell array containing a structure for each installed package. +## will produce a short report with the package name, version, and installation +## directory for each installed package. Supply a package name to limit +## reporting to a particular package. For example: +## +## @example +## pkg list image +## @end example +## +## If a single return argument is requested then @code{pkg} returns a cell +## array where each element is a structure with information on a single +## package. +## +## @example +## installed_packages = pkg ("list") +## @end example ## ## If two output arguments are requested @code{pkg} splits the list of ## installed packages into those which were installed by the current user, @@ -137,7 +152,7 @@ ## [user_packages, system_packages] = pkg ("list") ## @end example ## -## The option @qcode{"-forge"} lists packages available at the Octave-Forge +## The @qcode{"-forge"} option lists packages available at the Octave-Forge ## repository. This requires an internet connection and the cURL library. ## For example: ## @@ -164,7 +179,7 @@ ## @end example ## ## @noindent -## If any of the requested packages is not installed, pkg returns an +## If any of the requested packages is not installed, @code{pkg} returns an ## error, unless a second output is requested: ## ## @example @@ -263,6 +278,7 @@ ## @end deftypefn function [local_packages, global_packages] = pkg (varargin) + ## Installation prefix (FIXME: what should these be on windows?) persistent user_prefix = false; persistent prefix = false; @@ -271,10 +287,6 @@ persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave", "octave_packages"); - confirm_recursive_rmdir (false, "local"); - - mlock (); - ## If user is superuser set global_istall to true ## FIXME: is it OK to set this always true on windows? global_install = ((ispc () && ! isunix ()) || (geteuid () == 0)); @@ -285,12 +297,17 @@ archprefix = tilde_expand (archprefix); endif + mlock (); + + confirm_recursive_rmdir (false, "local"); + available_actions = {"list", "install", "uninstall", "load", ... "unload", "prefix", "local_list", ... "global_list", "rebuild", "build", ... "describe", "update"}; - ## Handle input - if (length (varargin) == 0 || ! iscellstr (varargin)) + + ## Parse input arguments + if (isempty (varargin) || ! iscellstr (varargin)) print_usage (); endif files = {}; @@ -299,7 +316,7 @@ action = "none"; verbose = false; octave_forge = false; - for i = 1:length (varargin) + for i = 1:numel (varargin) switch (varargin{i}) case "-nodeps" deps = false; @@ -327,11 +344,10 @@ [prefix, archprefix] = default_prefix (global_install); endif case available_actions - if (strcmp (action, "none")) - action = varargin{i}; - else + if (! strcmp (action, "none")) error ("more than one action specified"); endif + action = varargin{i}; otherwise files{end+1} = varargin{i}; endswitch @@ -352,19 +368,20 @@ endif else if (nargout == 0) - installed_packages (local_list, global_list); + installed_packages (local_list, global_list, files); elseif (nargout == 1) - local_packages = installed_packages (local_list, global_list); + local_packages = installed_packages (local_list, global_list, files); elseif (nargout == 2) [local_packages, global_packages] = installed_packages (local_list, - global_list); + global_list, + files); else error ("too many output arguments requested"); endif endif case "install" - if (length (files) == 0) + if (isempty (files)) error ("you must specify at least one filename when calling 'pkg install'"); endif @@ -389,48 +406,47 @@ end_unwind_protect case "uninstall" - if (length (files) == 0) + if (isempty (files)) error ("you must specify at least one package when calling 'pkg uninstall'"); endif - uninstall (files, deps, verbose, local_list, - global_list, global_install); + uninstall (files, deps, verbose, local_list, global_list, global_install); case "load" - if (length (files) == 0) - error ("you must specify at least one package, 'all' or 'auto' when calling 'pkg load'"); + if (isempty (files)) + error ("you must specify at least one package, 'all', or 'auto' when calling 'pkg load'"); endif load_packages (files, deps, local_list, global_list); case "unload" - if (length (files) == 0) + if (isempty (files)) error ("you must specify at least one package or 'all' when calling 'pkg unload'"); endif unload_packages (files, deps, local_list, global_list); case "prefix" - if (length (files) == 0 && nargout == 0) + if (isempty (files) && nargout == 0) printf ("Installation prefix: %s\n", prefix); printf ("Architecture dependent prefix: %s\n", archprefix); - elseif (length (files) == 0 && nargout >= 1) + elseif (isempty (files) && nargout >= 1) local_packages = prefix; global_packages = archprefix; - elseif (length (files) >= 1 && nargout <= 2 && ischar (files{1})) + elseif (numel (files) >= 1 && nargout <= 2 && ischar (files{1})) prefix = tilde_expand (files{1}); if (! exist (prefix, "dir")) - [status, msg, msgid] = mkdir (prefix); + [status, msg] = mkdir (prefix); if (status == 0) - error("cannot create prefix %s: %s", prefix, msg); + error ("cannot create prefix %s: %s", prefix, msg); endif warning ("creating the directory %s\n", prefix); endif local_packages = prefix = canonicalize_file_name (prefix); user_prefix = true; - if (length (files) >= 2 && ischar (files{2})) + if (numel (files) >= 2 && ischar (files{2})) archprefix = tilde_expand (files{2}); if (! exist (archprefix, "dir")) - [status, msg, msgid] = mkdir (archprefix); + [status, msg] = mkdir (archprefix); if (status == 0) - error("cannot create archprefix %s: %s", archprefix, msg); + error ("cannot create archprefix %s: %s", archprefix, msg); endif warning ("creating the directory %s\n", archprefix); global_packages = archprefix = canonicalize_file_name (archprefix); @@ -441,11 +457,11 @@ endif case "local_list" - if (length (files) == 0 && nargout == 0) + if (isempty (files) && nargout == 0) disp (local_list); - elseif (length (files) == 0 && nargout == 1) + elseif (isempty (files) && nargout == 1) local_packages = local_list; - elseif (length (files) == 1 && nargout == 0 && ischar (files{1})) + elseif (numel (files) == 1 && nargout == 0 && ischar (files{1})) local_list = files{1}; if (! exist (local_list, "file")) try @@ -461,11 +477,11 @@ endif case "global_list" - if (length (files) == 0 && nargout == 0) - disp(global_list); - elseif (length (files) == 0 && nargout == 1) + if (isempty (files) && nargout == 0) + disp (global_list); + elseif (isempty (files) && nargout == 1) local_packages = global_list; - elseif (length (files) == 1 && nargout == 0 && ischar (files{1})) + elseif (numel (files) == 1 && nargout == 0 && ischar (files{1})) global_list = files{1}; if (! exist (global_list, "file")) try @@ -490,8 +506,8 @@ local_packages = global_packages; endif else - local_packages = rebuild (prefix, archprefix, local_list, files, auto, - verbose); + local_packages = rebuild (prefix, archprefix, local_list, files, + auto, verbose); local_packages = save_order (local_packages); save (local_list, "local_packages"); if (nargout == 0) @@ -500,23 +516,21 @@ endif case "build" - if (length (files) < 2) + if (numel (files) < 2) error ("you must specify at least the build directory and one filename\nwhen calling 'pkg build'"); endif build (files, deps, auto, verbose); case "describe" - if (length (files) == 0) + if (isempty (files)) error ("you must specify at least one package or 'all' when calling 'pkg describe'"); endif - ## FIXME: the name of the output variables is inconsistent - ## with their content + ## FIXME: name of the output variables is inconsistent with their content switch (nargout) case 0 describe (files, verbose, local_list, global_list); case 1 - pkg_desc_list = describe (files, verbose, local_list, ... - global_list); + pkg_desc_list = describe (files, verbose, local_list, global_list); local_packages = pkg_desc_list; case 2 [pkg_desc_list, flag] = describe (files, verbose, local_list, ... @@ -530,24 +544,20 @@ case "update" if (nargout == 0) installed_pkgs_lst = installed_packages (local_list, global_list); - if (length (files) > 0) + if (numel (files) > 0) update_lst = {}; - for i = 1:length (files) - is_installed = false; - for j = 1:length (installed_pkgs_lst) - if (strcmp (files{i}, installed_pkgs_lst{j}.name)) - update_lst = { update_lst{:}, installed_pkgs_lst{j} }; - is_installed = true; - endif - endfor - if (is_installed == false) - s = sprintf ("Package %s is not installed - not updating this package", files{i}); - warning (s); + installed_names = {installed_pkgs_list.name}'; + for i = 1:numel (files) + idx = find (strcmp (files{i}, installed_names), 1); + if (isempty (idx)) + warning ("Package %s is not installed - not updating this package", files{i}); + else + update_lst = { update_lst, installed_pkgs_lst{idx} }; endif endfor installed_pkgs_lst = update_lst; endif - for i = 1:length (installed_pkgs_lst) + for i = 1:numel (installed_pkgs_lst) installed_pkg_name = installed_pkgs_lst{i}.name; installed_pkg_version = installed_pkgs_lst{i}.version; forge_pkg_version = get_forge_pkg (installed_pkg_name); @@ -560,7 +570,8 @@ endif otherwise - error ("you must specify a valid action for 'pkg'. See 'help pkg' for details"); + error ("you must specify a valid action for 'pkg'. See 'help pkg' for details"); endswitch + endfunction
--- a/scripts/pkg/private/installed_packages.m +++ b/scripts/pkg/private/installed_packages.m @@ -22,7 +22,8 @@ ## Undocumented internal function. ## @end deftypefn -function [out1, out2] = installed_packages (local_list, global_list) +function [out1, out2] = installed_packages (local_list, global_list, pkgname = {}) + ## Get the list of installed packages. try local_packages = load (local_list).local_packages; @@ -38,41 +39,42 @@ ## Eliminate duplicates in the installed package list. ## Locally installed packages take precedence. - dup = []; - for i = 1:length (installed_pkgs_lst) - if (any (dup == i)) - continue; + installed_names = cellfun (@(x) x.name, installed_pkgs_lst, + "uniformoutput", false); + [~, idx] = unique (installed_names, "first"); + installed_names = installed_names(idx); + installed_pkgs_lst = installed_pkgs_lst(idx); + + ## Check whether info on a particular package was requested + if (! isempty (pkgname)) + idx = find (strcmp (pkgname{1}, installed_names)); + if (isempty (idx)) + installed_names = {}; + installed_pkgs_lst = {}; + else + installed_names = installed_names(idx); + installed_pkgs_lst = installed_pkgs_lst(idx); endif - for j = (i+1):length (installed_pkgs_lst) - if (any (dup == j)) - continue; - endif - if (strcmp (installed_pkgs_lst{i}.name, installed_pkgs_lst{j}.name)) - dup = [dup, j]; - endif - endfor - endfor - if (! isempty (dup)) - installed_pkgs_lst(dup) = []; endif ## Now check if the package is loaded. + ## FIXME: couldn't dir_in_loadpath() be used here? tmppath = strrep (path (), "\\", "/"); - for i = 1:length (installed_pkgs_lst) + for i = 1:numel (installed_pkgs_lst) if (strfind (tmppath, strrep (installed_pkgs_lst{i}.dir, '\', '/'))) installed_pkgs_lst{i}.loaded = true; else installed_pkgs_lst{i}.loaded = false; endif endfor - for i = 1:length (local_packages) + for i = 1:numel (local_packages) if (strfind (tmppath, strrep (local_packages{i}.dir, '\', '/'))) local_packages{i}.loaded = true; else local_packages{i}.loaded = false; endif endfor - for i = 1:length (global_packages) + for i = 1:numel (global_packages) if (strfind (tmppath, strrep (global_packages{i}.dir, '\', '/'))) global_packages{i}.loaded = true; else @@ -90,10 +92,14 @@ return; endif - ## We shouldn't return something, so we'll print something. - num_packages = length (installed_pkgs_lst); + ## Don't return anything, instead we'll print something. + num_packages = numel (installed_pkgs_lst); if (num_packages == 0) - printf ("no packages installed.\n"); + if (isempty (pkgname)) + printf ("no packages installed.\n"); + else + printf ("package %s is not installed.\n", pkgname{1}); + endif return; endif @@ -101,20 +107,13 @@ h1 = "Package Name"; h2 = "Version"; h3 = "Installation directory"; - max_name_length = length (h1); - max_version_length = length (h2); - names = cell (num_packages, 1); - for i = 1:num_packages - max_name_length = max (max_name_length, - length (installed_pkgs_lst{i}.name)); - max_version_length = max (max_version_length, - length (installed_pkgs_lst{i}.version)); - names{i} = installed_pkgs_lst{i}.name; - endfor - max_dir_length = terminal_size ()(2) - max_name_length - ... - max_version_length - 7; + max_name_length = max ([length(h1), cellfun(@length, installed_names)]); + version_lengths = cellfun (@(x) length (x.version), installed_pkgs_lst); + max_version_length = max ([length(h2), version_lengths]); + ncols = terminal_size ()(2); + max_dir_length = ncols - max_name_length - max_version_length - 7; if (max_dir_length < 20) - max_dir_length = Inf; + max_dir_length = Inf; endif h1 = postpad (h1, max_name_length + 1, " "); @@ -129,13 +128,12 @@ printf ("%s\n", tmp); ## Print the packages. - format = sprintf ("%%%ds %%1s| %%%ds | %%s\n", max_name_length, - max_version_length); - [dummy, idx] = sort (names); + format = sprintf ("%%%ds %%1s| %%%ds | %%s\n", + max_name_length, max_version_length); for i = 1:num_packages - cur_name = installed_pkgs_lst{idx(i)}.name; - cur_version = installed_pkgs_lst{idx(i)}.version; - cur_dir = installed_pkgs_lst{idx(i)}.dir; + cur_name = installed_pkgs_lst{i}.name; + cur_version = installed_pkgs_lst{i}.version; + cur_dir = installed_pkgs_lst{i}.dir; if (length (cur_dir) > max_dir_length) first_char = length (cur_dir) - max_dir_length + 4; first_filesep = strfind (cur_dir(first_char:end), filesep ()); @@ -145,12 +143,13 @@ cur_dir = ["..." cur_dir(first_char:end)]; endif endif - if (installed_pkgs_lst{idx(i)}.loaded) + if (installed_pkgs_lst{i}.loaded) cur_loaded = "*"; else cur_loaded = " "; endif printf (format, cur_name, cur_loaded, cur_version, cur_dir); endfor + endfunction