changeset 6645:81eb28d50cee

[project @ 2007-05-21 21:05:54 by dbateman]
author dbateman
date Mon, 21 May 2007 21:05:54 +0000
parents 004561c38e8f
children bd0a70c3f2db
files scripts/ChangeLog scripts/miscellaneous/copyfile.m scripts/pkg/pkg.m
diffstat 3 files changed, 275 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Mon May 21 20:59:26 2007 +0000
+++ b/scripts/ChangeLog	Mon May 21 21:05:54 2007 +0000
@@ -1,3 +1,26 @@
+2007-05-21  David Bateman  <dbateman@free.fr>
+
+	* pkg/pkg.m: Add rebuild target, and -local, -global option to
+	force installation location.
+	(rebuild): New subfunction to rebuild package database from
+	installed packages. Also allows changing of autoload status
+	(install): Warn use if attempting to install from non existent
+	file. 
+	(issuperuser): Use 'geteuid() == 0' instead of 'strcmp (getenv(
+	"USER", "root"))' for root test.
+
+2007-05-21  Michael Goffioul  <michael.goffioul@swing.be>
+
+	* miscellaneous/copyfile.m: check for cp.exe on Windows platforms
+	and replace "\" characters with "/".
+	* pkg/pkg.m: Use shell rather than system throughout. Replace "\" 
+	characters with "/" throughout.
+	(shell): New subfunction that wraps system and is careful with the
+	shell on windows platforms.
+	(configure_make): Explictly pass complier etc to configure
+	process.
+	(issuperuser): Force default to global install for Windows machines.
+	
 2007-05-19  Kristan Onu
 
 	* plot/Makefile.in (SOURCES): Remove hbar.m and add barh.m.
--- a/scripts/miscellaneous/copyfile.m	Mon May 21 20:59:26 2007 +0000
+++ b/scripts/miscellaneous/copyfile.m	Mon May 21 21:05:54 2007 +0000
@@ -40,7 +40,7 @@
   ## FIXME -- maybe use the same method as in ls to allow users control
   ## over the command that is executed.
 
-  if (ispc () && ! isunix () && isempty (file_in_path (EXEC_PATH, "cp")))
+  if (ispc () && ! isunix () && isempty (file_in_path (EXEC_PATH, "cp.exe")))
     ## Windows.
     cmd = "cmd /C xcopy /E";
     cmd_force_flag = "/Y";
@@ -73,6 +73,11 @@
     f1 = sprintf ("\"%s\" ", f1{:});
 
     f2 = tilde_expand (f2);
+  
+    if (ispc () && ! isunix () && ! isempty (file_in_path (EXEC_PATH, "cp.exe")))
+      f1 = strrep (f1, "\\", "/");
+      f2 = strrep (f2, "\\", "/");
+    endif
 
     ## Copy the files.
     [err, msg] = system (sprintf ("%s %s \"%s\"", cmd, f1, f2));
--- a/scripts/pkg/pkg.m	Mon May 21 20:59:26 2007 +0000
+++ b/scripts/pkg/pkg.m	Mon May 21 21:05:54 2007 +0000
@@ -32,21 +32,35 @@
 ## @noindent
 ## installs the package found in the file @code{image-1.0.0.tar.gz}.
 ##
-## If @var{option} is @code{-nodeps} the package manager will disable the
-## dependency checking. That way it is possible to install a package even
-## if it depends on another package that's not installed on the system.
-## @strong{Use this option with care.}
+## The @var{option} variable can contain options that affect the manner
+## in which a package is installed. These options can be one or more of
+##
+## @table @code
+## @item -nodeps
+## The package manager will disable the dependency checking. That way it 
+## is possible to install a package even if it depends on another package 
+## that's not installed on the system. @strong{Use this option with care.}
+##
+## @item -noauto
+## The package manager will not automatically load the installed package 
+## when starting Octave, even if the package requests that it is.
 ##
-## If @var{option} is @code{-noauto} the package manager will not
-## automatically load the installed package when starting Octave,
-## even if the package requests that it is.
+## @item -auto
+## The package manager will automatically load the installed package when 
+## starting Octave, even if the package requests that it isn't.
+##
+## @item -local
+## A local installation is forced, even if the user has system privileges.
 ##
-## If @var{option} is @code{-auto} the package manager will
-## automatically load the installed package when starting Octave,
-## even if the package requests that it isn't.
+## @item -global
+## A global installation is forced, even if the user doesn't normally have
+## system privileges
 ##
-## Finally, if @var{option} is @code{-verbose} the package manager will
-## print the output of all of the commands that are performed
+## @item -verbose
+## The package manager will print the output of all of the commands that are 
+## performed.
+## @end table
+##
 ## @item uninstall
 ## Uninstall named packages.  For example,
 ## @example
