summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPeter Scheibel <scheibel1@llnl.gov>2023-08-09 00:07:04 -0700
committerGitHub <noreply@github.com>2023-08-09 09:07:04 +0200
commit3453259c98c7d39655b8495ca2e3677c51284b43 (patch)
tree839f8c4d399554b3c006730f154d279df24d2890 /lib
parentee243b84eb5ff183a0d8ed47c513527d20e46b51 (diff)
downloadspack-3453259c98c7d39655b8495ca2e3677c51284b43.tar.gz
spack-3453259c98c7d39655b8495ca2e3677c51284b43.tar.bz2
spack-3453259c98c7d39655b8495ca2e3677c51284b43.tar.xz
spack-3453259c98c7d39655b8495ca2e3677c51284b43.zip
Spec versions: allow `git.` references for branches with `/` (#38239)
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/parser.py11
-rw-r--r--lib/spack/spack/test/spec_syntax.py8
-rw-r--r--lib/spack/spack/test/versions.py20
3 files changed, 36 insertions, 3 deletions
diff --git a/lib/spack/spack/parser.py b/lib/spack/spack/parser.py
index 3416f2540b..29d10a6672 100644
--- a/lib/spack/spack/parser.py
+++ b/lib/spack/spack/parser.py
@@ -76,7 +76,9 @@ IS_WINDOWS = sys.platform == "win32"
IDENTIFIER = r"([a-zA-Z_0-9][a-zA-Z_0-9\-]*)"
DOTTED_IDENTIFIER = rf"({IDENTIFIER}(\.{IDENTIFIER})+)"
GIT_HASH = r"([A-Fa-f0-9]{40})"
-GIT_VERSION = rf"((git\.({DOTTED_IDENTIFIER}|{IDENTIFIER}))|({GIT_HASH}))"
+#: Git refs include branch names, and can contain "." and "/"
+GIT_REF = r"([a-zA-Z_0-9][a-zA-Z_0-9./\-]*)"
+GIT_VERSION = rf"((git\.({GIT_REF}))|({GIT_HASH}))"
NAME = r"[a-zA-Z_0-9][a-zA-Z_0-9\-.]*"
@@ -128,6 +130,7 @@ class TokenType(TokenBase):
DEPENDENCY = r"(\^)"
# Version
VERSION_HASH_PAIR = rf"(@({GIT_VERSION})=({VERSION}))"
+ GIT_VERSION = rf"@({GIT_VERSION})"
VERSION = rf"(@\s*({VERSION_LIST}))"
# Variants
PROPAGATED_BOOL_VARIANT = rf"((\+\+|~~|--)\s*{NAME})"
@@ -364,8 +367,10 @@ class SpecNodeParser:
compiler_name.strip(), compiler_version
)
self.has_compiler = True
- elif self.ctx.accept(TokenType.VERSION) or self.ctx.accept(
- TokenType.VERSION_HASH_PAIR
+ elif (
+ self.ctx.accept(TokenType.VERSION_HASH_PAIR)
+ or self.ctx.accept(TokenType.GIT_VERSION)
+ or self.ctx.accept(TokenType.VERSION)
):
self.hash_not_parsed_or_raise(initial_spec, self.ctx.current_token.value)
if self.has_version:
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index 4a55752fdd..773acd7ce7 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -517,6 +517,14 @@ def specfile_for(default_mock_concretization):
[Token(TokenType.VERSION, value="@:0.4"), Token(TokenType.COMPILER, value="% nvhpc")],
"@:0.4%nvhpc",
),
+ (
+ "zlib@git.foo/bar",
+ [
+ Token(TokenType.UNQUALIFIED_PACKAGE_NAME, "zlib"),
+ Token(TokenType.GIT_VERSION, "@git.foo/bar"),
+ ],
+ "zlib@git.foo/bar",
+ ),
],
)
def test_parse_single_spec(spec_str, tokens, expected_roundtrip):
diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py
index 7d329336ae..e2c5a91097 100644
--- a/lib/spack/spack/test/versions.py
+++ b/lib/spack/spack/test/versions.py
@@ -676,6 +676,26 @@ def test_git_ref_comparisons(mock_git_version_info, install_mockery, mock_packag
assert str(spec_branch.version) == "git.1.x=1.2"
+@pytest.mark.skipif(sys.platform == "win32", reason="Not supported on Windows (yet)")
+def test_git_branch_with_slash():
+ class MockLookup(object):
+ def get(self, ref):
+ assert ref == "feature/bar"
+ return "1.2", 0
+
+ v = spack.version.from_string("git.feature/bar")
+ assert isinstance(v, GitVersion)
+ v.attach_lookup(MockLookup())
+
+ # Create a version range
+ test_number_version = spack.version.from_string("1.2")
+ v.satisfies(test_number_version)
+
+ serialized = VersionList([v]).to_dict()
+ v_deserialized = VersionList.from_dict(serialized)
+ assert v_deserialized[0].ref == "feature/bar"
+
+
@pytest.mark.parametrize(
"string,git",
[