Better management of the dependencies
Pierre MARECHAL [Thu, 25 Jun 2009 14:43:05 +0000 (16:43 +0200)]
scilab/modules/atoms/macros/atomsInstall.sci
scilab/modules/atoms/macros/atomsRemove.sci
scilab/modules/atoms/macros/atoms_internals/atomsGetDepParents.sci
scilab/modules/atoms/macros/atoms_internals/atomsInstallList.sci
scilab/modules/atoms/macros/atoms_internals/atomsInstallUnregister.sci
scilab/modules/atoms/macros/atoms_internals/atomsRemoveList.sci [new file with mode: 0644]

index 332b113..ce7cfd0 100644 (file)
@@ -116,14 +116,15 @@ function result = atomsInstall(packages,allusers)
        // =========================================================================
        [install_package_list,dependency_tree] = atomsInstallList(packages);
        
-       // Loop on install_package_list to print if a package has to be installed or not
+       // Loop on install_package_list to print if a package has to be installed
+       // or not
        // =========================================================================
        if VERBOSE 
                for i=1:size(install_package_list(:,1),"*")
                        if install_package_list(i,1) == "+" then
-                               mprintf("\t%s (%s) will be installed\n",install_package_list(i,2),install_package_list(i,3));
+                               mprintf("\t%s (%s) will be installed\n",install_package_list(i,3),install_package_list(i,4));
                        elseif install_package_list(i,1) == "~" then
-                               mprintf("\t%s (%s) is already installed and up-to-date\n",install_package_list(i,2),install_package_list(i,3));
+                               mprintf("\t%s (%s) is already installed and up-to-date\n",install_package_list(i,3),install_package_list(i,4));
                        end
                end
        end
@@ -133,9 +134,9 @@ function result = atomsInstall(packages,allusers)
        
        for i=1:size(install_package_list(:,1),"*")
                
-               this_package_details = dependency_tree(install_package_list(i,2));
-               this_package_name    = this_package_details("Toolbox");
-               this_package_version = this_package_details("Version");
+               this_package_details = dependency_tree(install_package_list(i,3));
+               this_package_name    = install_package_list(i,3);
+               this_package_version = install_package_list(i,4);
                
                if install_package_list(i,1) <> "+" then
                        continue;
@@ -244,9 +245,9 @@ function result = atomsInstall(packages,allusers)
                
                unarchive_dir = "";
                
-               for i=1:size(dir_list_after,"*")
-                       if find(dir_list_after(i) == dir_list_before) == [] then
-                               unarchive_dir = dir_list_after(i);
+               for j=1:size(dir_list_after,"*")
+                       if find(dir_list_after(j) == dir_list_before) == [] then
+                               unarchive_dir = dir_list_after(j);
                                break;
                        end
                end
@@ -273,12 +274,12 @@ function result = atomsInstall(packages,allusers)
                // Register the successfully installed package
                // =====================================================================
                
-               if grep(packages,"/$"+this_package_name+"\s/","r") == [] then
+               if install_package_list(i,2) == "U" then
+                       // Intentionnaly Installed
+                       this_package_status = "I";
+               else
                        // Automaticaly installed
                        this_package_status = "A";
-               else
-                       // Volontary Installed
-                       this_package_status = "I";
                end
                
                atomsInstallRegister(this_package_name,this_package_version,this_package_status,allusers);
index 67b8785..1475b18 100644 (file)
@@ -92,116 +92,38 @@ function result = atomsRemove(packages,allusers)
                end
        end 
        
-       // Loop on packages and to build the list of package to uninstall
+       // Build the list of package to Uninstall
        // =========================================================================
+       remove_package_list = atomsRemoveList(packages,allusers);
        
-       packagesToUninstall_W = []; // Wanted packages
-       packagesToUninstall_D = []; // Dependency packages
-       packagesToUninstall_B = []; // Broken packages
        
