spack uninstall: use topo order (#34053)
This commit is contained in:
parent
bcc0fda4e2
commit
4bf964e6b3
@ -43,4 +43,4 @@ def gc(parser, args):
|
||||
if not args.yes_to_all:
|
||||
spack.cmd.uninstall.confirm_removal(specs)
|
||||
|
||||
spack.cmd.uninstall.do_uninstall(None, specs, force=False)
|
||||
spack.cmd.uninstall.do_uninstall(specs, force=False)
|
||||
|
@ -230,54 +230,21 @@ def _remove_from_env(spec, env):
|
||||
pass # ignore non-root specs
|
||||
|
||||
|
||||
def do_uninstall(env, specs, force):
|
||||
"""Uninstalls all the specs in a list.
|
||||
def do_uninstall(specs, force=False):
|
||||
# TODO: get rid of the call-sites that use this function,
|
||||
# so that we don't have to do a dance of list -> set -> list -> set
|
||||
hashes_to_remove = set(s.dag_hash() for s in specs)
|
||||
|
||||
Args:
|
||||
env (spack.environment.Environment or None): active environment, or ``None``
|
||||
if there is not one
|
||||
specs (list): list of specs to be uninstalled
|
||||
force (bool): force uninstallation (boolean)
|
||||
"""
|
||||
packages = []
|
||||
for item in specs:
|
||||
try:
|
||||
# should work if package is known to spack
|
||||
packages.append(item.package)
|
||||
except spack.repo.UnknownEntityError:
|
||||
# The package.py file has gone away -- but still
|
||||
# want to uninstall.
|
||||
spack.package_base.PackageBase.uninstall_by_spec(item, force=True)
|
||||
|
||||
# A package is ready to be uninstalled when nothing else references it,
|
||||
# unless we are requested to force uninstall it.
|
||||
def is_ready(dag_hash):
|
||||
if force:
|
||||
return True
|
||||
|
||||
record = spack.store.db.query_local_by_spec_hash(dag_hash)
|
||||
if not record.ref_count:
|
||||
return True
|
||||
|
||||
# If this spec is only used as a build dependency, we can uninstall
|
||||
return all(
|
||||
dspec.deptypes == ("build",) or not dspec.parent.installed
|
||||
for dspec in record.spec.edges_from_dependents()
|
||||
)
|
||||
|
||||
while packages:
|
||||
ready = [x for x in packages if is_ready(x.spec.dag_hash())]
|
||||
if not ready:
|
||||
msg = (
|
||||
"unexpected error [cannot proceed uninstalling specs with"
|
||||
" remaining link or run dependents {0}]"
|
||||
)
|
||||
msg = msg.format(", ".join(x.name for x in packages))
|
||||
raise spack.error.SpackError(msg)
|
||||
|
||||
packages = [x for x in packages if x not in ready]
|
||||
for item in ready:
|
||||
item.do_uninstall(force=force)
|
||||
for s in traverse.traverse_nodes(
|
||||
specs,
|
||||
order="topo",
|
||||
direction="children",
|
||||
root=True,
|
||||
cover="nodes",
|
||||
deptype="all",
|
||||
):
|
||||
if s.dag_hash() in hashes_to_remove:
|
||||
spack.package_base.PackageBase.uninstall_by_spec(s, force=force)
|
||||
|
||||
|
||||
def get_uninstall_list(args, specs, env):
|
||||
@ -419,7 +386,7 @@ def uninstall_specs(args, specs):
|
||||
confirm_removal(uninstall_list)
|
||||
|
||||
# Uninstall everything on the list
|
||||
do_uninstall(env, uninstall_list, args.force)
|
||||
do_uninstall(uninstall_list, args.force)
|
||||
|
||||
if env:
|
||||
with env.write_transaction():
|
||||
|
Loading…
Reference in New Issue
Block a user