summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2022-05-08 01:19:44 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2022-05-13 10:45:12 -0700
commitc93e465134b06b8f18717fc664ac328858bad95c (patch)
tree9c440311a5e5535e30b88e75832192544577006f /lib
parent521c2060304474aa5f7755d8ed07af4b84e30dbf (diff)
downloadspack-c93e465134b06b8f18717fc664ac328858bad95c.tar.gz
spack-c93e465134b06b8f18717fc664ac328858bad95c.tar.bz2
spack-c93e465134b06b8f18717fc664ac328858bad95c.tar.xz
spack-c93e465134b06b8f18717fc664ac328858bad95c.zip
full hash: fix uninstall and gc with full hash DB
The database now stores full hashes, so we need to adjust the criteria we use to determine if something can be uninstalled. Specifically, it's ok to uninstall thing that have remaining build-only dependents.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/cmd/uninstall.py18
-rw-r--r--lib/spack/spack/database.py7
-rw-r--r--lib/spack/spack/package.py6
3 files changed, 26 insertions, 5 deletions
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index ce3d6f7dab..f7fbd67754 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -225,15 +225,25 @@ def do_uninstall(env, specs, force):
# A package is ready to be uninstalled when nothing else references it,
# unless we are requested to force uninstall it.
- is_ready = lambda x: not spack.store.db.query_by_spec_hash(x)[1].ref_count
- if force:
- is_ready = lambda x: True
+ def is_ready(dag_hash):
+ if force:
+ return True
+
+ _, record = spack.store.db.query_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",)
+ 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 dependents {0}]'
+ ' remaining link or run dependents {0}]'
msg = msg.format(', '.join(x.name for x in packages))
raise spack.error.SpackError(msg)
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index 06389cad78..1b10965a42 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -691,6 +691,13 @@ class Database(object):
return db
def query_by_spec_hash(self, hash_key, data=None):
+ """Get a spec for hash, and whether it's installed upstream.
+
+ Return:
+ (tuple): (bool, optional InstallRecord): bool tells us whether
+ the spec is installed upstream. Its InstallRecord is also
+ returned if it's installed at all; otherwise None.
+ """
if data and hash_key in data:
return False, data[hash_key]
if not data:
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 9fc227baec..ce8f2add09 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -2371,7 +2371,11 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
if not force:
dependents = spack.store.db.installed_relatives(
- spec, 'parents', True)
+ spec,
+ direction='parents',
+ transitive=True,
+ deptype=("link", "run"),
+ )
if dependents:
raise PackageStillNeededError(spec, dependents)