-       for i=1:size(packages,"*")
-               
-               package = packages(i);
-               
-               if size(regexp(package,"/\s/") ,"*" ) > 1 then
-                       error(msprintf(gettext("%s: Wrong value for input argument #%d: it must contain at most one space.\n"),"atomsInstall",1));
-               end
-               
-               if size(regexp(package,"/\s/") ,"*" ) == 0 then
-                       // Just the toolbox name is specified
-                       package_names(i)    = package;
-                       package_versions(i) = "";
-               else
-                       // A version is specified
-                       space               = regexp(package,"/\s/");
-                       package_names(i)    = part(package,[1:space-1]);
-                       package_versions(i) = part(package,[space+1:length(package)]);
-               end
-               
-               // Ok, The syntax is correct, Now check if the package is really installed
-               if ~ atomsIsInstalled(package_names(i),package_versions(i)) then
-                       continue;
-               end
-               
-               // get the list of the versions of this package to uninstall
-               
-               if isempty(package_versions(i)) then
-                       // uninstall all version of this toolbox
-                       this_package_versions = atomsGetInstalledVers(package_names(i));
-               else
-                       // Just uninstall the specified version
-                       this_package_versions = package_versions(i);
-               end
-               
-               // Loop on this version list
-               
-               for j=1:size(this_package_versions,"*")
-                       
-                       packagesToUninstall_W = [ packagesToUninstall_W ; atomsGetInstalledDetails( package_names(i),this_package_versions(j)) ];
-                       
-                       if VERBOSE then
-                               mprintf( "\t%s (%s) will be removed\n" , package_names(i) , this_package_versions(j) );
-                       end
-                       
-                       // Establish the dependency list to uninstall
-                       // =================================================================
-                       
-                       // Get the dependencies of this package
-                       this_package_child_deps = atomsGetDepChilds(package_names(i),this_package_versions(j));
-                       
-                       // Loop on dependency childs
-                       for k=1:size(this_package_child_deps(:,1),"*")
-                               
-                               // If this dependence is automatically installed, add it to the
-                               // list of package to uninstall
-                               
-                               if atomsGetInstalledStatus( this_package_child_deps(k,1) , this_package_child_deps(k,2) ) == "A" then
-                                       packagesToUninstall_D = [ packagesToUninstall_D ; atomsGetInstalledDetails(this_package_child_deps(k,1),this_package_child_deps(k,2)) ];
-                                       
-                                       if VERBOSE then
-                                               mprintf( "\t%s (%s) will be removed\n" , this_package_child_deps(k,1) , this_package_child_deps(k,2) );
-                                       end
-                               end
-                               
-                       end
-                       
-                       // Establish the broken list to uninstall
-                       // =================================================================
-                       
-                       // Get the dependencies of this package
-                       this_package_parent_deps = atomsGetDepParents(package_names(i),this_package_versions(j));
-                       
-                       // Loop on dependency parents
-                       for k=1:size(this_package_parent_deps(:,1),"*")
-                               
-                               // If this dependence is automatically installed, add it to the
-                               // list of package to uninstall
-                               packagesToUninstall_B = [ packagesToUninstall_B ; atomsGetInstalledDetails(this_package_parent_deps(k,1) , this_package_parent_deps(k,2)) ];
-                               
+       // Loop on remList to print if a package has to be remove
+       // or not
+       // =========================================================================
+       if VERBOSE 
+               for i=1:size(remove_package_list(:,1),"*")
+                       if remove_package_list(i,1) == "-" then
+                               mprintf("\t%s (%s) will be removed\n",remove_package_list(i,3),remove_package_list(i,4));
+                       elseif (remove_package_list(i,1) == "~") & (remove_package_list(i,1) == "B") then
+                               mprintf("\t%s (%s) cannot be removed and will be broken\n",remove_package_list(i,3),remove_package_list(i,4));
                        end
-                       
                end
-               
        end
        
-       // Loop on packages to filter the list of package to uninstall
-       // =========================================================================
-       
-       // All wanted packages must be uninstalled
-       packagesToUninstall = packagesToUninstall_W;
-       
-       // For the moment, All dependency packages must be uninstalled
-       packagesToUninstall = [ packagesToUninstall ; packagesToUninstall_D ];
-       
        // Now we have the list of package that have to be uninstalled
        // =========================================================================
        
-       for i=1:size(packagesToUninstall(:,1),"*")
+       for i=1:size(remove_package_list(:,1),"*")
+               
+               // If the package must be keeped, the job is done
+               if remove_package_list(i,1) <> "-" then
+                       continue;
+               end
                
-               this_package_name      = packagesToUninstall(i,1);
-               this_package_version   = packagesToUninstall(i,2);
-               this_package_directory = packagesToUninstall(i,4);
+               this_package_name      = remove_package_list(i,3);
+               this_package_version   = remove_package_list(i,4);
                this_package_insdet    = atomsGetInstalledDetails(this_package_name,this_package_version);
+               this_package_directory = this_package_insdet(4);
                
                if VERBOSE then
                        mprintf( "\tRemoving %s (%s) ... " , this_package_name , this_package_version );
@@ -213,7 +135,7 @@ function result = atomsRemove(packages,allusers)
                        (grep(this_package_directory,pathconvert(SCIHOME)) == []) then
                        
                        chdir(initialpath);
