From 5b138287373cacaf76442864973e2b16b65387ee Mon Sep 17 00:00:00 2001 From: Pierre MARECHAL Date: Thu, 25 Jun 2009 16:43:05 +0200 Subject: [PATCH] Better management of the dependencies --- scilab/modules/atoms/macros/atomsInstall.sci | 27 +-- scilab/modules/atoms/macros/atomsRemove.sci | 120 ++-------- .../macros/atoms_internals/atomsGetDepParents.sci | 12 +- .../macros/atoms_internals/atomsInstallList.sci | 39 +++- .../atoms_internals/atomsInstallUnregister.sci | 7 +- .../macros/atoms_internals/atomsRemoveList.sci | 237 ++++++++++++++++++++ 6 files changed, 311 insertions(+), 131 deletions(-) create mode 100644 scilab/modules/atoms/macros/atoms_internals/atomsRemoveList.sci diff --git a/scilab/modules/atoms/macros/atomsInstall.sci b/scilab/modules/atoms/macros/atomsInstall.sci index 332b113..ce7cfd0 100644 --- a/scilab/modules/atoms/macros/atomsInstall.sci +++ b/scilab/modules/atoms/macros/atomsInstall.sci @@ -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); diff --git a/scilab/modules/atoms/macros/atomsRemove.sci b/scilab/modules/atoms/macros/atomsRemove.sci index 67b8785..1475b18 100644 --- a/scilab/modules/atoms/macros/atomsRemove.sci +++ b/scilab/modules/atoms/macros/atomsRemove.sci @@ -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"); diff --git a/scilab/modules/atoms/macros/atoms_internals/atomsGetDepParents.sci b/scilab/modules/atoms/macros/atoms_internals/atomsGetDepParents.sci index 8965063..b710bfc 100644 --- a/scilab/modules/atoms/macros/atoms_internals/atomsGetDepParents.sci +++ b/scilab/modules/atoms/macros/atoms_internals/atomsGetDepParents.sci @@ -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 diff --git a/scilab/modules/atoms/macros/atoms_internals/atomsInstallList.sci b/scilab/modules/atoms/macros/atoms_internals/atomsInstallList.sci index f1c2d30..b8cf4d0 100644 --- a/scilab/modules/atoms/macros/atoms_internals/atomsInstallList.sci +++ b/scilab/modules/atoms/macros/atoms_internals/atomsInstallList.sci @@ -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 diff --git a/scilab/modules/atoms/macros/atoms_internals/atomsInstallUnregister.sci b/scilab/modules/atoms/macros/atoms_internals/atomsInstallUnregister.sci index 8823c16..25b1c08 100644 --- a/scilab/modules/atoms/macros/atoms_internals/atomsInstallUnregister.sci +++ b/scilab/modules/atoms/macros/atoms_internals/atomsInstallUnregister.sci @@ -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 index 0000000..f955bc2 --- /dev/null +++ b/scilab/modules/atoms/macros/atoms_internals/atomsRemoveList.sci @@ -0,0 +1,237 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - DIGITEO - Pierre MARECHAL +// +// 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 -- 1.7.9.5