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.
Allow spec queries by
namespace
(spack#45416)
* Allow spec queries by `namespace` Spack specs have "namespaces" that indicate what package repository they come from, but there has not been a way to use the spec syntax to match one. You can say things like this: ```console spack find builtin.zlib spack find myrepo.zlib ``` But, because namespaces are written as a dot-separated prefix on the name, you can't say "find me all specs in namespace myrepo". The syntax doesn't allow it. This PR allows you to specify anonymous specs with namespaces on the CLI. Specifically you can do queries like this: ```console spack find namespace=builtin spack find namespace=myrepo ``` You can use this anywhere else you use spec syntax, e.g. in a config file to separate installations based on what repo they came from: ```yaml spack: config: install_tree: root: $spack/opt/spack projections: namespace=myrepo: "myrepo_special_path/{name}-{hash}" namespace=builtin: "builtin/{name}-{hash}" ``` This PR adds a special `namespace_if_anonymous` attribute to specs, which returns the `namespace` if the spec has no name, otherwise it returns `None`. This allows us to print the namespace for anonymous specs but to continue hiding it for most views, as we've done so far. This is implemented as a special case, but it's one that already exists, along with `platform`, `os`, `target`, etc. This also reserves existing special case names for variants so that users cannot define them in their package files. This change is potentially breaking, but I do not think it will be common. There are no builtin packages with a variant called `namespace`, and defining `os`, `target`, or `platform` as a variant would've likely caused other problems if they were already being used. Signed-off-by: Todd Gamblin <[email protected]>
- Loading branch information
Showing
6 changed files
with
136 additions
and
107 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
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 |
---|---|---|
|
@@ -197,6 +197,9 @@ class TestSpecSemantics: | |
'multivalue-variant foo="baz"', | ||
'multivalue-variant foo="bar,baz,barbaz"', | ||
), | ||
# Namespace (special case, but like variants | ||
("builtin.libelf", "namespace=builtin", "builtin.libelf"), | ||
("libelf", "namespace=builtin", "builtin.libelf"), | ||
# Flags | ||
("mpich ", 'mpich cppflags="-O3"', 'mpich cppflags="-O3"'), | ||
( | ||
|
@@ -317,6 +320,7 @@ def test_concrete_specs_which_satisfies_abstract(self, lhs, rhs, default_mock_co | |
("libelf debug=True", "libelf debug=False"), | ||
('libelf cppflags="-O3"', 'libelf cppflags="-O2"'), | ||
("libelf platform=test target=be os=be", "libelf target=fe os=fe"), | ||
("namespace=builtin.mock", "namespace=builtin"), | ||
], | ||
) | ||
def test_constraining_abstract_specs_with_empty_intersection(self, lhs, rhs): | ||
|
@@ -406,6 +410,25 @@ def test_indirect_unsatisfied_single_valued_variant(self): | |
spec.concretize() | ||
assert "[email protected]" not in spec | ||
|
||
def test_satisfied_namespace(self): | ||
spec = Spec("zlib").concretized() | ||
assert spec.satisfies("namespace=builtin.mock") | ||
assert not spec.satisfies("namespace=builtin") | ||
|
||
@pytest.mark.parametrize( | ||
"spec_string", | ||
[ | ||
"tcl namespace==foobar", | ||
"tcl arch==foobar", | ||
"tcl os==foobar", | ||
"tcl patches==foobar", | ||
"tcl dev_path==foobar", | ||
], | ||
) | ||
def test_propagate_reserved_variant_names(self, spec_string): | ||
with pytest.raises(spack.parser.SpecParsingError, match="Propagation"): | ||
Spec(spec_string) | ||
|
||
def test_unsatisfiable_multi_value_variant(self, default_mock_concretization): | ||
# Semantics for a multi-valued variant is different | ||
# Depending on whether the spec is concrete or not | ||
|
@@ -768,11 +791,11 @@ def test_spec_formatting_bad_formats(self, default_mock_concretization, fmt_str) | |
|
||
def test_combination_of_wildcard_or_none(self): | ||
# Test that using 'none' and another value raises | ||
with pytest.raises(spack.variant.InvalidVariantValueCombinationError): | ||
with pytest.raises(spack.parser.SpecParsingError, match="cannot be combined"): | ||
Spec("multivalue-variant foo=none,bar") | ||
|
||
# Test that using wildcard and another value raises | ||
with pytest.raises(spack.variant.InvalidVariantValueCombinationError): | ||
with pytest.raises(spack.parser.SpecParsingError, match="cannot be combined"): | ||
Spec("multivalue-variant foo=*,bar") | ||
|
||
def test_errors_in_variant_directive(self): | ||
|
Oops, something went wrong.