diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2021-02-04 13:17:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-04 13:17:32 +0100 |
commit | 694d633a2c46505b5bcb2e57a52966e37c36477e (patch) | |
tree | cbd505dfdf0d8d706cf68a53297550b40f03b3e4 /lib/spack | |
parent | e9ae44fd8c0c00d75e7b324b241ad9d54c73e0ff (diff) | |
download | spack-694d633a2c46505b5bcb2e57a52966e37c36477e.tar.gz spack-694d633a2c46505b5bcb2e57a52966e37c36477e.tar.bz2 spack-694d633a2c46505b5bcb2e57a52966e37c36477e.tar.xz spack-694d633a2c46505b5bcb2e57a52966e37c36477e.zip |
spack external find: allow to search by tags (#21407)
This commit adds an option to the `external find`
command that allows it to search by tags. In this
way group of executables with common purposes can
be grouped under a single name and a simple command
can be used to detect all of them.
As an example introduce the 'build-tools' tag to
search for common development tools on a system
Diffstat (limited to 'lib/spack')
-rw-r--r-- | lib/spack/spack/cmd/common/arguments.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/cmd/external.py | 23 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/external.py | 25 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/find.py | 6 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/list.py | 6 |
5 files changed, 55 insertions, 9 deletions
diff --git a/lib/spack/spack/cmd/common/arguments.py b/lib/spack/spack/cmd/common/arguments.py index c09f890114..f83708a7dd 100644 --- a/lib/spack/spack/cmd/common/arguments.py +++ b/lib/spack/spack/cmd/common/arguments.py @@ -250,8 +250,8 @@ def very_long(): @arg def tags(): return Args( - '-t', '--tags', action='append', - help='filter a package query by tags') + '-t', '--tag', action='append', dest='tags', metavar='TAG', + help='filter a package query by tag (multiple use allowed)') @arg diff --git a/lib/spack/spack/cmd/external.py b/lib/spack/spack/cmd/external.py index c4f3c0e854..c7d045e66d 100644 --- a/lib/spack/spack/cmd/external.py +++ b/lib/spack/spack/cmd/external.py @@ -16,6 +16,7 @@ import llnl.util.tty.colify as colify import six import spack import spack.cmd +import spack.cmd.common.arguments import spack.error import spack.util.environment import spack.util.spack_yaml as syaml @@ -42,6 +43,7 @@ def setup_parser(subparser): '--scope', choices=scopes, metavar=scopes_metavar, default=spack.config.default_modify_scope('packages'), help="configuration scope to modify") + spack.cmd.common.arguments.add_common_arguments(find_parser, ['tags']) find_parser.add_argument('packages', nargs=argparse.REMAINDER) sp.add_parser( @@ -148,9 +150,28 @@ def _spec_is_valid(spec): def external_find(args): + # Construct the list of possible packages to be detected + packages_to_check = [] + + # Add the packages that have been required explicitly if args.packages: packages_to_check = list(spack.repo.get(pkg) for pkg in args.packages) - else: + if args.tags: + allowed = set(spack.repo.path.packages_with_tags(*args.tags)) + packages_to_check = [x for x in packages_to_check if x in allowed] + + if args.tags and not packages_to_check: + # If we arrived here we didn't have any explicit package passed + # as argument, which means to search all packages. + # Since tags are cached it's much faster to construct what we need + # to search directly, rather than filtering after the fact + packages_to_check = [ + spack.repo.get(pkg) for pkg in + spack.repo.path.packages_with_tags(*args.tags) + ] + + # If the list of packages is empty, search for every possible package + if not args.tags and not packages_to_check: packages_to_check = spack.repo.path.all_packages() pkg_to_entries = _get_external_packages(packages_to_check) diff --git a/lib/spack/spack/test/cmd/external.py b/lib/spack/spack/test/cmd/external.py index 5a94164e61..3249a92894 100644 --- a/lib/spack/spack/test/cmd/external.py +++ b/lib/spack/spack/test/cmd/external.py @@ -2,6 +2,8 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import pytest + import os import os.path @@ -242,3 +244,26 @@ def test_new_entries_are_reported_correctly( # has been found output = external('find', 'gcc') assert 'No new external packages detected' in output + + +@pytest.mark.parametrize('command_args', [ + ('-t', 'build-tools'), + ('-t', 'build-tools', 'cmake'), +]) +def test_use_tags_for_detection( + command_args, mock_executable, mutable_config, monkeypatch +): + # Prepare an environment to detect a fake cmake + cmake_exe = mock_executable('cmake', output="echo cmake version 3.19.1") + prefix = os.path.dirname(cmake_exe) + monkeypatch.setenv('PATH', prefix) + + openssl_exe = mock_executable('openssl', output="OpenSSL 2.8.3") + prefix = os.path.dirname(openssl_exe) + monkeypatch.setenv('PATH', prefix) + + # Test that we detect specs + output = external('find', *command_args) + assert 'The following specs have been' in output + assert 'cmake' in output + assert 'openssl' not in output diff --git a/lib/spack/spack/test/cmd/find.py b/lib/spack/spack/test/cmd/find.py index ef73b629e0..762578a028 100644 --- a/lib/spack/spack/test/cmd/find.py +++ b/lib/spack/spack/test/cmd/find.py @@ -89,7 +89,7 @@ def test_query_arguments(): @pytest.mark.usefixtures('database', 'mock_display') def test_tag1(parser, specs): - args = parser.parse_args(['--tags', 'tag1']) + args = parser.parse_args(['--tag', 'tag1']) spack.cmd.find.find(parser, args) assert len(specs) == 2 @@ -100,7 +100,7 @@ def test_tag1(parser, specs): @pytest.mark.db @pytest.mark.usefixtures('database', 'mock_display') def test_tag2(parser, specs): - args = parser.parse_args(['--tags', 'tag2']) + args = parser.parse_args(['--tag', 'tag2']) spack.cmd.find.find(parser, args) assert len(specs) == 1 @@ -110,7 +110,7 @@ def test_tag2(parser, specs): @pytest.mark.db @pytest.mark.usefixtures('database', 'mock_display') def test_tag2_tag3(parser, specs): - args = parser.parse_args(['--tags', 'tag2', '--tags', 'tag3']) + args = parser.parse_args(['--tag', 'tag2', '--tag', 'tag3']) spack.cmd.find.find(parser, args) assert len(specs) == 0 diff --git a/lib/spack/spack/test/cmd/list.py b/lib/spack/spack/test/cmd/list.py index afa71de90e..f99b7420a4 100644 --- a/lib/spack/spack/test/cmd/list.py +++ b/lib/spack/spack/test/cmd/list.py @@ -33,15 +33,15 @@ def test_list_search_description(): def test_list_tags(): - output = list('--tags', 'proxy-app') + output = list('--tag', 'proxy-app') assert 'cloverleaf3d' in output assert 'hdf5' not in output - output = list('--tags', 'hpc') + output = list('--tag', 'hpc') assert 'nek5000' in output assert 'mfem' in output - output = list('--tags', 'HPC') + output = list('--tag', 'HPC') assert 'nek5000' in output assert 'mfem' in output |