@@ -124,6 +138,17 @@
 ## @example
 ## pkg global_list
 ## @end example
+## @item rebuild
+## Rebuilds the package database from the installed directories. This can 
+## be used in cases where for some reason the package database is corrupted.
+## It can also take the @code{-auto} and @code{-noauto} options to allow the
+## autolaoding state of a package to be changed. For example
+##
+## @example
+## pkg rebuild -noauto image
+## @end example
+##
+## will remove the autoloading status of the image package.
 ## @end table
 ## @end deftypefn
 
@@ -132,20 +157,22 @@
 
 function [local_packages, global_packages] = pkg (varargin)
   ## Installation prefix (XXX: what should these be on windows?)
+  persistent user_prefix = false;
   persistent prefix = -1;
   persistent local_list = tilde_expand (fullfile("~", ".octave_packages"));
   persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave",
 				     "octave_packages");
   mlock ();
 
+  global_install = issuperuser ();
   if (prefix == -1)
-    if (issuperuser ())
+    if (global_install)
       prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
     else
       prefix = fullfile ("~", "octave");
     endif
+    prefix = tilde_expand (prefix);
   endif
-  prefix = tilde_expand (prefix);
 
   ## Handle input
   if (length (varargin) == 0 || ! iscellstr (varargin))
@@ -166,8 +193,18 @@
 	auto = 1;
       case "-verbose"
 	verbose = true;
+      case "-local"
+	global_install = false;
+	if (! user_prefix)
+	  prefix = fullfile ("~", "octave");
+	endif
+      case "-global"
+	global_install = true;
+	if (! user_prefix)
+	  prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
+	endif
       case {"list", "install", "uninstall", "load", "unload", ...
-	    "prefix", "local_list", "global_list"}
+	    "prefix", "local_list", "global_list", "rebuild"}
 	action = varargin{i};
       otherwise
 	files{end+1} = varargin{i};
@@ -192,13 +229,15 @@
       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, global_list);
+      install (files, deps, auto, prefix, verbose, local_list, 
+	       global_list, global_install);
 
     case "uninstall"
       if (length (files) == 0)
 	error ("you must specify at least one package when calling 'pkg uninstall'");
       endif
-      uninstall (files, deps, verbose, local_list, global_list);
+      uninstall (files, deps, verbose, local_list, 
+		 global_list, global_install);
 
     case "load"
       if (length (files) == 0)
@@ -222,6 +261,8 @@
 	## if (!strcmp(prefix(end), filesep))
 	##   prefix(end+1) = filesep;
 	## endif
+	prefix = tilde_expand (prefix);
+	user_prefix = true;
       else
 	error ("you must specify a prefix directory, or request an output argument");
       endif
@@ -247,11 +288,94 @@
       else
 	error ("you must specify a global_list file, or request an output argument");
       endif
+
+    case "rebuild"
+      if (global_install)
+	global_packages = rebuild (prefix, global_list, auto, verbose);
+	save (global_list, "global_packages");
+	local_packages = global_packages;
+      else
+	local_packages = rebuild (prefix, local_list, files, auto, verbose);
+	save (local_list, "local_packages");
+      endif
+
     otherwise
       error ("you must specify a valid action for 'pkg'. See 'help pkg' for details");
   endswitch
 endfunction
 
+function descriptions = rebuild (prefix, list, files, auto, verbose)
+  if (isempty (files))
+    [dirlist, err, msg] = readdir (prefix);
+    if (err)
+      error ("couldn't read directory %s: %s", prefix, msg);
+    endif
+    ## the two first entries of dirlist are "." and ".."
+    dirlist([1,2]) = [];
+  else
+    old_descriptions = installed_packages (list, list);
+    wd = pwd ();
+    cd (prefix);
+    dirlist = glob (cellfun(@(x) [x, '-*'], files, 'UniformOutput', 0))
+    cd (wd);
+  endif
+  descriptions = {};
+  for k = 1:length (dirlist)
+    descfile = fullfile (prefix, dirlist{k}, "packinfo", "DESCRIPTION");
+    if (verbose)
+      printf ("recreating package description from %s\n", dirlist{k});
+    endif
+    if (exist (descfile, "file"))
+      desc = get_description (descfile);
+      desc.dir = fullfile (prefix, dirlist{k});
+      if (auto != 0)
+	if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
+	  unlink (fullfile (desc.dir, "packinfo", ".autoload"));
+	endif
+        if (auto < 0)
+	  desc.autoload = 0;
+	elseif (auto > 0)
+	  desc.autoload = 1;
+	  fclose (fopen (fullfile (desc.dir, "packinfo", ".autoload"), "wt"));
+	endif
+      else
+	if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
+	  desc.autoload = 1;
+	else
+	  desc.autoload = 0;
+	endif
+      endif
+      descriptions{end + 1} = desc;
+    elseif (verbose)
+      warning ("directory %s is not a valid package", dirlist{k});
+    endif
+  endfor
+
+  if (isempty (files))
+    ## We are rebuilding for a particular package(s) so we should take
+    ## care to keep the other untouched packages in the descriptions
+    descriptions = {desriptions{:}, old_desriptions{:}};
+
+    dup = [];
+    for i = 1:length (descriptions)
+      if (find (dup, i))
+	continue;
+      endif
+      for j = (i+1):length (descriptions)
+	if (find (dup, j))
+	  continue;
+	endif
+	if (strcmp (descriptions{i}.name, descriptions{j}.name))
+	  dup = [dup, j];
+	endif
+      endfor
+    endfor
+    if (! isempty (dup))
+      descriptions (dup) = [];
+    endif  
+  endif
+endfunction
+
 function auto = isautoload (desc)
 auto = false;
 if (isfield (desc{1}, "autoload"))
