summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHarmen Stoppels <me@harmenstoppels.nl>2023-11-01 09:08:57 +0100
committerGitHub <noreply@github.com>2023-11-01 09:08:57 +0100
commitac976a4bf42d475328f26f34e70bf1317fc0bdec (patch)
tree673e83ccf0189ea9ff012b06164bbf91be6b7363 /lib
parente5f3ffc04fb7a1fea237226210b0cafc9246d0f2 (diff)
downloadspack-ac976a4bf42d475328f26f34e70bf1317fc0bdec.tar.gz
spack-ac976a4bf42d475328f26f34e70bf1317fc0bdec.tar.bz2
spack-ac976a4bf42d475328f26f34e70bf1317fc0bdec.tar.xz
spack-ac976a4bf42d475328f26f34e70bf1317fc0bdec.zip
Parser: fix ambiguity with whitespace in version ranges (#40344)
Allowing white space around `:` in version ranges introduces an ambiguity: ``` a@1: b ``` parses as `a@1:b` but should really be parsed as two separate specs `a@1:` and `b`. With white space disallowed around `:` in ranges, the ambiguity is resolved.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/parser.py6
-rw-r--r--lib/spack/spack/test/spec_syntax.py35
2 files changed, 27 insertions, 14 deletions
diff --git a/lib/spack/spack/parser.py b/lib/spack/spack/parser.py
index 55eee4f154..b73a189797 100644
--- a/lib/spack/spack/parser.py
+++ b/lib/spack/spack/parser.py
@@ -96,9 +96,9 @@ else:
VALUE = r"(?:[a-zA-Z_0-9\-+\*.,:=\~\/\\]+)"
QUOTED_VALUE = r"[\"']+(?:[a-zA-Z_0-9\-+\*.,:=\~\/\\\s]+)[\"']+"
-VERSION = r"=?([a-zA-Z0-9_][a-zA-Z_0-9\-\.]*\b)"
-VERSION_RANGE = rf"({VERSION}\s*:\s*{VERSION}(?!\s*=)|:\s*{VERSION}(?!\s*=)|{VERSION}\s*:|:)"
-VERSION_LIST = rf"({VERSION_RANGE}|{VERSION})(\s*[,]\s*({VERSION_RANGE}|{VERSION}))*"
+VERSION = r"=?(?:[a-zA-Z0-9_][a-zA-Z_0-9\-\.]*\b)"
+VERSION_RANGE = rf"(?:(?:{VERSION})?:(?:{VERSION}(?!\s*=))?)"
+VERSION_LIST = rf"(?:{VERSION_RANGE}|{VERSION})(?:\s*,\s*(?:{VERSION_RANGE}|{VERSION}))*"
class TokenBase(enum.Enum):
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index e7a760dc93..1d98731785 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -472,33 +472,46 @@ def specfile_for(default_mock_concretization):
[Token(TokenType.PROPAGATED_KEY_VALUE_PAIR, value='cflags=="-O3 -g"')],
'cflags=="-O3 -g"',
),
- # Way too many spaces
+ # Whitespace is allowed in version lists
+ ("@1.2:1.4 , 1.6 ", [Token(TokenType.VERSION, value="@1.2:1.4 , 1.6")], "@1.2:1.4,1.6"),
+ # But not in ranges. `a@1:` and `b` are separate specs, not a single `a@1:b`.
(
- "@1.2 : 1.4 , 1.6 ",
- [Token(TokenType.VERSION, value="@1.2 : 1.4 , 1.6")],
- "@1.2:1.4,1.6",
+ "a@1: b",
+ [
+ Token(TokenType.UNQUALIFIED_PACKAGE_NAME, value="a"),
+ Token(TokenType.VERSION, value="@1:"),
+ Token(TokenType.UNQUALIFIED_PACKAGE_NAME, value="b"),
+ ],
+ "a@1:",
+ ),
+ (
+ "@1.2: develop = foo",
+ [
+ Token(TokenType.VERSION, value="@1.2:"),
+ Token(TokenType.KEY_VALUE_PAIR, value="develop = foo"),
+ ],
+ "@1.2: develop=foo",
),
- ("@1.2 : develop", [Token(TokenType.VERSION, value="@1.2 : develop")], "@1.2:develop"),
(
- "@1.2 : develop = foo",
+ "@1.2:develop = foo",
[
- Token(TokenType.VERSION, value="@1.2 :"),
+ Token(TokenType.VERSION, value="@1.2:"),
Token(TokenType.KEY_VALUE_PAIR, value="develop = foo"),
],
"@1.2: develop=foo",
),
(
- "% intel @ 12.1 : 12.6 + debug",
+ "% intel @ 12.1:12.6 + debug",
[
- Token(TokenType.COMPILER_AND_VERSION, value="% intel @ 12.1 : 12.6"),
+ Token(TokenType.COMPILER_AND_VERSION, value="% intel @ 12.1:12.6"),
Token(TokenType.BOOL_VARIANT, value="+ debug"),
],
"%intel@12.1:12.6+debug",
),
(
- "@ 12.1 : 12.6 + debug - qt_4",
+ "@ 12.1:12.6 + debug - qt_4",
[
- Token(TokenType.VERSION, value="@ 12.1 : 12.6"),
+ Token(TokenType.VERSION, value="@ 12.1:12.6"),
Token(TokenType.BOOL_VARIANT, value="+ debug"),
Token(TokenType.BOOL_VARIANT, value="- qt_4"),
],