Add --preferred and --latest tospack checksum
(#25830)
This commit is contained in:
parent
f184900b1a
commit
cc8b6ca69f
@ -14,6 +14,7 @@
|
|||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.stage
|
import spack.stage
|
||||||
import spack.util.crypto
|
import spack.util.crypto
|
||||||
|
from spack.package import preferred_version
|
||||||
from spack.util.naming import valid_fully_qualified_module_name
|
from spack.util.naming import valid_fully_qualified_module_name
|
||||||
from spack.version import Version, ver
|
from spack.version import Version, ver
|
||||||
|
|
||||||
@ -26,9 +27,16 @@ def setup_parser(subparser):
|
|||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
'--keep-stage', action='store_true',
|
'--keep-stage', action='store_true',
|
||||||
help="don't clean up staging area when command completes")
|
help="don't clean up staging area when command completes")
|
||||||
subparser.add_argument(
|
sp = subparser.add_mutually_exclusive_group()
|
||||||
|
sp.add_argument(
|
||||||
'-b', '--batch', action='store_true',
|
'-b', '--batch', action='store_true',
|
||||||
help="don't ask which versions to checksum")
|
help="don't ask which versions to checksum")
|
||||||
|
sp.add_argument(
|
||||||
|
'-l', '--latest', action='store_true',
|
||||||
|
help="checksum the latest available version only")
|
||||||
|
sp.add_argument(
|
||||||
|
'-p', '--preferred', action='store_true',
|
||||||
|
help="checksum the preferred version only")
|
||||||
arguments.add_common_arguments(subparser, ['package'])
|
arguments.add_common_arguments(subparser, ['package'])
|
||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
'versions', nargs=argparse.REMAINDER,
|
'versions', nargs=argparse.REMAINDER,
|
||||||
@ -48,15 +56,18 @@ def checksum(parser, args):
|
|||||||
# Get the package we're going to generate checksums for
|
# Get the package we're going to generate checksums for
|
||||||
pkg = spack.repo.get(args.package)
|
pkg = spack.repo.get(args.package)
|
||||||
|
|
||||||
|
url_dict = {}
|
||||||
if args.versions:
|
if args.versions:
|
||||||
# If the user asked for specific versions, use those
|
# If the user asked for specific versions, use those
|
||||||
url_dict = {}
|
|
||||||
for version in args.versions:
|
for version in args.versions:
|
||||||
version = ver(version)
|
version = ver(version)
|
||||||
if not isinstance(version, Version):
|
if not isinstance(version, Version):
|
||||||
tty.die("Cannot generate checksums for version lists or "
|
tty.die("Cannot generate checksums for version lists or "
|
||||||
"version ranges. Use unambiguous versions.")
|
"version ranges. Use unambiguous versions.")
|
||||||
url_dict[version] = pkg.url_for_version(version)
|
url_dict[version] = pkg.url_for_version(version)
|
||||||
|
elif args.preferred:
|
||||||
|
version = preferred_version(pkg)
|
||||||
|
url_dict = dict([(version, pkg.url_for_version(version))])
|
||||||
else:
|
else:
|
||||||
# Otherwise, see what versions we can find online
|
# Otherwise, see what versions we can find online
|
||||||
url_dict = pkg.fetch_remote_versions()
|
url_dict = pkg.fetch_remote_versions()
|
||||||
@ -76,7 +87,7 @@ def checksum(parser, args):
|
|||||||
version_lines = spack.stage.get_checksums_for_versions(
|
version_lines = spack.stage.get_checksums_for_versions(
|
||||||
url_dict, pkg.name, keep_stage=args.keep_stage,
|
url_dict, pkg.name, keep_stage=args.keep_stage,
|
||||||
batch=(args.batch or len(args.versions) > 0 or len(url_dict) == 1),
|
batch=(args.batch or len(args.versions) > 0 or len(url_dict) == 1),
|
||||||
fetch_options=pkg.fetch_options)
|
latest=args.latest, fetch_options=pkg.fetch_options)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print(version_lines)
|
print(version_lines)
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import spack.fetch_strategy as fs
|
import spack.fetch_strategy as fs
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.spec
|
import spack.spec
|
||||||
|
from spack.package import preferred_version
|
||||||
|
|
||||||
description = 'get detailed information on a particular package'
|
description = 'get detailed information on a particular package'
|
||||||
section = 'basic'
|
section = 'basic'
|
||||||
@ -197,13 +198,7 @@ def print_text_info(pkg):
|
|||||||
else:
|
else:
|
||||||
pad = padder(pkg.versions, 4)
|
pad = padder(pkg.versions, 4)
|
||||||
|
|
||||||
# Here we sort first on the fact that a version is marked
|
preferred = preferred_version(pkg)
|
||||||
# as preferred in the package, then on the fact that the
|
|
||||||
# version is not develop, then lexicographically
|
|
||||||
key_fn = lambda v: (pkg.versions[v].get('preferred', False),
|
|
||||||
not v.isdevelop(),
|
|
||||||
v)
|
|
||||||
preferred = sorted(pkg.versions, key=key_fn).pop()
|
|
||||||
url = ''
|
url = ''
|
||||||
if pkg.has_code:
|
if pkg.has_code:
|
||||||
url = fs.for_package_version(pkg, preferred)
|
url = fs.for_package_version(pkg, preferred)
|
||||||
|
@ -83,6 +83,22 @@
|
|||||||
_spack_configure_argsfile = 'spack-configure-args.txt'
|
_spack_configure_argsfile = 'spack-configure-args.txt'
|
||||||
|
|
||||||
|
|
||||||
|
def preferred_version(pkg):
|
||||||
|
"""
|
||||||
|
Returns a sorted list of the preferred versions of the package.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
pkg (Package): The package whose versions are to be assessed.
|
||||||
|
"""
|
||||||
|
# Here we sort first on the fact that a version is marked
|
||||||
|
# as preferred in the package, then on the fact that the
|
||||||
|
# version is not develop, then lexicographically
|
||||||
|
key_fn = lambda v: (pkg.versions[v].get('preferred', False),
|
||||||
|
not v.isdevelop(),
|
||||||
|
v)
|
||||||
|
return sorted(pkg.versions, key=key_fn).pop()
|
||||||
|
|
||||||
|
|
||||||
class InstallPhase(object):
|
class InstallPhase(object):
|
||||||
"""Manages a single phase of the installation.
|
"""Manages a single phase of the installation.
|
||||||
|
|
||||||
|
@ -824,9 +824,7 @@ def purge():
|
|||||||
remove_linked_tree(stage_path)
|
remove_linked_tree(stage_path)
|
||||||
|
|
||||||
|
|
||||||
def get_checksums_for_versions(
|
def get_checksums_for_versions(url_dict, name, **kwargs):
|
||||||
url_dict, name, first_stage_function=None, keep_stage=False,
|
|
||||||
fetch_options=None, batch=False):
|
|
||||||
"""Fetches and checksums archives from URLs.
|
"""Fetches and checksums archives from URLs.
|
||||||
|
|
||||||
This function is called by both ``spack checksum`` and ``spack
|
This function is called by both ``spack checksum`` and ``spack
|
||||||
@ -842,6 +840,7 @@ def get_checksums_for_versions(
|
|||||||
keep_stage (bool): whether to keep staging area when command completes
|
keep_stage (bool): whether to keep staging area when command completes
|
||||||
batch (bool): whether to ask user how many versions to fetch (false)
|
batch (bool): whether to ask user how many versions to fetch (false)
|
||||||
or fetch all versions (true)
|
or fetch all versions (true)
|
||||||
|
latest (bool): whether to take the latest version (true) or all (false)
|
||||||
fetch_options (dict): Options used for the fetcher (such as timeout
|
fetch_options (dict): Options used for the fetcher (such as timeout
|
||||||
or cookies)
|
or cookies)
|
||||||
|
|
||||||
@ -849,7 +848,15 @@ def get_checksums_for_versions(
|
|||||||
(str): A multi-line string containing versions and corresponding hashes
|
(str): A multi-line string containing versions and corresponding hashes
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
batch = kwargs.get('batch', False)
|
||||||
|
fetch_options = kwargs.get('fetch_options', None)
|
||||||
|
first_stage_function = kwargs.get('first_stage_function', None)
|
||||||
|
keep_stage = kwargs.get('keep_stage', False)
|
||||||
|
latest = kwargs.get('latest', False)
|
||||||
|
|
||||||
sorted_versions = sorted(url_dict.keys(), reverse=True)
|
sorted_versions = sorted(url_dict.keys(), reverse=True)
|
||||||
|
if latest:
|
||||||
|
sorted_versions = sorted_versions[:1]
|
||||||
|
|
||||||
# Find length of longest string in the list for padding
|
# Find length of longest string in the list for padding
|
||||||
max_len = max(len(str(v)) for v in sorted_versions)
|
max_len = max(len(str(v)) for v in sorted_versions)
|
||||||
@ -863,7 +870,7 @@ def get_checksums_for_versions(
|
|||||||
for v in sorted_versions]))
|
for v in sorted_versions]))
|
||||||
print()
|
print()
|
||||||
|
|
||||||
if batch:
|
if batch or latest:
|
||||||
archives_to_fetch = len(sorted_versions)
|
archives_to_fetch = len(sorted_versions)
|
||||||
else:
|
else:
|
||||||
archives_to_fetch = tty.get_number(
|
archives_to_fetch = tty.get_number(
|
||||||
|
60
lib/spack/spack/test/cmd/checksum.py
Normal file
60
lib/spack/spack/test/cmd/checksum.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Copyright 2013-2021 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 pytest
|
||||||
|
|
||||||
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
|
import spack.cmd.checksum
|
||||||
|
import spack.repo
|
||||||
|
from spack.main import SpackCommand
|
||||||
|
|
||||||
|
spack_checksum = SpackCommand('checksum')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('arguments,expected', [
|
||||||
|
(['--batch', 'patch'], (True, False, False)),
|
||||||
|
(['--latest', 'patch'], (False, True, False)),
|
||||||
|
(['--preferred', 'patch'], (False, False, True)),
|
||||||
|
])
|
||||||
|
def test_checksum_args(arguments, expected):
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
spack.cmd.checksum.setup_parser(parser)
|
||||||
|
args = parser.parse_args(arguments)
|
||||||
|
check = args.batch, args.latest, args.preferred
|
||||||
|
assert check == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('arguments,expected', [
|
||||||
|
(['--batch', 'preferred-test'], 'versions of preferred-test'),
|
||||||
|
(['--latest', 'preferred-test'], 'Found 1 version'),
|
||||||
|
(['--preferred', 'preferred-test'], 'Found 1 version'),
|
||||||
|
])
|
||||||
|
def test_checksum(arguments, expected, mock_packages, mock_stage):
|
||||||
|
output = spack_checksum(*arguments)
|
||||||
|
assert expected in output
|
||||||
|
assert 'version(' in output
|
||||||
|
|
||||||
|
|
||||||
|
def test_checksum_interactive(
|
||||||
|
mock_packages, mock_fetch, mock_stage, monkeypatch):
|
||||||
|
def _get_number(*args, **kwargs):
|
||||||
|
return 1
|
||||||
|
monkeypatch.setattr(tty, 'get_number', _get_number)
|
||||||
|
|
||||||
|
output = spack_checksum('preferred-test')
|
||||||
|
assert 'versions of preferred-test' in output
|
||||||
|
assert 'version(' in output
|
||||||
|
|
||||||
|
|
||||||
|
def test_checksum_versions(mock_packages, mock_fetch, mock_stage):
|
||||||
|
pkg = spack.repo.get('preferred-test')
|
||||||
|
|
||||||
|
versions = [str(v) for v in pkg.versions if not v.isdevelop()]
|
||||||
|
output = spack_checksum('preferred-test', versions[0])
|
||||||
|
assert 'Found 1 version' in output
|
||||||
|
assert 'version(' in output
|
@ -575,7 +575,7 @@ _spack_cd() {
|
|||||||
_spack_checksum() {
|
_spack_checksum() {
|
||||||
if $list_options
|
if $list_options
|
||||||
then
|
then
|
||||||
SPACK_COMPREPLY="-h --help --keep-stage -b --batch"
|
SPACK_COMPREPLY="-h --help --keep-stage -b --batch -l --latest -p --preferred"
|
||||||
else
|
else
|
||||||
_all_packages
|
_all_packages
|
||||||
fi
|
fi
|
||||||
|
Loading…
Reference in New Issue
Block a user