@@ -266,8 +390,7 @@
 endif
 endfunction
 
-function install (files, handle_deps, autoload, prefix, verbose, local_list, global_list)
-  global_install = issuperuser ();
+function install (files, handle_deps, autoload, prefix, verbose, local_list, global_list, global_install)
 
   # Check that the directory in prefix exist. If it doesn't: create it!
   if (! exist (prefix, "dir"))
@@ -299,66 +422,70 @@
     for i = 1:length (files)
       tgz = files{i};
 
-      ## Create a temporary directory 
-      tmpdir = tmpnam ();
-      tmpdirs{end+1} = tmpdir;
-      if (verbose)
-	printf ("mkdir (%s)\n", tmpdir);
-      endif
-      [status, msg] = mkdir (tmpdir);
-      if (status != 1)
-	error ("couldn't create temporary directory: %s", msg);
-      endif
-
-      ## Uncompress the package
-      if (verbose)
-	printf ("untar (%s, %s)\n", tgz, tmpdir);
-      endif
-      untar (tgz, tmpdir);
+      if (exist (tgz, "file"))
+	## Create a temporary directory 
+	tmpdir = tmpnam ();
+	tmpdirs{end+1} = tmpdir;
+        if (verbose)
+	  printf ("mkdir (%s)\n", tmpdir);
+	endif
+	[status, msg] = mkdir (tmpdir);
+	if (status != 1)
+	  error ("couldn't create temporary directory: %s", msg);
+	endif
 
-      ## Get the name of the directories produced by tar
-      [dirlist, err, msg] = readdir (tmpdir);
-      if (err)
-	error ("couldn't read directory produced by tar: %s", msg);
-      endif
-
-      if (length (dirlist) > 3)
-	error ("bundles of packages are not allowed")
-      endif
+	## Uncompress the package
+	if (verbose)
+	  printf ("untar (%s, %s)\n", tgz, tmpdir);
+	endif
+	untar (tgz, tmpdir);
 
-      ## the two first entries of dirlist are "." and ".."
-      for k = 3:length (dirlist)
-	packdir = fullfile (tmpdir, dirlist{k});
-	packdirs{end+1} = packdir;
-
-	## Make sure the package contains necessary files
-	verify_directory (packdir);
+	## Get the name of the directories produced by tar
+	[dirlist, err, msg] = readdir (tmpdir);
+	if (err)
+	  error ("couldn't read directory produced by tar: %s", msg);
+	endif
 
-	## Read the DESCRIPTION file
-	filename = fullfile (packdir, "DESCRIPTION");
-	desc = get_description (filename);
-
-	## Verify that package name corresponds with filename
-	[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);
+	if (length (dirlist) > 3)
+	  error ("bundles of packages are not allowed")
 	endif
 
-	## Set default installation directory
-	desc.dir = fullfile (prefix, strcat (desc.name, "-", desc.version));
+	## the two first entries of dirlist are "." and ".."
+	for k = 3:length (dirlist)
+	  packdir = fullfile (tmpdir, dirlist{k});
+	  packdirs{end+1} = packdir;
 
-	## Save desc
-	descriptions{end+1} = desc;
+	  ## Make sure the package contains necessary files
+	  verify_directory (packdir);
+
+	  ## Read the DESCRIPTION file
+	  filename = fullfile (packdir, "DESCRIPTION");
+	  desc = get_description (filename);
 
-	## Are any of the new packages already installed?
-	## If so we'll remove the old version.
-	for j = 1:length (packages)
-	  if (strcmp (packages{j}.name, desc.name))
-	    packages_to_uninstall(end+1) = j;
+	  ## Verify that package name corresponds with filename
+	  [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);
 	  endif
