From e96f31c29d3408e6421d277728272c7c037c199b Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Thu, 26 Oct 2023 18:57:55 +0200 Subject: [PATCH] spack checksum pkg@1.2, use as version filter (#39694) * spack checksum pkg@1.2, use as version filter Currently pkg@1.2 splits on @ and looks for 1.2 specifically, with this PR pkg@1.2 is a filter so any matching 1.2, 1.2.1, ..., 1.2.10 version is displayed. * fix tests * fix style --- lib/spack/spack/cmd/checksum.py | 22 ++++++++-------------- lib/spack/spack/stage.py | 6 ++++-- lib/spack/spack/test/cmd/checksum.py | 12 +++--------- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/lib/spack/spack/cmd/checksum.py b/lib/spack/spack/cmd/checksum.py index 91a04ca1c9..9e5e32b3b7 100644 --- a/lib/spack/spack/cmd/checksum.py +++ b/lib/spack/spack/cmd/checksum.py @@ -21,7 +21,6 @@ from spack.package_base import PackageBase, deprecated_version, preferred_version from spack.util.editor import editor from spack.util.format import get_version_lines -from spack.util.naming import valid_fully_qualified_module_name from spack.version import Version description = "checksum available versions of a package" @@ -68,27 +67,19 @@ def setup_parser(subparser): modes_parser.add_argument( "--verify", action="store_true", default=False, help="verify known package checksums" ) - arguments.add_common_arguments(subparser, ["package", "jobs"]) + subparser.add_argument("package", help="package or spec. for example cmake or cmake@3.18") subparser.add_argument( "versions", nargs=argparse.REMAINDER, help="versions to generate checksums for" ) + arguments.add_common_arguments(subparser, ["jobs"]) def checksum(parser, args): - # Did the user pass 'package@version' string? - if len(args.versions) == 0 and "@" in args.package: - args.versions = [args.package.split("@")[1]] - args.package = args.package.split("@")[0] - - # Make sure the user provided a package and not a URL - if not valid_fully_qualified_module_name(args.package): - tty.die("`spack checksum` accepts package names, not URLs.") + spec = spack.spec.Spec(args.package) # Get the package we're going to generate checksums for - pkg_cls = spack.repo.PATH.get_pkg_class(args.package) - pkg = pkg_cls(spack.spec.Spec(args.package)) + pkg = spack.repo.PATH.get_pkg_class(spec.name)(spec) - # Build a list of versions to checksum versions = [Version(v) for v in args.versions] # Define placeholder for remote versions. @@ -152,7 +143,10 @@ def checksum(parser, args): tty.die(f"Could not find any remote versions for {pkg.name}") elif len(url_dict) > 1 and not args.batch and sys.stdin.isatty(): filtered_url_dict = spack.stage.interactive_version_filter( - url_dict, pkg.versions, url_changes=url_changed_for_version + url_dict, + pkg.versions, + url_changes=url_changed_for_version, + initial_verion_filter=spec.versions, ) if not filtered_url_dict: exit(0) diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py index 1c7ebdec5c..690a45e7c5 100644 --- a/lib/spack/spack/stage.py +++ b/lib/spack/spack/stage.py @@ -870,6 +870,7 @@ def interactive_version_filter( url_dict: Dict[StandardVersion, str], known_versions: Iterable[StandardVersion] = (), *, + initial_verion_filter: Optional[VersionList] = None, url_changes: Set[StandardVersion] = set(), input: Callable[..., str] = input, ) -> Optional[Dict[StandardVersion, str]]: @@ -883,8 +884,9 @@ def interactive_version_filter( Filtered dictionary of versions to URLs or None if the user wants to quit """ # Find length of longest string in the list for padding - sorted_and_filtered = sorted(url_dict.keys(), reverse=True) - version_filter = VersionList([":"]) + version_filter = initial_verion_filter or VersionList([":"]) + sorted_and_filtered = [v for v in url_dict if v.satisfies(version_filter)] + sorted_and_filtered.sort(reverse=True) max_len = max(len(str(v)) for v in sorted_and_filtered) orig_url_dict = url_dict # only copy when using editor to modify print_header = True diff --git a/lib/spack/spack/test/cmd/checksum.py b/lib/spack/spack/test/cmd/checksum.py index b2fc9d5f6c..0dbaa88053 100644 --- a/lib/spack/spack/test/cmd/checksum.py +++ b/lib/spack/spack/test/cmd/checksum.py @@ -8,6 +8,7 @@ import pytest import spack.cmd.checksum +import spack.parser import spack.repo import spack.spec from spack.main import SpackCommand @@ -254,17 +255,10 @@ def test_checksum_deprecated_version(mock_packages, mock_clone_repo, mock_fetch, assert "Added 0 new versions to" not in output -def test_checksum_at(mock_packages): - pkg_cls = spack.repo.PATH.get_pkg_class("zlib") - versions = [str(v) for v in pkg_cls.versions] - output = spack_checksum(f"zlib@{versions[0]}") - assert "Found 1 version" in output - - def test_checksum_url(mock_packages): pkg_cls = spack.repo.PATH.get_pkg_class("zlib") - output = spack_checksum(f"{pkg_cls.url}", fail_on_error=False) - assert "accepts package names" in output + with pytest.raises(spack.parser.SpecSyntaxError): + spack_checksum(f"{pkg_cls.url}") def test_checksum_verification_fails(install_mockery, capsys):