From 99f3b9f06495b3610889d598b1c8d96f86bfe58f Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Fri, 16 Jun 2023 09:22:28 -0700 Subject: [PATCH] show external status as [e] (#33792) --- lib/spack/spack/relocate.py | 2 +- lib/spack/spack/spec.py | 46 ++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py index eaab4b7b03..883b1e5927 100644 --- a/lib/spack/spack/relocate.py +++ b/lib/spack/spack/relocate.py @@ -676,7 +676,7 @@ def is_relocatable(spec): Raises: ValueError: if the spec is not installed """ - if not spec.install_status(): + if not spec.installed: raise ValueError("spec is not installed [{0}]".format(str(spec))) if spec.external or spec.virtual: diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 3e52af1bcc..fdf9becb53 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -50,6 +50,7 @@ """ import collections import collections.abc +import enum import io import itertools import os @@ -173,6 +174,16 @@ SPECFILE_FORMAT_VERSION = 4 +# InstallStatus is used to map install statuses to symbols for display +# Options are artificially disjoint for dispay purposes +class InstallStatus(enum.Enum): + installed = "@g{[+]} " + upstream = "@g{[^]} " + external = "@g{[e]} " + absent = "@K{ - } " + missing = "@r{[-]} " + + def colorize_spec(spec): """Returns a spec colorized according to the colors specified in color_formats.""" @@ -4481,12 +4492,20 @@ def __str__(self): def install_status(self): """Helper for tree to print DB install status.""" if not self.concrete: - return None - try: - record = spack.store.db.get_record(self) - return record.installed - except KeyError: - return None + return InstallStatus.absent + + if self.external: + return InstallStatus.external + + upstream, record = spack.store.db.query_by_spec_hash(self.dag_hash()) + if not record: + return InstallStatus.absent + elif upstream and record.installed: + return InstallStatus.upstream + elif record.installed: + return InstallStatus.installed + else: + return InstallStatus.missing def _installed_explicitly(self): """Helper for tree to print DB install status.""" @@ -4500,7 +4519,10 @@ def _installed_explicitly(self): def tree(self, **kwargs): """Prints out this spec and its dependencies, tree-formatted - with indentation.""" + with indentation. + + Status function may either output a boolean or an InstallStatus + """ color = kwargs.pop("color", clr.get_color_when()) depth = kwargs.pop("depth", False) hashes = kwargs.pop("hashes", False) @@ -4532,14 +4554,12 @@ def tree(self, **kwargs): if status_fn: status = status_fn(node) - if node.installed_upstream: - out += clr.colorize("@g{[^]} ", color=color) - elif status is None: - out += clr.colorize("@K{ - } ", color=color) # !installed + if status in list(InstallStatus): + out += clr.colorize(status.value, color=color) elif status: - out += clr.colorize("@g{[+]} ", color=color) # installed + out += clr.colorize("@g{[+]} ", color=color) else: - out += clr.colorize("@r{[-]} ", color=color) # missing + out += clr.colorize("@r{[-]} ", color=color) if hashes: out += clr.colorize("@K{%s} ", color=color) % node.dag_hash(hlen)