From e81ce18cade3a9824e5c28cf78c99e3836241b4d Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Mon, 28 Oct 2024 19:28:03 -0700 Subject: cmd/solve: use interface from cmd/spec (#47182) Currently, `spack solve` has different spec selection semantics than `spack spec`. `spack solve` currently does not allow specifying a single spec when an environment is active. This PR modifies `spack solve` to inherit the interface from `spack spec`, and to use the same spec selection logic. This will allow for better use of `spack solve --show opt` for debugging. --------- Co-authored-by: Todd Gamblin --- lib/spack/spack/cmd/solve.py | 54 +++++++------------------------------------- lib/spack/spack/cmd/spec.py | 25 ++++++++++---------- 2 files changed, 20 insertions(+), 59 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/solve.py b/lib/spack/spack/cmd/solve.py index f5a9c09c3d..8adc06fdfb 100644 --- a/lib/spack/spack/cmd/solve.py +++ b/lib/spack/spack/cmd/solve.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -import argparse import re import sys @@ -12,13 +11,12 @@ import llnl.util.tty.color as color import spack import spack.cmd -import spack.cmd.common.arguments +import spack.cmd.spec import spack.config import spack.environment import spack.hash_types as ht import spack.solver.asp as asp import spack.spec -from spack.cmd.common import arguments description = "concretize a specs using an ASP solver" section = "developer" @@ -41,42 +39,6 @@ def setup_parser(subparser): " solutions models found by asp program\n" " all all of the above", ) - - # Below are arguments w.r.t. spec display (like spack spec) - arguments.add_common_arguments(subparser, ["long", "very_long", "namespaces"]) - - install_status_group = subparser.add_mutually_exclusive_group() - arguments.add_common_arguments(install_status_group, ["install_status", "no_install_status"]) - - subparser.add_argument( - "-y", - "--yaml", - action="store_const", - dest="format", - default=None, - const="yaml", - help="print concrete spec as yaml", - ) - subparser.add_argument( - "-j", - "--json", - action="store_const", - dest="format", - default=None, - const="json", - help="print concrete spec as json", - ) - subparser.add_argument( - "-c", - "--cover", - action="store", - default="nodes", - choices=["nodes", "edges", "paths"], - help="how extensively to traverse the DAG (default: nodes)", - ) - subparser.add_argument( - "-t", "--types", action="store_true", default=False, help="show dependency types" - ) subparser.add_argument( "--timers", action="store_true", @@ -86,9 +48,8 @@ def setup_parser(subparser): subparser.add_argument( "--stats", action="store_true", default=False, help="print out statistics from clingo" ) - subparser.add_argument("specs", nargs=argparse.REMAINDER, help="specs of packages") - spack.cmd.common.arguments.add_concretizer_args(subparser) + spack.cmd.spec.setup_parser(subparser) def _process_result(result, show, required_format, kwargs): @@ -164,11 +125,12 @@ def solve(parser, args): # If we have an active environment, pick the specs from there env = spack.environment.active_environment() - if env and args.specs: - msg = "cannot give explicit specs when an environment is active" - raise RuntimeError(msg) - - specs = list(env.user_specs) if env else spack.cmd.parse_specs(args.specs) + if args.specs: + specs = spack.cmd.parse_specs(args.specs) + elif env: + specs = list(env.user_specs) + else: + tty.die("spack solve requires at least one spec or an active environment") solver = asp.Solver() output = sys.stdout if "asp" in show else None diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py index e5cc951d69..188e536088 100644 --- a/lib/spack/spack/cmd/spec.py +++ b/lib/spack/spack/cmd/spec.py @@ -96,26 +96,25 @@ def spec(parser, args): if args.install_status: tree_context = spack.store.STORE.db.read_transaction - # Use command line specified specs, otherwise try to use environment specs. + env = ev.active_environment() + if args.specs: input_specs = spack.cmd.parse_specs(args.specs) concretized_specs = spack.cmd.parse_specs(args.specs, concretize=True) specs = list(zip(input_specs, concretized_specs)) - else: - env = ev.active_environment() - if env: - env.concretize() - specs = env.concretized_specs() + elif env: + env.concretize() + specs = env.concretized_specs() + if not args.format: # environments are printed together in a combined tree() invocation, # except when using --yaml or --json, which we print spec by spec below. - if not args.format: - tree_kwargs["key"] = spack.traverse.by_dag_hash - tree_kwargs["hashes"] = args.long or args.very_long - print(spack.spec.tree([concrete for _, concrete in specs], **tree_kwargs)) - return - else: - tty.die("spack spec requires at least one spec or an active environment") + tree_kwargs["key"] = spack.traverse.by_dag_hash + tree_kwargs["hashes"] = args.long or args.very_long + print(spack.spec.tree([concrete for _, concrete in specs], **tree_kwargs)) + return + else: + tty.die("spack spec requires at least one spec or an active environment") for input, output in specs: # With --yaml or --json, just print the raw specs to output -- cgit v1.2.3-70-g09d2