command: add spack find --format

- spack find --format allows you to supply a format string and have specs
  output in a more machine-readable way, without dedcoration

e.g.:

    spack find --format "{name}-{version}-{hash}"
    autoconf-2.69-icynozk7ti6h4ezzgonqe6jgw5f3ulx4
    automake-1.16.1-o5v3tc77kesgonxjbmeqlwfmb5qzj7zy
    bzip2-1.0.6-syohzw57v2jfag5du2x4bowziw3m5p67
    ...

or:

    spack find --format "{hash}"
    icynozk7ti6h4ezzgonqe6jgw5f3ulx4
    o5v3tc77kesgonxjbmeqlwfmb5qzj7zy
    syohzw57v2jfag5du2x4bowziw3m5p67
    ...

This is intended to make it much easier to script with `spack find`
This commit is contained in:
Todd Gamblin 2019-09-01 16:40:07 -07:00
parent 9b8f1fdc40
commit 64af0a9874
2 changed files with 53 additions and 23 deletions

View File

@ -200,6 +200,20 @@ def gray_hash(spec, length):
return colorize('@K{%s}' % h)
def display_formatted_specs(specs, format_string, deps=False):
"""Print a list of specs formatted with the provided string.
Arguments:
specs (list): list of specs to display.
deps (bool): whether to also print dependencies of specs.
"""
for spec in specs:
print(spec.format(format_string))
if deps:
for depth, dep in spec.traverse(depth=True, root=False):
print(" " * depth, dep.format(format_string))
def display_specs(specs, args=None, **kwargs):
"""Display human readable specs with customizable formatting.

View File

@ -10,6 +10,7 @@
import spack.environment as ev
import spack.repo
import spack.cmd as cmd
import spack.cmd.common.arguments as arguments
from spack.cmd import display_specs
from spack.util.string import plural
@ -33,11 +34,18 @@ def setup_parser(subparser):
const='paths',
help='show paths to package install directories')
format_group.add_argument(
"--format", action="store", default=None,
help="output specs with the specified format string")
# TODO: separate this entirely from the "mode" option -- it's
# TODO: orthogonal, but changing it for all commands that use it with
# TODO: display_spec is tricky. Also make -pd work together properly.
subparser.add_argument(
'-d', '--deps',
action='store_const',
dest='mode',
const='deps',
help='show full dependency DAG of installed packages')
help='output dependencies along with found specs')
arguments.add_common_arguments(
subparser, ['long', 'very_long', 'tags'])
@ -143,6 +151,26 @@ def decorator(spec, fmt):
return decorator, added, roots, removed
def display_env(env, args, decorator):
tty.msg('In environment %s' % env.name)
if not env.user_specs:
tty.msg('No root specs')
else:
tty.msg('Root specs')
# TODO: Change this to not print extraneous deps and variants
display_specs(
env.user_specs, args,
decorator=lambda s, f: color.colorize('@*{%s}' % f))
print()
if args.show_concretized:
tty.msg('Concretized roots')
display_specs(
env.specs_by_hash.values(), args, decorator=decorator)
print()
def find(parser, args):
q_args = query_arguments(args)
results = args.specs(**q_args)
@ -168,25 +196,13 @@ def find(parser, args):
results = [x for x in results if x.name in packages_with_tags]
# Display the result
if env:
tty.msg('In environment %s' % env.name)
if not env.user_specs:
tty.msg('No root specs')
else:
tty.msg('Root specs')
# TODO: Change this to not print extraneous deps and variants
display_specs(
env.user_specs, args,
decorator=lambda s, f: color.colorize('@*{%s}' % f))
print()
if args.show_concretized:
tty.msg('Concretized roots')
display_specs(
env.specs_by_hash.values(), args, decorator=decorator)
print()
tty.msg("%s" % plural(len(results), 'installed package'))
display_specs(results, args, decorator=decorator, all_headers=True)
if args.format:
cmd.display_formatted_specs(
results, args.format, deps=(args.mode == "deps"))
elif args.json:
cmd.display_specs_as_json(results, deps=(args.mode == "deps"))
else:
if env:
display_env(env, args, decorator)
tty.msg("%s" % plural(len(results), 'installed package'))
display_specs(results, args, decorator=decorator, all_headers=True)