-                       error(msprintf(gettext("%s: The directory of this package (%s-%s) is located neither in SCI nor in SCIHOME. For security reason, ATOMS refuses to delete this directory.\n"),"atomsRemove",packagesToUninstall(1,1),packagesToUninstall(1,2)));
+                       error(msprintf(gettext("%s: The directory of this package (%s-%s) is located neither in SCI nor in SCIHOME. For security reason, ATOMS refuses to delete this directory.\n"),"atomsRemove",this_package_name,this_package_version));
                end
                
                uninstall_status = rmdir(this_package_directory,"s");
index 8965063..b710bfc 100644 (file)
@@ -18,29 +18,29 @@ function packages = atomsGetDepParents(name,version,allusers)
        // =========================================================================
        
        if rhs < 2 | rhs > 3 then
-               error(msprintf(gettext("%s: Wrong number of input argument: %d to %d expected.\n"),"atomsGetDepChilds",2,3));
+               error(msprintf(gettext("%s: Wrong number of input argument: %d to %d expected.\n"),"atomsGetDepParents",2,3));
        end
        
        // Check input parameters type
        // =========================================================================
        
        if type(name) <> 10 then
-               error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsGetDepChilds",1));
+               error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsGetDepParents",1));
        end
        
        if type(version)<>10  then
-               error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsGetDepChilds",2));
+               error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsGetDepParents",2));
        end
        
        // Check input parameters dimensions
        // =========================================================================
        
        if size(name,"*") <> 1 then
-               error(msprintf(gettext("%s: Wrong size for input argument #%d: A single string expected.\n"),"atomsGetDepChilds",1));
+               error(msprintf(gettext("%s: Wrong size for input argument #%d: A single string expected.\n"),"atomsGetDepParents",1));
        end
        
        if size(version,"*")<>1  then
-               error(msprintf(gettext("%s: Wrong size for input argument #%d: A single string expected.\n"),"atomsGetDepChilds",2));
+               error(msprintf(gettext("%s: Wrong size for input argument #%d: A single string expected.\n"),"atomsGetDepParents",2));
        end
        
        // All user management
@@ -51,7 +51,7 @@ function packages = atomsGetDepParents(name,version,allusers)
        else
                // Just check if it's a boolean
                if type(allusers) <> 4 then
-                       error(msprintf(gettext("%s: Wrong type for input argument #%d: A boolean expected.\n"),"atomsGetDepChilds",3));
+                       error(msprintf(gettext("%s: Wrong type for input argument #%d: A boolean expected.\n"),"atomsGetDepParents",3));
                end
        end
        
index f1c2d30..b8cf4d0 100644 (file)
@@ -9,13 +9,17 @@
 
 // Internal function
 
-// Give the matrix of the toolbox to install :
+// Return a matrix that list the changes caused by the installation of one or
+// more packages
+
+// !~  U  toolbox_4  1.0  !
+// !                      !
+// !~     toolbox_2  1.3  !
+// !                      !
+// !~     toolbox_1  1.9  !
+// !                      !
+// !~  U  toolbox_5  1.0  !
 
-// !+  toolbox_3  1.6  !
-// !                   !
-// !~  toolbox_2  1.5  !
-// !                   !
-// !~  toolbox_1  1.9  !
 
 function [insList,depTree] = atomsInstallList(packages)
        
@@ -89,7 +93,16 @@ function [insList,depTree] = atomsInstallList(packages)
                
                // Concatenate the tree with the existing one
                depTree = atomsCatTree( depTree , tree );
-               
+       end
+       
+       // Add a field to detect later if it's the toolbox is automaticaly installed
+       // or if it's a user choice
+       // =========================================================================
+       
+       for i=1:size(package_names,"*")
+               this_package_details                = depTree(package_names(i));
+               this_package_details("user_choice") = %T;
+               depTree(package_names(i))           = this_package_details;
        end
        
        // Now we have the list of package that have to be installed
@@ -107,11 +120,17 @@ function [insList,depTree] = atomsInstallList(packages)
                this_package_name    = this_package_details("Toolbox");
                this_package_version = this_package_details("Version");
                
+               if isfield(this_package_details,"user_choice") & this_package_details("user_choice") then
+                       this_package_user_choice = "U"; // stand for User Choice
+               else
+                       this_package_user_choice = ""; // stand for User Choice
+               end
+               
                to_install = %F; 
                
                if atomsIsInstalled(this_package_name) then
                        vers = atomsGetInstalledVers(mandatory_packages(i));
