Fix bug in uninstall (regression in 0fc3b58)

This commit is contained in:
Todd Gamblin 2015-06-20 21:46:52 -07:00
parent afe86e0d68
commit edfcac32c3
2 changed files with 35 additions and 15 deletions

View File

@ -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)

View File

@ -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):