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:
|
if not args.yes_to_all:
|
||||||
spack.cmd.uninstall.confirm_removal(specs)
|
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
|
pass # ignore non-root specs
|
||||||
|
|
||||||
|
|
||||||
def do_uninstall(env, specs, force):
|
def do_uninstall(specs, force=False):
|
||||||
"""Uninstalls all the specs in a list.
|
# 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:
|
for s in traverse.traverse_nodes(
|
||||||
env (spack.environment.Environment or None): active environment, or ``None``
|
specs,
|
||||||
if there is not one
|
order="topo",
|
||||||
specs (list): list of specs to be uninstalled
|
direction="children",
|
||||||
force (bool): force uninstallation (boolean)
|
root=True,
|
||||||
"""
|
cover="nodes",
|
||||||
packages = []
|
deptype="all",
|
||||||
for item in specs:
|
):
|
||||||
try:
|
if s.dag_hash() in hashes_to_remove:
|
||||||
# should work if package is known to spack
|
spack.package_base.PackageBase.uninstall_by_spec(s, force=force)
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
def get_uninstall_list(args, specs, env):
|
def get_uninstall_list(args, specs, env):
|
||||||
@ -419,7 +386,7 @@ def uninstall_specs(args, specs):
|
|||||||
confirm_removal(uninstall_list)
|
confirm_removal(uninstall_list)
|
||||||
|
|
||||||
# Uninstall everything on the list
|
# Uninstall everything on the list
|
||||||
do_uninstall(env, uninstall_list, args.force)
|
do_uninstall(uninstall_list, args.force)
|
||||||
|
|
||||||
if env:
|
if env:
|
||||||
with env.write_transaction():
|
with env.write_transaction():
|
||||||
|
Loading…
Reference in New Issue
Block a user