forked from spack/spack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
spack deconcretize
command (spack#38803)
We have two ways to concretize now: * `spack concretize` concretizes only the root specs that are not concrete in the environment. * `spack concretize -f` eliminates all cached concretization data and reconcretizes the *entire* environment. This PR adds `spack deconcretize`, which eliminates cached concretization data for a spec. This allows users greater control over what is preserved from their `spack.lock` file and what is reused when not using `spack concretize -f`. If you want to update a spec installed in your environment, you can call `spack deconcretize` on it, and that spec and any relevant dependents will be removed from the lock file. `spack concretize` has two options: * `--root`: limits deconcretized specs to *specific* roots in the environment. You can use this to deconcretize exactly one root in a `unify: false` environment. i.e., if `foo` root is a dependent of `bar`, both roots, `spack deconcretize bar` will *not* deconcretize `foo`. * `--all`: deconcretize *all* specs that match the input spec. By default `spack deconcretize` will complain about multiple matches, like `spack uninstall`.
- Loading branch information
Showing
8 changed files
with
265 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other | ||
# Spack Project Developers. See the top-level COPYRIGHT file for details. | ||
# | ||
# SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
import sys | ||
from typing import List | ||
|
||
import llnl.util.tty as tty | ||
|
||
import spack.cmd | ||
|
||
display_args = {"long": True, "show_flags": False, "variants": False, "indent": 4} | ||
|
||
|
||
def confirm_action(specs: List[spack.spec.Spec], participle: str, noun: str): | ||
"""Display the list of specs to be acted on and ask for confirmation. | ||
Args: | ||
specs: specs to be removed | ||
participle: action expressed as a participle, e.g. "uninstalled" | ||
noun: action expressed as a noun, e.g. "uninstallation" | ||
""" | ||
tty.msg(f"The following {len(specs)} packages will be {participle}:\n") | ||
spack.cmd.display_specs(specs, **display_args) | ||
print("") | ||
answer = tty.get_yes_or_no("Do you want to proceed?", default=False) | ||
if not answer: | ||
tty.msg(f"Aborting {noun}") | ||
sys.exit(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other | ||
# Spack Project Developers. See the top-level COPYRIGHT file for details. | ||
# | ||
# SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
import argparse | ||
import sys | ||
from typing import List | ||
|
||
import llnl.util.tty as tty | ||
|
||
import spack.cmd | ||
import spack.cmd.common.arguments as arguments | ||
import spack.cmd.common.confirmation as confirmation | ||
import spack.environment as ev | ||
import spack.spec | ||
|
||
description = "remove specs from the concretized lockfile of an environment" | ||
section = "environments" | ||
level = "long" | ||
|
||
# Arguments for display_specs when we find ambiguity | ||
display_args = {"long": True, "show_flags": False, "variants": False, "indent": 4} | ||
|
||
|
||
def setup_parser(subparser): | ||
subparser.add_argument( | ||
"--root", action="store_true", help="deconcretize only specific environment roots" | ||
) | ||
arguments.add_common_arguments(subparser, ["yes_to_all", "specs"]) | ||
subparser.add_argument( | ||
"-a", | ||
"--all", | ||
action="store_true", | ||
dest="all", | ||
help="deconcretize ALL specs that match each supplied spec", | ||
) | ||
|
||
|
||
def get_deconcretize_list( | ||
args: argparse.Namespace, specs: List[spack.spec.Spec], env: ev.Environment | ||
) -> List[spack.spec.Spec]: | ||
""" | ||
Get list of environment roots to deconcretize | ||
""" | ||
env_specs = [s for _, s in env.concretized_specs()] | ||
to_deconcretize = [] | ||
errors = [] | ||
|
||
for s in specs: | ||
if args.root: | ||
# find all roots matching given spec | ||
to_deconc = [e for e in env_specs if e.satisfies(s)] | ||
else: | ||
# find all roots matching or depending on a matching spec | ||
to_deconc = [e for e in env_specs if any(d.satisfies(s) for d in e.traverse())] | ||
|
||
if len(to_deconc) < 1: | ||
tty.warn(f"No matching specs to deconcretize for {s}") | ||
|
||
elif len(to_deconc) > 1 and not args.all: | ||
errors.append((s, to_deconc)) | ||
|
||
to_deconcretize.extend(to_deconc) | ||
|
||
if errors: | ||
for spec, matching in errors: | ||
tty.error(f"{spec} matches multiple concrete specs:") | ||
sys.stderr.write("\n") | ||
spack.cmd.display_specs(matching, output=sys.stderr, **display_args) | ||
sys.stderr.write("\n") | ||
sys.stderr.flush() | ||
tty.die("Use '--all' to deconcretize all matching specs, or be more specific") | ||
|
||
return to_deconcretize | ||
|
||
|
||
def deconcretize_specs(args, specs): | ||
env = spack.cmd.require_active_env(cmd_name="deconcretize") | ||
|
||
if args.specs: | ||
deconcretize_list = get_deconcretize_list(args, specs, env) | ||
else: | ||
deconcretize_list = [s for _, s in env.concretized_specs()] | ||
|
||
if not args.yes_to_all: | ||
confirmation.confirm_action(deconcretize_list, "deconcretized", "deconcretization") | ||
|
||
with env.write_transaction(): | ||
for spec in deconcretize_list: | ||
env.deconcretize(spec) | ||
env.write() | ||
|
||
|
||
def deconcretize(parser, args): | ||
if not args.specs and not args.all: | ||
tty.die( | ||
"deconcretize requires at least one spec argument.", | ||
" Use `spack deconcretize --all` to deconcretize ALL specs.", | ||
) | ||
|
||
specs = spack.cmd.parse_specs(args.specs) if args.specs else [any] | ||
deconcretize_specs(args, specs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other | ||
# Spack Project Developers. See the top-level COPYRIGHT file for details. | ||
# | ||
# SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
import pytest | ||
|
||
import spack.environment as ev | ||
from spack.main import SpackCommand, SpackCommandError | ||
|
||
deconcretize = SpackCommand("deconcretize") | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def test_env(mutable_mock_env_path, config, mock_packages): | ||
ev.create("test") | ||
with ev.read("test") as e: | ||
e.add("[email protected] foobar=bar ^[email protected]") | ||
e.add("[email protected] foobar=bar ^[email protected]") | ||
e.concretize() | ||
e.write() | ||
|
||
|
||
def test_deconcretize_dep(test_env): | ||
with ev.read("test") as e: | ||
deconcretize("-y", "[email protected]") | ||
specs = [s for s, _ in e.concretized_specs()] | ||
|
||
assert len(specs) == 1 | ||
assert specs[0].satisfies("[email protected]") | ||
|
||
|
||
def test_deconcretize_all_dep(test_env): | ||
with ev.read("test") as e: | ||
with pytest.raises(SpackCommandError): | ||
deconcretize("-y", "b") | ||
deconcretize("-y", "--all", "b") | ||
specs = [s for s, _ in e.concretized_specs()] | ||
|
||
assert len(specs) == 0 | ||
|
||
|
||
def test_deconcretize_root(test_env): | ||
with ev.read("test") as e: | ||
output = deconcretize("-y", "--root", "[email protected]") | ||
assert "No matching specs to deconcretize" in output | ||
assert len(e.concretized_order) == 2 | ||
|
||
deconcretize("-y", "--root", "[email protected]") | ||
specs = [s for s, _ in e.concretized_specs()] | ||
|
||
assert len(specs) == 1 | ||
assert specs[0].satisfies("[email protected]") | ||
|
||
|
||
def test_deconcretize_all_root(test_env): | ||
with ev.read("test") as e: | ||
with pytest.raises(SpackCommandError): | ||
deconcretize("-y", "--root", "a") | ||
|
||
output = deconcretize("-y", "--root", "--all", "b") | ||
assert "No matching specs to deconcretize" in output | ||
assert len(e.concretized_order) == 2 | ||
|
||
deconcretize("-y", "--root", "--all", "a") | ||
specs = [s for s, _ in e.concretized_specs()] | ||
|
||
assert len(specs) == 0 | ||
|
||
|
||
def test_deconcretize_all(test_env): | ||
with ev.read("test") as e: | ||
with pytest.raises(SpackCommandError): | ||
deconcretize() | ||
deconcretize("-y", "--all") | ||
specs = [s for s, _ in e.concretized_specs()] | ||
|
||
assert len(specs) == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters