diff options
author | Harmen Stoppels <me@harmenstoppels.nl> | 2023-11-01 09:08:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-01 09:08:57 +0100 |
commit | ac976a4bf42d475328f26f34e70bf1317fc0bdec (patch) | |
tree | 673e83ccf0189ea9ff012b06164bbf91be6b7363 | |
parent | e5f3ffc04fb7a1fea237226210b0cafc9246d0f2 (diff) | |
download | spack-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.
-rw-r--r-- | lib/spack/spack/parser.py | 6 | ||||
-rw-r--r-- | lib/spack/spack/test/spec_syntax.py | 35 |
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"), ], |