-                       if atomsVersionCompare( vers(1) , this_package_version ) < 0 then
+                       if find( vers == this_package_version ) == [] then
                                to_install = %T;
                        end
                else
@@ -119,9 +138,9 @@ function [insList,depTree] = atomsInstallList(packages)
                end
                
                if to_install then
-                       insList = [ insList ; "+" this_package_name this_package_version ];
+                       insList = [ insList ; "+" this_package_user_choice this_package_name this_package_version ];
                else
-                       insList = [ insList ; "~" this_package_name this_package_version ];
+                       insList = [ insList ; "~" this_package_user_choice this_package_name this_package_version ];
                end
                
        end
index 8823c16..25b1c08 100644 (file)
@@ -139,9 +139,6 @@ function nbDel = atomsInstallUnregister(name,version,allusers)
                                
                                if installed_deps_in(k) == "["+name(j)+" - "+version(j)+"]" then
                                        found = 1;
-                               end
-                               
-                               if found == 1 then
                                        continue;
                                end
                                
@@ -149,6 +146,10 @@ function nbDel = atomsInstallUnregister(name,version,allusers)
                                        found = 0;
                                end
                                
+                               if found == 1 then
+                                       continue;
+                               end
+                               
                                if found == 0 then
                                        installed_deps_out = [ installed_deps_out , installed_deps_in(k) ];
                                end
