Fix bug in uninstall (regression in 0fc3b58)
				
					
				
			This commit is contained in:
		| @@ -22,13 +22,17 @@ | |||||||
| # along with this program; if not, write to the Free Software Foundation, | # along with this program; if not, write to the Free Software Foundation, | ||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
|  | import sys | ||||||
| from external import argparse | from external import argparse | ||||||
|  |  | ||||||
| import llnl.util.tty as tty | import llnl.util.tty as tty | ||||||
|  | from llnl.util.tty.colify import colify | ||||||
|  |  | ||||||
| import spack | import spack | ||||||
| import spack.cmd | import spack.cmd | ||||||
| import spack.packages | import spack.packages | ||||||
|  | from spack.cmd.find import display_specs | ||||||
|  | from spack.package import PackageStillNeededError | ||||||
|  |  | ||||||
| description="Remove an installed package" | description="Remove an installed package" | ||||||
|  |  | ||||||
| @@ -57,13 +61,14 @@ def uninstall(parser, args): | |||||||
|     for spec in specs: |     for spec in specs: | ||||||
|         matching_specs = spack.db.get_installed(spec) |         matching_specs = spack.db.get_installed(spec) | ||||||
|         if not args.all and len(matching_specs) > 1: |         if not args.all and len(matching_specs) > 1: | ||||||
|             args =  ["%s matches multiple packages." % spec, |             tty.error("%s matches multiple packages:" % spec) | ||||||
|                      "Matching packages:"] |             print | ||||||
|             args += ["  " + str(s) for s in matching_specs] |             display_specs(matching_specs, long=True) | ||||||
|             args += ["You can either:", |             print | ||||||
|                      "  a) Use spack uninstall -a to uninstall ALL matching specs, or", |             print "You can either:" | ||||||
|                      "  b) use a more specific spec."] |             print "  a) Use a more specific spec, or" | ||||||
|             tty.die(*args) |             print "  b) use spack uninstall -a to uninstall ALL matching specs." | ||||||
|  |             sys.exit(1) | ||||||
|  |  | ||||||
|         if len(matching_specs) == 0: |         if len(matching_specs) == 0: | ||||||
|             if args.force: continue |             if args.force: continue | ||||||
| @@ -86,4 +91,13 @@ def num_installed_deps(pkg): | |||||||
|  |  | ||||||
|     # Uninstall packages in order now. |     # Uninstall packages in order now. | ||||||
|     for pkg in pkgs: |     for pkg in pkgs: | ||||||
|  |         try: | ||||||
|             pkg.do_uninstall(force=args.force) |             pkg.do_uninstall(force=args.force) | ||||||
|  |         except PackageStillNeededError, e: | ||||||
|  |             tty.error("Will not uninstall %s" % e.spec.format("$_$@$%@$#", color=True)) | ||||||
|  |             print | ||||||
|  |             print "The following packages depend on it:" | ||||||
|  |             display_specs(e.dependents, long=True) | ||||||
|  |             print | ||||||
|  |             print "You can use spack uninstall -f to force this action." | ||||||
|  |             sys.exit(1) | ||||||
|   | |||||||
| @@ -569,7 +569,7 @@ def installed_dependents(self): | |||||||
|             if self.name == spec.name: |             if self.name == spec.name: | ||||||
|                 continue |                 continue | ||||||
|             for dep in spec.traverse(): |             for dep in spec.traverse(): | ||||||
|                 if spec == dep: |                 if self.spec == dep: | ||||||
|                     dependents.append(spec) |                     dependents.append(spec) | ||||||
|         return dependents |         return dependents | ||||||
|  |  | ||||||
| @@ -897,12 +897,9 @@ def do_uninstall(self, force=False): | |||||||
|             raise InstallError(str(self.spec) + " is not installed.") |             raise InstallError(str(self.spec) + " is not installed.") | ||||||
|  |  | ||||||
|         if not force: |         if not force: | ||||||
|             deps = self.installed_dependents |             dependents = self.installed_dependents | ||||||
|             formatted_deps = [s.format('$_$@$%@$+$=$#') for s in deps] |             if dependents: | ||||||
|             if deps: raise InstallError( |                 raise PackageStillNeededError(self.spec, dependents) | ||||||
|                 "Cannot uninstall %s." % self.spec, |  | ||||||
|                 "The following installed packages depend on it: %s" % |  | ||||||
|                 ' '.join(formatted_deps)) |  | ||||||
|  |  | ||||||
|         # Pre-uninstall hook runs first. |         # Pre-uninstall hook runs first. | ||||||
|         spack.hooks.pre_uninstall(self) |         spack.hooks.pre_uninstall(self) | ||||||
| @@ -1182,6 +1179,15 @@ def __init__(self, message, long_msg=None): | |||||||
|         super(InstallError, self).__init__(message, long_msg) |         super(InstallError, self).__init__(message, long_msg) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PackageStillNeededError(InstallError): | ||||||
|  |     """Raised when package is still needed by another on uninstall.""" | ||||||
|  |     def __init__(self, spec, dependents): | ||||||
|  |         super(PackageStillNeededError, self).__init__( | ||||||
|  |             "Cannot uninstall %s" % spec) | ||||||
|  |         self.spec = spec | ||||||
|  |         self.dependents = dependents | ||||||
|  |  | ||||||
|  |  | ||||||
| class PackageError(spack.error.SpackError): | class PackageError(spack.error.SpackError): | ||||||
|     """Raised when something is wrong with a package definition.""" |     """Raised when something is wrong with a package definition.""" | ||||||
|     def __init__(self, message, long_msg=None): |     def __init__(self, message, long_msg=None): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Todd Gamblin
					Todd Gamblin