summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2021-02-04 13:17:32 +0100
committerGitHub <noreply@github.com>2021-02-04 13:17:32 +0100
commit694d633a2c46505b5bcb2e57a52966e37c36477e (patch)
treecbd505dfdf0d8d706cf68a53297550b40f03b3e4 /lib
parente9ae44fd8c0c00d75e7b324b241ad9d54c73e0ff (diff)
downloadspack-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')
-rw-r--r--lib/spack/spack/cmd/common/arguments.py4
-rw-r--r--lib/spack/spack/cmd/external.py23
-rw-r--r--lib/spack/spack/test/cmd/external.py25
-rw-r--r--lib/spack/spack/test/cmd/find.py6
-rw-r--r--lib/spack/spack/test/cmd/list.py6
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