diff --git a/scilab/modules/atoms/macros/atoms_internals/atomsRemoveList.sci b/scilab/modules/atoms/macros/atoms_internals/atomsRemoveList.sci
new file mode 100644 (file)
index 0000000..f955bc2
--- /dev/null
@@ -0,0 +1,237 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2009 - DIGITEO - Pierre MARECHAL <pierre.marechal@scilab.org>
+//
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution.  The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+
+// Internal function
+
+// Return a matrix that list the changes caused by the uninstallation of one or
+// more packages
+
+// -->A = atomsRemoveList('toolbox_2',%F)
+//  A  =
+//  
+// !-  U  toolbox_2  1.5  !
+// !                      !
+// !-  U  toolbox_2  1.3  !
+// !                      !
+// !-  B  toolbox_3  1.6  !
+// !                      !
+// !-  B  toolbox_5  1.0  !
+// !                      !
+// !-  B  toolbox_4  1.0  !
+
+// -  : The package will be removed
+// ~  : The package will be keeped
+
+// U  : The package is intentionnaly removed
+// P  : The package is a parent of one package
+// C  : The package is a child of one package
+// B  : The package will be broken (It's a parent but cannot be uninstall)
+
+function remList = atomsRemoveList(packages,allusers)
+       
+       remList = [];
+       
+       // Save the initial path
+       // =========================================================================
+       initialpath = pwd();
+       
+       // Check input parameters
+       // =========================================================================
+       
+       rhs = argn(2);
+       
+       if rhs > 2 then
+               error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"atomsRemoveList",1,2))
+       end
+       
+       if type(packages) <> 10 then
+               error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsRemoveList",1));
+       end
+       
+       // Apply changes for all users or just for me ?
+       // =========================================================================
+       
+       if rhs == 1 then
+               // By default, uninstall the package (if we have write access
+               // of course !)
+               if atomsAUWriteAccess() then
+                       allusers = %T; 
+               else
+                       allusers = %F;
+               end
+       
+       else
+               // Just check if it's a boolean
+               if type(allusers) <> 4 then
+                       chdir(initialpath);
+                       error(msprintf(gettext("%s: Wrong type for input argument #%d: A boolean expected.\n"),"atomsRemoveList",2));
+               end
+               
+               // Check if we have the write access
+               if allusers & ~ atomsAUWriteAccess() then
+                       chdir(initialpath);
+                       error(msprintf(gettext("%s: You haven''t write access on this directory : %s.\n"),"atomsRemoveList",2,pathconvert(SCI+"/.atoms")));
+               end
+       end
+       
+       // Loop on packages and to build the list of package to uninstall
+       // =========================================================================
+       
+       packages = stripblanks(packages);
+       
+       // First step : List the packages wanted by the user
+       
+       for i=1:size(packages,"*")
+               
+               package = packages(i);
+               
+               if size(regexp(package,"/\s/") ,"*" ) > 1 then
+                       error(msprintf(gettext("%s: Wrong value for input argument #%d: it must contain at most one space.\n"),"atomsInstall",1));
+               end
+               
+               if size(regexp(package,"/\s/") ,"*" ) == 0 then
+                       // Just the toolbox name is specified
+                       package_names(i)    = package;
+                       package_versions(i) = "";
+               else
+                       // A version is specified
+                       space               = regexp(package,"/\s/");
+                       package_names(i)    = part(package,[1:space-1]);
+                       package_versions(i) = part(package,[space+1:length(package)]);
+               end
+               
+               // Ok, The syntax is correct, Now check if the package is really installed
+               if ~ atomsIsInstalled(package_names(i),package_versions(i)) then
+                       continue;
+               end
+               
+               // get the list of the versions of this package to uninstall
+               
+               if isempty(package_versions(i)) then
+                       // uninstall all version of this toolbox
+                       this_package_versions = atomsGetInstalledVers(package_names(i));
+               else
+                       // Just uninstall the specified version
+                       this_package_versions = package_versions(i);
+               end
+               
+               for j=1:size(this_package_versions,"*")
+                       remList = [ remList ; "-" "U" package_names(i) this_package_versions(j) ];
+               end
+               
+       end
+       
+       // Second Step : List the packages that depends of the uninstalled packages
+       // =========================================================================
+       
+       packages = remList;
+       for i=1:size(packages(:,1),"*")
+               
+               this_package_name    = packages(i,3);
+               this_package_version = packages(i,4);
+               
+               // Get the parents of this toolbox
+               // (inevitably removed, unless we have not the right)
+               // ----------------------------------------------------
+               
+               this_package_parents = atomsGetDepParents(this_package_name,this_package_version);
+               
+               for j=1:size(this_package_parents(:,1),"*")
+                       
+                       this_parent_name    = this_package_parents(j,1);
+                       this_parent_version = this_package_parents(j,2);
+                       
+                       // Check if we have the right to remove this package
+                       // If not, tag it as Broken (for later)
+                       if ~allusers then
+                               details = atomsGetInstalledDetails(this_parent_name,this_parent_version);
+                               if details(3) == "allusers" then
+                                       remList = [ remList ; "~" "B" this_parent_name this_parent_version ]; // B stands for "Broken"
+                                       continue
+                               end
+                       end
+                       
+                       // Add this parent to the list
+                       if find(remList(:,3)+" - "+remList(:,4) == this_parent_name+" - "+this_parent_version) == [] then
+                               remList = [ remList ; "-" "P" this_parent_name this_parent_version ];  // P stands for "Parent"
+                       end
+                       
+               end
+               
+               // Get the childs of this toolbox
+               // ----------------------------------------------
+               
+               this_package_childs = atomsGetDepChilds(this_package_name,this_package_version);
+               
+               for j=1:size(this_package_childs(:,1),"*")
+                       
+                       this_child_name    = this_package_childs(j,1);
+                       this_child_version = this_package_childs(j,2);
+                       
+                       // Check if we have the right to remove this package
+                       // If not, Do not add it to the list
+                       if ~allusers then
+                               details = atomsGetInstalledDetails(this_child_name,this_child_version);
+                               if details(3) == "allusers" then
+                                       continue
+                               end
+                       end
+                       
+                       if find(remList(:,3)+" - "+remList(:,4) == this_child_name+" - "+this_child_version) == [] then
+                               remList = [ remList ; "-" "C" this_child_name this_child_version ]; // C stands for "Child" 
+                       end
+                       
+               end
+               
+       end
+       
+       // Third Step : Loop on childs check if we uninstall it or not
+       // =========================================================================
+       
+       packages = remList(find(remList(:,2)=="C"),:);
+       
+       for i=1:size(remList(:,1),"*")
+               
+               // This is not a Child package :
+               // => continue
+               // ----------------------------------------------
+               
+               if remList(i,2) <> "C" then
+                       continue;
+               end
+               
+               this_package_name    = remList(i,3);
+               this_package_version = remList(i,4);
+               
+               // The package has been intentionnaly installed :
+               // => Do not install it
+               // ----------------------------------------------
+               
+               if atomsGetInstalledStatus(this_package_name,this_package_version) == "I" then
+                       remList(i,1) = "~";
+               end
+               
+               // Get the parents of this toolbox
+               // ----------------------------------------------
+               
+               this_package_parents = atomsGetDepParents(this_package_name,this_package_version);
+               
+               for j=1:size(this_package_parents(:,1),"*")
+                       
+                       if find(remList(:,3)+" - "+remList(:,4) == this_package_parents(j,1)+" - "+this_package_parents(j,2)) == [] then
+                               // One of the parent is not the remove list
+                               // => do not install it
+                               remList(i,1) = "~";
+                               continue;
+                       end
+               end
+               
+       end
+       
+endfunction