From cebe4fdf1d7cc3a150c5ee5080104e58dc7557c5 Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Tue, 15 Feb 2022 18:42:05 +0100 Subject: Make `spack -e [env] spec` show environment root specs (#25941) --- lib/spack/spack/cmd/spec.py | 47 +++++++++++++++++++++++++--------------- lib/spack/spack/test/cmd/spec.py | 19 ++++++++++++++-- 2 files changed, 47 insertions(+), 19 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py index 74961aafc4..2b1ba62571 100644 --- a/lib/spack/spack/cmd/spec.py +++ b/lib/spack/spack/cmd/spec.py @@ -13,6 +13,7 @@ import llnl.util.tty as tty import spack import spack.cmd import spack.cmd.common.arguments as arguments +import spack.environment as ev import spack.hash_types as ht import spack.spec import spack.store @@ -24,6 +25,9 @@ level = "short" def setup_parser(subparser): subparser.epilog = """\ +when an environment is active and no specs are provided, the environment root \ +specs are used instead + for further documentation regarding the spec syntax, see: spack help --spec """ @@ -79,37 +83,46 @@ def spec(parser, args): if args.install_status: tree_context = spack.store.db.read_transaction - if not args.specs: - tty.die("spack spec requires at least one spec") - concretize_kwargs = { 'reuse': args.reuse } - for spec in spack.cmd.parse_specs(args.specs): + # Use command line specified specs, otherwise try to use environment specs. + if args.specs: + input_specs = spack.cmd.parse_specs(args.specs) + specs = [(s, s.concretized(**concretize_kwargs)) for s in input_specs] + else: + env = ev.active_environment() + if env: + env.concretize(**concretize_kwargs) + specs = env.concretized_specs() + else: + tty.die("spack spec requires at least one spec or an active environmnt") + + for (input, output) in specs: # With -y, just print YAML to output. if args.format: - if spec.name in spack.repo.path or spec.virtual: - spec.concretize(**concretize_kwargs) - # The user can specify the hash type to use hash_type = getattr(ht, args.hash_type) if args.format == 'yaml': # use write because to_yaml already has a newline. - sys.stdout.write(spec.to_yaml(hash=hash_type)) + sys.stdout.write(output.to_yaml(hash=hash_type)) else: - print(spec.to_json(hash=hash_type)) + print(output.to_json(hash=hash_type)) continue with tree_context(): - tree_kwargs['hashes'] = False # Always False for input spec - print("Input spec") - print("--------------------------------") - print(spec.tree(**tree_kwargs)) + # Only show the headers for input specs that are not concrete to avoid + # repeated output. This happens because parse_specs outputs concrete + # specs for `/hash` inputs. + if not input.concrete: + tree_kwargs['hashes'] = False # Always False for input spec + print("Input spec") + print("--------------------------------") + print(input.tree(**tree_kwargs)) + print("Concretized") + print("--------------------------------") tree_kwargs['hashes'] = args.long or args.very_long - print("Concretized") - print("--------------------------------") - spec.concretize(**concretize_kwargs) - print(spec.tree(**tree_kwargs)) + print(output.tree(**tree_kwargs)) diff --git a/lib/spack/spack/test/cmd/spec.py b/lib/spack/spack/test/cmd/spec.py index 12064e3e8e..89e4efae5c 100644 --- a/lib/spack/spack/test/cmd/spec.py +++ b/lib/spack/spack/test/cmd/spec.py @@ -7,8 +7,9 @@ import re import pytest +import spack.environment as ev import spack.spec -from spack.main import SpackCommand +from spack.main import SpackCommand, SpackCommandError pytestmark = pytest.mark.usefixtures('config', 'mutable_mock_repo') @@ -85,6 +86,20 @@ def test_spec_deptypes_edges(): def test_spec_returncode(): - with pytest.raises(spack.main.SpackCommandError): + with pytest.raises(SpackCommandError): spec() assert spec.returncode == 1 + + +def test_env_aware_spec(mutable_mock_env_path): + env = ev.create('test') + env.add('mpileaks') + + with env: + output = spec() + assert 'mpileaks@2.3' in output + assert 'callpath@1.0' in output + assert 'dyninst@8.2' in output + assert 'libdwarf@20130729' in output + assert 'libelf@0.8.1' in output + assert 'mpich@3.0.4' in output -- cgit v1.2.3-60-g2f50