1######################################################################## 2## 3## Copyright (C) 2005-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {} uninstall (@var{pkgnames}, @var{handle_deps}, @var{verbose}, @var{local_list}, @var{global_list}, @var{global_install}) 28## Undocumented internal function. 29## @end deftypefn 30 31function uninstall (pkgnames, handle_deps, verbose, local_list, 32 global_list, global_install) 33 34 ## Get the list of installed packages. 35 [local_packages, global_packages] = installed_packages(local_list, 36 global_list); 37 if (global_install) 38 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; 39 else 40 installed_pkgs_lst = local_packages; 41 endif 42 43 num_packages = length (installed_pkgs_lst); 44 delete_idx = []; 45 for i = 1:num_packages 46 cur_name = installed_pkgs_lst{i}.name; 47 if (any (strcmp (cur_name, pkgnames))) 48 delete_idx(end+1) = i; 49 endif 50 endfor 51 52 ## Are all the packages that should be uninstalled already installed? 53 if (length (delete_idx) != length (pkgnames)) 54 if (global_install) 55 ## Try again for a locally installed package. 56 installed_pkgs_lst = local_packages; 57 58 num_packages = length (installed_pkgs_lst); 59 delete_idx = []; 60 for i = 1:num_packages 61 cur_name = installed_pkgs_lst{i}.name; 62 if (any (strcmp (cur_name, pkgnames))) 63 delete_idx(end+1) = i; 64 endif 65 endfor 66 if (length (delete_idx) != length (pkgnames)) 67 ## FIXME: We should have a better error message. 68 warning ("some of the packages you want to uninstall are not installed"); 69 endif 70 else 71 ## FIXME: We should have a better error message. 72 warning ("some of the packages you want to uninstall are not installed"); 73 endif 74 endif 75 76 if (isempty (delete_idx)) 77 warning ("no packages will be uninstalled"); 78 else 79 80 ## Compute the packages that will remain installed. 81 idx = setdiff (1:num_packages, delete_idx); 82 remaining_packages = {installed_pkgs_lst{idx}}; 83 to_delete_packages = {installed_pkgs_lst{delete_idx}}; 84 85 ## Check dependencies. 86 if (handle_deps) 87 error_text = ""; 88 for i = 1:length (remaining_packages) 89 desc = remaining_packages{i}; 90 bad_deps = get_unsatisfied_deps (desc, to_delete_packages, true); 91 92 ## Will the uninstallation break any dependencies? 93 if (! isempty (bad_deps)) 94 for i = 1:length (bad_deps) 95 dep = bad_deps{i}; 96 error_text = [error_text " " desc.name " needs " ... 97 dep.package " " dep.operator " " dep.version "\n"]; 98 endfor 99 endif 100 endfor 101 102 if (! isempty (error_text)) 103 error ("the following dependencies where unsatisfied:\n %s", error_text); 104 endif 105 endif 106 107 ## Delete the directories containing the packages. 108 for i = delete_idx 109 desc = installed_pkgs_lst{i}; 110 ## If an 'on_uninstall.m' exist, call it! 111 if (exist (fullfile (desc.dir, "packinfo", "on_uninstall.m"), "file")) 112 wd = pwd (); 113 cd (fullfile (desc.dir, "packinfo")); 114 on_uninstall (desc); 115 cd (wd); 116 endif 117 ## Do the actual deletion. 118 if (desc.loaded) 119 rmpath (desc.dir); 120 if (isfolder (getarchdir (desc))) 121 rmpath (getarchdir (desc)); 122 endif 123 endif 124 if (isfolder (desc.dir)) 125 [status, msg] = rmdir (desc.dir, "s"); 126 if (status != 1 && isfolder (desc.dir)) 127 error ("couldn't delete directory %s: %s", desc.dir, msg); 128 endif 129 [status, msg] = rmdir (getarchdir (desc), "s"); 130 if (status != 1 && isfolder (getarchdir (desc))) 131 error ("couldn't delete directory %s: %s", getarchdir (desc), msg); 132 endif 133 if (dirempty (desc.archprefix)) 134 rmdir (desc.archprefix, "s"); 135 endif 136 else 137 warning ("directory %s previously lost", desc.dir); 138 endif 139 endfor 140 141 ## Write a new ~/.octave_packages. 142 if (global_install) 143 if (length (remaining_packages) == 0) 144 unlink (global_list); 145 else 146 global_packages = save_order (remaining_packages); 147 if (ispc) 148 ## On Windows ensure LFN paths are saved rather than 8.3 style paths 149 global_packages = standardize_paths (global_packages); 150 endif 151 global_packages = make_rel_paths (global_packages); 152 save (global_list, "global_packages"); 153 endif 154 else 155 if (length (remaining_packages) == 0) 156 unlink (local_list); 157 else 158 local_packages = save_order (remaining_packages); 159 if (ispc) 160 local_packages = standardize_paths (local_packages); 161 endif 162 save (local_list, "local_packages"); 163 endif 164 endif 165 endif 166 167endfunction 168