-	endfor
-      endfor        
+
+	  ## Set default installation directory
+	  desc.dir = fullfile (prefix, strcat (desc.name, "-", desc.version));
+
+	  ## Save desc
+	  descriptions{end+1} = desc;
+
+	  ## Are any of the new packages already installed?
+	  ## If so we'll remove the old version.
+	  for j = 1:length (packages)
+	    if (strcmp (packages{j}.name, desc.name))
+	      packages_to_uninstall(end+1) = j;
+	    endif
+	  endfor
+	endfor        
+      else
+	warning ("file %s does not exist", tgz);
+      endif
     endfor
   catch
     ## Something went wrong, delete tmpdirs
@@ -416,7 +543,7 @@
   try
     for i = packages_to_uninstall
       uninstall ({installed_packages{i}.name}, false, verbose, local_list, 
-		 global_list);
+		 global_list, global_install);
     endfor
   catch
     ## Something went wrong, delete tmpdirs
@@ -514,11 +641,12 @@
   endif
 endfunction
 
-function uninstall (pkgnames, handle_deps, verbose, local_list, global_list)
+function uninstall (pkgnames, handle_deps, verbose, local_list, 
+		    global_list, global_install)
   ## Get the list of installed packages
   [local_packages, global_packages] = installed_packages(local_list, 
 							 global_list);
-  if (issuperuser ())
+  if (global_install)
     installed_packages = {local_packages{:}, global_packages{:}};
   else
     installed_packages = local_packages;
@@ -535,7 +663,7 @@
 
   ## Are all the packages that should be uninstalled already installed?
   if (length (delete_idx) != length (pkgnames))
-    if (issuperuser ())
+    if (global_install)
       ## Try again for a locally installed package
       installed_packages = local_packages
 
@@ -610,7 +738,7 @@
   endfor
 
   ## Write a new ~/.octave_packages
-  if (issuperuser ())
+  if (global_install)
     if (length (remaining_packages) == 0)
       unlink (global_list);
     else
@@ -665,8 +793,12 @@
     src = fullfile (packdir, "src");
     ## configure
     if (exist (fullfile (src, "configure"), "file"))
-      [status, output] = system (strcat ("cd ", src, "; ./configure --prefix=",
-					 desc.dir));
+      [status, output] = shell (strcat ("cd ", src, "; ./configure --prefix=\"",
+					 desc.dir, "\"",
+					 " CC=", octave_config_info ("CC"),
+					 " CXX=", octave_config_info ("CXX"),
+					 " AR=", octave_config_info ("AR"),
+					 " RANLIB=", octave_config_info ("RANLIB")));
       if (verbose)
 	printf("%s", output);
       endif
@@ -678,8 +810,8 @@
 
     ## make
     if (exist (fullfile (src, "Makefile"), "file"))
-      [status, output] = system (strcat ("export INSTALLDIR=", desc.dir,
-					 "; make -C ", src));
+      [status, output] = shell (strcat ("export INSTALLDIR=\"", desc.dir,
+					 "\"; make -C ", src));
       if (verbose)
 	printf("%s", output);
       endif
@@ -978,7 +1110,12 @@
 endfunction
 
 function out = issuperuser ()
-  out = strcmp (getenv("USER"), "root");
+  if (ispc () && ! isunix ())
+    out = 1;
+  else
+    ## Need to be a bit presistent in probing superuser
+    out = (geteuid() == 0);
+  endif
 endfunction
 
 ## This function makes sure the package contains the
@@ -1275,9 +1412,9 @@
   endif  
 
   ## Now check if the package is loaded
-  tmppath = path();
+  tmppath = strrep (path(), "\\", "/");
   for i = 1:length (installed_packages)
-    if (regexp (tmppath, installed_packages{i}.dir))
+    if (regexp (tmppath, strrep (installed_packages{i}.dir, "\\", "/")))
       installed_packages{i}.loaded = true;
     else
       installed_packages{i}.loaded = false;
@@ -1520,3 +1657,29 @@
    octave_config_info("api_version")];
   arch = _arch;
 endfunction
+
+function [status, output] = shell (cmd)
+
+  persistent have_sh;
+
+  cmd = strrep (cmd, "\\", "/");
+  disp (cmd);
+  if (ispc () && ! isunix ())
+    if (isempty(have_sh))
+      if (system("sh.exe -c \"exit\""))
+        have_sh = false;
+      else
+        have_sh = true;
+      endif
+    endif
+    if (have_sh)
+      [status, output] = system (["sh.exe -c \"", cmd, "\""]);
+    else
+      error ("Can not find the command shell")
+    endif
+  else
+    [status, output] = system (cmd);
+  endif
+  disp(output);
+
+endfunction