Compare commits
1 Commits
develop
...
install-st
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6cbe4e1311 |
@ -115,7 +115,7 @@ def emulate_env_utility(cmd_name, context: Context, args):
|
||||
f"Not all dependencies of {spec.name} are installed. "
|
||||
f"Cannot setup {context} environment:",
|
||||
spec.tree(
|
||||
status_fn=spack.spec.Spec.install_status,
|
||||
install_status=True,
|
||||
hashlen=7,
|
||||
hashes=True,
|
||||
# This shows more than necessary, but we cannot dynamically change deptypes
|
||||
|
@ -135,8 +135,6 @@ def _process_result(result, show, required_format, kwargs):
|
||||
|
||||
def solve(parser, args):
|
||||
# these are the same options as `spack spec`
|
||||
install_status_fn = spack.spec.Spec.install_status
|
||||
|
||||
fmt = spack.spec.DISPLAY_FORMAT
|
||||
if args.namespaces:
|
||||
fmt = "{namespace}." + fmt
|
||||
@ -146,7 +144,7 @@ def solve(parser, args):
|
||||
"format": fmt,
|
||||
"hashlen": None if args.very_long else 7,
|
||||
"show_types": args.types,
|
||||
"status_fn": install_status_fn if args.install_status else None,
|
||||
"install_status": args.install_status,
|
||||
"hashes": args.long or args.very_long,
|
||||
}
|
||||
|
||||
|
@ -75,8 +75,6 @@ def setup_parser(subparser):
|
||||
|
||||
|
||||
def spec(parser, args):
|
||||
install_status_fn = spack.spec.Spec.install_status
|
||||
|
||||
fmt = spack.spec.DISPLAY_FORMAT
|
||||
if args.namespaces:
|
||||
fmt = "{namespace}." + fmt
|
||||
@ -86,7 +84,7 @@ def spec(parser, args):
|
||||
"format": fmt,
|
||||
"hashlen": None if args.very_long else 7,
|
||||
"show_types": args.types,
|
||||
"status_fn": install_status_fn if args.install_status else None,
|
||||
"install_status": args.install_status,
|
||||
}
|
||||
|
||||
# use a read transaction if we are getting install status for every
|
||||
|
@ -2212,7 +2212,7 @@ def _tree_to_display(spec):
|
||||
return spec.tree(
|
||||
recurse_dependencies=True,
|
||||
format=spack.spec.DISPLAY_FORMAT,
|
||||
status_fn=spack.spec.Spec.install_status,
|
||||
install_status=True,
|
||||
hashlen=7,
|
||||
hashes=True,
|
||||
)
|
||||
|
@ -186,11 +186,11 @@ class InstallStatus(enum.Enum):
|
||||
Options are artificially disjoint for display purposes
|
||||
"""
|
||||
|
||||
installed = "@g{[+]} "
|
||||
upstream = "@g{[^]} "
|
||||
external = "@g{[e]} "
|
||||
absent = "@K{ - } "
|
||||
missing = "@r{[-]} "
|
||||
INSTALLED = "@g{[+]}"
|
||||
UPSTREAM = "@g{[^]}"
|
||||
EXTERNAL = "@g{[e]}"
|
||||
ABSENT = "@K{ - }"
|
||||
MISSING = "@r{[-]}"
|
||||
|
||||
|
||||
def colorize_spec(spec):
|
||||
@ -1499,7 +1499,7 @@ def edge_attributes(self) -> str:
|
||||
if not deptypes_str and not virtuals_str:
|
||||
return ""
|
||||
result = f"{deptypes_str} {virtuals_str}".strip()
|
||||
return f"[{result}]"
|
||||
return f"[{result}] "
|
||||
|
||||
def dependencies(
|
||||
self, name=None, deptype: Union[dt.DepTypes, dt.DepFlag] = dt.ALL
|
||||
@ -4319,8 +4319,7 @@ def colorized(self):
|
||||
return colorize_spec(self)
|
||||
|
||||
def format(self, format_string=DEFAULT_FORMAT, **kwargs):
|
||||
r"""Prints out particular pieces of a spec, depending on what is
|
||||
in the format string.
|
||||
r"""Prints out particular pieces of a spec, depending on what is in the format string.
|
||||
|
||||
Using the ``{attribute}`` syntax, any field of the spec can be
|
||||
selected. Those attributes can be recursive. For example,
|
||||
@ -4446,6 +4445,9 @@ def write_attribute(spec, attribute, color):
|
||||
elif attribute == "spack_install":
|
||||
write(morph(spec, spack.store.STORE.layout.root))
|
||||
return
|
||||
elif re.match(r"install_status", attribute):
|
||||
write(self.install_status_symbol())
|
||||
return
|
||||
elif re.match(r"hash(:\d)?", attribute):
|
||||
col = "#"
|
||||
if ":" in attribute:
|
||||
@ -4540,8 +4542,18 @@ def write_attribute(spec, attribute, color):
|
||||
"Format string terminated while reading attribute." "Missing terminating }."
|
||||
)
|
||||
|
||||
# remove leading whitespace from directives that add it for internal formatting.
|
||||
# Arch, compiler flags, and variants add spaces for spec format correctness, but
|
||||
# we don't really want them in formatted string output. We do want to preserve
|
||||
# whitespace from the format string.
|
||||
formatted_spec = out.getvalue()
|
||||
return formatted_spec.strip()
|
||||
whitespace_attrs = [r"{arch=[^}]*}", r"{architecture}", r"{compiler_flags}", r"{variants}"]
|
||||
if any(re.match(rx, format_string) for rx in whitespace_attrs):
|
||||
formatted_spec = formatted_spec.lstrip()
|
||||
if any(re.search(f"{rx}$", format_string) for rx in whitespace_attrs):
|
||||
formatted_spec = formatted_spec.rstrip()
|
||||
|
||||
return formatted_spec
|
||||
|
||||
def cformat(self, *args, **kwargs):
|
||||
"""Same as format, but color defaults to auto instead of False."""
|
||||
@ -4591,7 +4603,7 @@ def __str__(self):
|
||||
self.traverse(root=False), key=lambda x: (x.name, x.abstract_hash)
|
||||
)
|
||||
sorted_dependencies = [
|
||||
d.format("{edge_attributes} " + DEFAULT_FORMAT) for d in sorted_dependencies
|
||||
d.format("{edge_attributes}" + DEFAULT_FORMAT) for d in sorted_dependencies
|
||||
]
|
||||
spec_str = " ^".join(root_str + sorted_dependencies)
|
||||
return spec_str.strip()
|
||||
@ -4611,20 +4623,25 @@ def colored_str(self):
|
||||
def install_status(self):
|
||||
"""Helper for tree to print DB install status."""
|
||||
if not self.concrete:
|
||||
return InstallStatus.absent
|
||||
return InstallStatus.ABSENT
|
||||
|
||||
if self.external:
|
||||
return InstallStatus.external
|
||||
return InstallStatus.EXTERNAL
|
||||
|
||||
upstream, record = spack.store.STORE.db.query_by_spec_hash(self.dag_hash())
|
||||
if not record:
|
||||
return InstallStatus.absent
|
||||
return InstallStatus.ABSENT
|
||||
elif upstream and record.installed:
|
||||
return InstallStatus.upstream
|
||||
return InstallStatus.UPSTREAM
|
||||
elif record.installed:
|
||||
return InstallStatus.installed
|
||||
return InstallStatus.INSTALLED
|
||||
else:
|
||||
return InstallStatus.missing
|
||||
return InstallStatus.MISSING
|
||||
|
||||
def install_status_symbol(self):
|
||||
"""Get an install status symbol."""
|
||||
status = self.install_status()
|
||||
return clr.colorize(status.value)
|
||||
|
||||
def _installed_explicitly(self):
|
||||
"""Helper for tree to print DB install status."""
|
||||
@ -4650,7 +4667,7 @@ def tree(
|
||||
show_types: bool = False,
|
||||
depth_first: bool = False,
|
||||
recurse_dependencies: bool = True,
|
||||
status_fn: Optional[Callable[["Spec"], InstallStatus]] = None,
|
||||
install_status: bool = False,
|
||||
prefix: Optional[Callable[["Spec"], str]] = None,
|
||||
) -> str:
|
||||
"""Prints out this spec and its dependencies, tree-formatted
|
||||
@ -4671,8 +4688,7 @@ def tree(
|
||||
show_types: if True, show the (merged) dependency type of a node
|
||||
depth_first: if True, traverse the DAG depth first when representing it as a tree
|
||||
recurse_dependencies: if True, recurse on dependencies
|
||||
status_fn: optional callable that takes a node as an argument and return its
|
||||
installation status
|
||||
install_status: if True, show installation status next to each spec
|
||||
prefix: optional callable that takes a node as an argument and return its
|
||||
installation prefix
|
||||
"""
|
||||
@ -4686,6 +4702,9 @@ def tree(
|
||||
):
|
||||
node = dep_spec.spec
|
||||
|
||||
if install_status:
|
||||
out += node.format("{install_status} ")
|
||||
|
||||
if prefix is not None:
|
||||
out += prefix(node)
|
||||
out += " " * indent
|
||||
@ -4693,15 +4712,6 @@ def tree(
|
||||
if depth:
|
||||
out += "%-4d" % d
|
||||
|
||||
if status_fn:
|
||||
status = status_fn(node)
|
||||
if status in list(InstallStatus):
|
||||
out += clr.colorize(status.value, color=color)
|
||||
elif status:
|
||||
out += clr.colorize("@g{[+]} ", color=color)
|
||||
else:
|
||||
out += clr.colorize("@r{[-]} ", color=color)
|
||||
|
||||
if hashes:
|
||||
out += clr.colorize("@K{%s} ", color=color) % node.dag_hash(hashlen)
|
||||
|
||||
|
@ -703,6 +703,13 @@ def check_prop(check_spec, fmt_str, prop, getter):
|
||||
actual = spec.format(named_str)
|
||||
assert expected == actual
|
||||
|
||||
def test_spec_format_instalL_status(self, database):
|
||||
installed = database.query_one("mpileaks^zmpi")
|
||||
assert installed.format("{install_status}") == "[+]"
|
||||
|
||||
not_installed = Spec("foo")
|
||||
assert not_installed.format("{install_status}") == " - "
|
||||
|
||||
def test_spec_formatting_escapes(self, default_mock_concretization):
|
||||
spec = default_mock_concretization("multivalue-variant cflags=-O2")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user