Mercurial > hg > octave-lyh
diff scripts/pkg/pkg.m @ 6925:1401a79af68c
[project @ 2007-09-26 18:58:52 by dbateman]
author | dbateman |
---|---|
date | Wed, 26 Sep 2007 18:58:53 +0000 |
parents | 65d0fa83261a |
children | ee12d56c4200 |
line wrap: on
line diff
--- a/scripts/pkg/pkg.m +++ b/scripts/pkg/pkg.m @@ -116,6 +116,13 @@ ## @example ## p = pkg prefix ## @end example +## +## The location in which to install the architecture dependent files can be +## independent specified with an addition argument. For example +## +## @example +## pkg prefix ~/my_octave_packages ~/my_octave_packages_for_my_pc +## @end example ## @item local_list ## Set the file in which to look for information on the locally ## installed packages. Locally installed packages are those that are @@ -173,24 +180,24 @@ ## Installation prefix (XXX: what should these be on windows?) persistent user_prefix = false; persistent prefix = -1; + persistent archprefix = -1; persistent local_list = tilde_expand (fullfile("~", ".octave_packages")); persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave", "octave_packages"); mlock (); - if (ispc () && ! isunix ()) - global_install = 1; - else - global_install = (geteuid() == 0); - endif + global_install = issuperuser (); if (prefix == -1) if (global_install) prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages"); + archprefix = fullfile (OCTAVE_HOME (), "libexec", "octave", "packages"); else prefix = fullfile ("~", "octave"); + archprefix = prefix; endif prefix = tilde_expand (prefix); + archprefix = tilde_expand (archprefix); endif ## Handle input @@ -222,9 +229,9 @@ if (! user_prefix) prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages"); endif - case {"list", "install", "uninstall", "load", "unload", ... - "prefix", "local_list", "global_list", "rebuild", "build"} - if (strcmp (action,"none")) + case {"list", "install", "uninstall", "load", "unload", "prefix", ... + "local_list", "global_list", "rebuild", "build"} + if (strcmp (action, "none")) action = varargin{i}; else error ("more than one action specified"); @@ -252,7 +259,7 @@ if (length (files) == 0) error ("you must specify at least one filename when calling 'pkg install'"); endif - install (files, deps, auto, prefix, verbose, local_list, + install (files, deps, auto, prefix, archprefix, verbose, local_list, global_list, global_install); case "uninstall" @@ -276,17 +283,27 @@ case "prefix" if (length (files) == 0 && nargout == 0) - disp (prefix); - elseif (length (files) == 0 && nargout == 1) + printf ("Installation prefix: %s\n", prefix); + printf ("Architecture dependent prefix: %s\n", archprefix); + elseif (length (files) == 0 && nargout >= 1) local_packages = prefix; - elseif (length (files) == 1 && nargout <= 1 && ischar (files{1})) + global_packages = archprefix; + elseif (length (files) >= 1 && nargout <= 2 && ischar (files{1})) prefix = files{1}; - ## if (!strcmp(prefix(end), filesep)) - ## prefix(end+1) = filesep; - ## endif prefix = absolute_pathname (prefix); local_packages = prefix; user_prefix = true; + if (length (files) >= 2 && ischar (files{2})) + archprefix = files{2}; + try + archprefix = absolute_pathname (archprefix); + catch + mkdir (archprefix); + warning ("creating the directory %s\n", archprefix); + archprefix = absolute_pathname (archprefix); + end_try_catch + global_packages = archprefix; + endif else error ("you must specify a prefix directory, or request an output argument"); endif @@ -327,14 +344,16 @@ case "rebuild" if (global_install) - global_packages = rebuild (prefix, global_list, files, auto, verbose); + global_packages = rebuild (prefix, archprefix, global_list, files, + auto, verbose); global_packages = save_order (global_packages); save (global_list, "global_packages"); if (nargout > 0) local_packages = global_packages; endif else - local_packages = rebuild (prefix, 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) @@ -353,7 +372,7 @@ endswitch endfunction -function descriptions = rebuild (prefix, list, files, auto, verbose) +function descriptions = rebuild (prefix, archprefix, list, files, auto, verbose) if (isempty (files)) [dirlist, err, msg] = readdir (prefix); if (err) @@ -380,6 +399,8 @@ if (exist (descfile, "file")) desc = get_description (descfile); desc.dir = fullfile (prefix, dirlist{k}); + desc.archprefix = fullfile (archprefix, strcat (desc.name, "-", + desc.version)); if (auto != 0) if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file")) unlink (fullfile (desc.dir, "packinfo", ".autoload")); @@ -450,7 +471,7 @@ endif files(1) = []; buildlist = fullfile (builddir, "octave_packages"); - install (files, handle_deps, autoload, installdir, verbose, + install (files, handle_deps, autoload, installdir, installdir, verbose, buildlist, "", false); unwind_protect repackage (builddir, buildlist); @@ -465,7 +486,8 @@ end_unwind_protect endfunction -function install (files, handle_deps, autoload, prefix, verbose, local_list, global_list, global_install) +function install (files, handle_deps, autoload, prefix, archprefix, verbose, + local_list, global_list, global_install) # Check that the directory in prefix exist. If it doesn't: create it! if (! exist (prefix, "dir")) @@ -491,7 +513,6 @@ ## Uncompress the packages and read the DESCRIPTION files tmpdirs = packdirs = descriptions = {}; try - ## Warn about non existent files for i = 1:length (files) if (isempty (glob(files{i}))) @@ -549,12 +570,17 @@ [dummy, nm] = fileparts (tgz); if ((length (nm) >= length (desc.name)) && ! strcmp (desc.name, nm(1:length(desc.name)))) - error ("package name '%s' doesn't correspond to its filename '%s'", desc.name, nm); + error ("package name '%s' doesn't correspond to its filename '%s'", + desc.name, nm); endif ## Set default installation directory desc.dir = fullfile (prefix, strcat (desc.name, "-", desc.version)); + ## Set default architectire dependent installation directory + desc.archprefix = fullfile (archprefix, strcat (desc.name, "-", + desc.version)); + ## Save desc descriptions{end+1} = desc; @@ -656,10 +682,10 @@ for i = 1:length (descriptions) desc = descriptions{i}; pdir = packdirs{i}; - copy_files (desc, pdir); - create_pkgadddel (desc, pdir, "PKG_ADD"); - create_pkgadddel (desc, pdir, "PKG_DEL"); - finish_installation (desc, pdir) + copy_files (desc, pdir, global_install); + create_pkgadddel (desc, pdir, "PKG_ADD", global_install); + create_pkgadddel (desc, pdir, "PKG_DEL", global_install); + finish_installation (desc, pdir, global_install) endfor catch ## Something went wrong, delete tmpdirs @@ -668,6 +694,7 @@ endfor for i = 1:length (descriptions) rm_rf (descriptions{i}.dir); + rm_rf (getarchdir (descriptions{i})); endfor rethrow (lasterror ()); end_try_catch @@ -675,9 +702,11 @@ ## Check if the installed directory is empty. If it is remove it ## from the list for i = length (descriptions):-1:1 - if (dirempty (descriptions{i}.dir, {"packinfo", "doc"})) + if (dirempty (descriptions{i}.dir, {"packinfo", "doc"}) && + dirempty (getarchdir (descriptions{i}))) warning ("package %s is empty\n", descriptions{i}.name); rm_rf (descriptions{i}.dir); + rm_rf (getarchdir (descriptions{i})); descriptions(i) = []; endif endfor @@ -738,7 +767,8 @@ idx (end + 1) = i; endif endfor - load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst); + load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, + global_install); endif endfunction @@ -826,8 +856,8 @@ ## Do the actual deletion if (desc.loaded) rmpath (desc.dir); - if (exist (fullfile (desc.dir, getarch()), "dir")) - rmpath (fullfile (desc.dir, getarch ())); + if (exist (getarchdir (desc))) + rmpath (getarchdir (desc)); endif endif if (exist (desc.dir, "dir")) @@ -835,6 +865,13 @@ if (status != 1) error ("couldn't delete directory %s: %s", desc.dir, msg); endif + [status, msg] = rm_rf (getarchdir (desc)); + if (status != 1) + error ("couldn't delete directory %s: %s", getarchdir (desc), msg); + endif + if (dirempty (desc.archprefix)) + rm_rf (desc.archprefix); + endif else warning ("directory %s previously lost", desc.dir); endif @@ -894,7 +931,8 @@ if (exist (fullfile (pack.name, "inst", "bin"), "dir")) movefile (fullfile (pack.name, "inst", "bin"), pack.name); endif - archdir = fullfile (pack.name, "inst", getarch ()); + archdir = fullfile (pack.archprefix, strcat (pack.name, "-", + pack.version), getarch ()); if (exist (archdir, "dir")) if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file")) unlink (fullfile (pack.name, "inst", "PKG_ADD")); @@ -922,7 +960,12 @@ endif tfile = strcat (pack.name, "-", pack.version, ".tar"); tar (tfile, pack.name); - + try + gzip (tfile); + unlink (tfile); + catch + warning ("failed to compress %s", tfile); + end_try_catch unwind_protect_cleanup if (exist (pack.name, "dir")) rm_rf (pack.name); @@ -1123,16 +1166,18 @@ endif endfunction -function create_pkgadddel (desc, packdir, nm) +function create_pkgadddel (desc, packdir, nm, global_install) instpkg = fullfile (desc.dir, nm); instfid = fopen (instpkg, "wt"); ## If it is exists, most of the PKG_* file should go into the ## architecture dependent directory so that the autoload/mfilename ## commands work as expected. The only part that doesn't is the ## part in the main directory. - if (exist (fullfile (desc.dir, getarch ()), "dir")) - archpkg = fullfile (desc.dir, getarch (), nm); - archfid = fopen (archpkg, "wt"); + archdir = fullfile (getarchprefix (desc), strcat (desc.name, "-", + desc.version), getarch ()); + if (exist (getarchdir (desc, global_install), "dir")) + archpkg = fullfile (getarchdir (desc, global_install), nm); + archfid = fopen (archpkg, "at"); else archpkg = instpkg; archfid = instfid; @@ -1186,7 +1231,7 @@ endif endfunction -function copy_files (desc, packdir, bindir) +function copy_files (desc, packdir, global_install) ## Create the installation directory if (! exist (desc.dir, "dir")) [status, output] = mkdir (desc.dir); @@ -1196,6 +1241,8 @@ endif endif + octfiledir = getarchdir (desc); + ## Copy the files from "inst" to installdir instdir = fullfile (packdir, "inst"); if (! dirempty (instdir)) @@ -1204,6 +1251,55 @@ rm_rf (desc.dir); error ("couldn't copy files to the installation directory"); endif + if (exist (fullfile (desc.dir, getarch ()), "dir") && + ! strcmp (fullfile (desc.dir, getarch ()), octfiledir)) + if (! exist (octfiledir, "dir")) + ## Can be required to create upto three levels of dirs + octm1 = fileparts (octfiledir); + if (! exist (octm1, "dir")) + octm2 = fileparts (octm1); + if (! exist (octm2, "dir")) + octm3 = fileparts (octm2); + if (! exist (octm3, "dir")) + [status, output] = mkdir (octm3); + if (status != 1) + rm_rf (desc.dir); + error ("couldn't create installation directory %s : %s", + octm3, output); + endif + endif + [status, output] = mkdir (octm2); + if (status != 1) + rm_rf (desc.dir); + error ("couldn't create installation directory %s : %s", + octm2, output); + endif + endif + [status, output] = mkdir (octm1); + if (status != 1) + rm_rf (desc.dir); + error ("couldn't create installation directory %s : %s", + octm1, output); + endif + endif + [status, output] = mkdir (octfiledir); + if (status != 1) + rm_rf (desc.dir); + error ("couldn't create installation directory %s : %s", + octfiledir, output); + endif + endif + [status, output] = movefile (fullfile (desc.dir, getarch (), "*"), + octfiledir); + rm_rf (fullfile (desc.dir, getarch ())); + + if (status != 1) + rm_rf (desc.dir); + rm_rf (octfiledir); + error ("couldn't copy files to the installation directory"); + endif + endif + endif ## Create the "packinfo" directory @@ -1211,21 +1307,24 @@ [status, msg] = mkdir (packinfo); if (status != 1) rm_rf (desc.dir); + rm_rf (octfiledir); error ("couldn't create packinfo directory: %s", msg); endif ## Copy DESCRIPTION [status, output] = copyfile (fullfile (packdir, "DESCRIPTION"), packinfo); if (status != 1) - rm_rf (desc.dir); - error ("couldn't copy DESCRIPTION: %s", output); + rm_rf (desc.dir); + rm_rf (octfiledir); + error ("couldn't copy DESCRIPTION: %s", output); endif ## Copy COPYING [status, output] = copyfile (fullfile (packdir, "COPYING"), packinfo); if (status != 1) - rm_rf (desc.dir); - error ("couldn't copy COPYING: %s", output); + rm_rf (desc.dir); + rm_rf (octfiledir); + error ("couldn't copy COPYING: %s", output); endif ## If the file ChangeLog exists, copy it @@ -1234,6 +1333,7 @@ [status, output] = copyfile (fChangeLog, packinfo); if (status != 1) rm_rf (desc.dir); + rm_rf (octfiledir); error ("couldn't copy ChangeLog file: %s", output); endif endif @@ -1244,14 +1344,16 @@ [status, output] = copyfile (fINDEX, packinfo); if (status != 1) rm_rf (desc.dir); + rm_rf (octfiledir); error ("couldn't copy INDEX file: %s", output); endif else try write_INDEX (desc, fullfile (packdir, "inst"), - fullfile (packinfo, "INDEX")); + fullfile (packinfo, "INDEX"), global_install); catch rm_rf (desc.dir); + rm_rf (octfiledir); rethrow (lasterror ()); end_try_catch endif @@ -1262,6 +1364,7 @@ [status, output] = copyfile (fon_uninstall, packinfo); if (status != 1) rm_rf (desc.dir); + rm_rf (octfiledir); error ("couldn't copy on_uninstall.m: %s", output); endif endif @@ -1269,17 +1372,17 @@ ## Is there a doc/ directory that needs to be installed docdir = fullfile (packdir, "doc"); if (exist (docdir, "dir") && ! dirempty (docdir)) - [status, output] = copyfile (docdir, desc.dir); + [status, output] = copyfile (docdir, desc.dir); endif ## Is there a bin/ directory that needs to be installed bindir = fullfile (packdir, "bin"); if (exist (bindir, "dir") && ! dirempty (bindir)) - [status, output] = copyfile (bindir, desc.dir); + [status, output] = copyfile (bindir, desc.dir); endif endfunction -function finish_installation (desc, packdir) +function finish_installation (desc, packdir, global_install) ## Is there a post-install to call? if (exist (fullfile (packdir, "post_install.m"), "file")) wd = pwd (); @@ -1290,6 +1393,7 @@ catch cd (wd); rm_rf (desc.dir); + rm_rf (getarchdir (desc), global_install); rethrow (lasterror ()); end_try_catch endif @@ -1470,7 +1574,7 @@ ## 'desc' describes the package. ## 'dir' is the 'inst' direcotyr in temporary directory. ## 'INDEX' is the name (including path) of resulting INDEX file. -function write_INDEX (desc, dir, INDEX) +function write_INDEX (desc, dir, INDEX, global_install) ## Get names of functions in dir [files, err, msg] = readdir (dir); if (err) @@ -1478,8 +1582,7 @@ endif ## Check for architecture dependent files - arch = getarch(); - tmpdir = fullfile (dir, arch); + tmpdir = getarchdir (desc); if (exist (tmpdir, "dir")) [files2, err, msg] = readdir (tmpdir); if (err) @@ -1718,7 +1821,7 @@ endif ## Load the packages, but take care of the ordering of dependencies - load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst); + load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, true); endfunction function unload_packages (files, handle_deps, local_list, global_list) @@ -1739,35 +1842,36 @@ ## unload all if (length (files) == 1 && strcmp (files{1}, "all")) dirs = pdirs; + desc = installed_pkgs_lst; ## unload package_name1 ... else dirs = {}; + desc = {}; for i = 1:length (files) - idx = strcmp (pnames, files{i}); + idx = strcmp (pnames, files {i}); if (! any (idx)) error ("package %s is not installed", files{i}); endif - dirs{end+1} = pdirs{idx}; + dirs {end + 1} = pdirs {idx}; + desc {end + 1} = installed_pkgs_lst {idx}; endfor endif ## Check for architecture dependent directories - arch = getarch(); archdirs = {}; for i = 1:length (dirs) - tmpdir = fullfile (dirs{i}, arch); + tmpdir = getarchdir (desc {i}); if (exist (tmpdir, "dir")) archdirs{end + 1} = dirs{i}; archdirs{end + 1} = tmpdir; + else + archdirs{end+ 1} = dirs {i}; endif endfor - if (length (archdirs) > 0) - dirs = archdirs; - endif ## Unload the packages - for i = 1:length (dirs) - d = dirs{i}; + for i = 1:length (archdirs) + d = archdirs{i}; idx = strcmp (p, d); if (any (idx)) rmpath (d); @@ -1777,13 +1881,18 @@ endfunction function [status_out, msg_out] = rm_rf (dir) - crr = confirm_recursive_rmdir (); - unwind_protect - confirm_recursive_rmdir (false); - [status, msg] = rmdir (dir, "s"); - unwind_protect_cleanup - confirm_recursive_rmdir (crr); - end_unwind_protect + if (exist (dir)) + crr = confirm_recursive_rmdir (); + unwind_protect + confirm_recursive_rmdir (false); + [status, msg] = rmdir (dir, "s"); + unwind_protect_cleanup + confirm_recursive_rmdir (crr); + end_unwind_protect + else + status = 1; + msg = ""; + endif if (nargout > 0) status_out = status; endif @@ -1793,26 +1902,30 @@ endfunction function emp = dirempty (nm, ign) - if (nargin < 2) - ign = {".", ".."}; - else - ign = [{".", ".."}, ign]; - endif - l = dir (nm); - for i = 1:length (l) - found = false; - for j = 1:length (ign) - if (strcmp (l(i).name, ign{j})) - found = true; - break; + if (exist (nm, "dir")) + if (nargin < 2) + ign = {".", ".."}; + else + ign = [{".", ".."}, ign]; + endif + l = dir (nm); + for i = 1:length (l) + found = false; + for j = 1:length (ign) + if (strcmp (l(i).name, ign{j})) + found = true; + break; + endif + endfor + if (! found) + emp = false; + return endif endfor - if (! found) - emp = false; - return - endif - endfor - emp = true; + emp = true; + else + emp = true; + endif endfunction function arch = getarch () @@ -1821,6 +1934,27 @@ arch = _arch; endfunction +function archprefix = getarchprefix (desc, global_install) + if ((nargin == 2 && global_install) || (nargin < 2 && issuperuser ())) + archprefix = fullfile (octave_config_info ("libexecdir"), "octave", + "packages", strcat(desc.name, "-", desc.version)); + else + archprefix = desc.dir; + endif +endfunction + +function archdir = getarchdir (desc) + archdir = fullfile (desc.archprefix, getarch()); +endfunction + +function s = issuperuser () + if ((ispc () && ! isunix ()) || (geteuid() == 0)) + s = true; + else + s = false; + endif +endfunction + function [status, output] = shell (cmd) persistent have_sh; @@ -1879,9 +2013,9 @@ newdesc(idx) = []; endfunction -function load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst) +function load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, + global_install) idx = load_package_dirs (idx, [], handle_deps, installed_pkgs_lst); - arch = getarch (); dirs = {}; execpath = EXEC_PATH (); for i = idx; @@ -1890,7 +2024,7 @@ if (exist (fullfile (dirs{end}, "bin"), "dir")) execpath = strcat (fullfile(dirs{end}, "bin"), ":", execpath); endif - tmpdir = fullfile (ndir, arch); + tmpdir = getarchdir (installed_pkgs_lst {i}); if (exist (tmpdir, "dir")) dirs{end + 1} = tmpdir; endif