|
17 | 17 |
|
18 | 18 | import configparser
|
19 | 19 | import hashlib
|
| 20 | +import re |
20 | 21 | import sys
|
21 | 22 | from collections import defaultdict
|
22 | 23 | from functools import reduce
|
|
25 | 26 |
|
26 | 27 | from jinja2 import Environment, FileSystemLoader
|
27 | 28 |
|
| 29 | +TOXENV_REGEX = re.compile( |
| 30 | + r""" |
| 31 | + {?(?P<py_versions>(py\d+\.\d+,?)+)}? |
| 32 | + -(?P<framework>[a-z](?:[a-z_]|-(?!v{?\d|latest))*[a-z0-9]) |
| 33 | + (?:-( |
| 34 | + (v{?(?P<framework_versions>[0-9.]+[0-9a-z,.]*}?)) |
| 35 | + | |
| 36 | + (?P<framework_versions_latest>latest) |
| 37 | + ))? |
| 38 | +""", |
| 39 | + re.VERBOSE, |
| 40 | +) |
28 | 41 |
|
29 | 42 | OUT_DIR = Path(__file__).resolve().parent.parent.parent / ".github" / "workflows"
|
30 | 43 | TOX_FILE = Path(__file__).resolve().parent.parent.parent / "tox.ini"
|
@@ -202,29 +215,37 @@ def parse_tox():
|
202 | 215 | py_versions_pinned = defaultdict(set)
|
203 | 216 | py_versions_latest = defaultdict(set)
|
204 | 217 |
|
| 218 | + parsed_correctly = True |
| 219 | + |
205 | 220 | for line in lines:
|
206 | 221 | # normalize lines
|
207 | 222 | line = line.strip().lower()
|
208 | 223 |
|
209 | 224 | try:
|
210 | 225 | # parse tox environment definition
|
211 |
| - try: |
212 |
| - (raw_python_versions, framework, framework_versions) = line.split("-") |
213 |
| - except ValueError: |
214 |
| - (raw_python_versions, framework) = line.split("-") |
215 |
| - framework_versions = [] |
| 226 | + parsed = TOXENV_REGEX.match(line) |
| 227 | + if not parsed: |
| 228 | + print(f"ERROR reading line {line}") |
| 229 | + raise ValueError("Failed to parse tox environment definition") |
| 230 | + |
| 231 | + groups = parsed.groupdict() |
| 232 | + raw_python_versions = groups["py_versions"] |
| 233 | + framework = groups["framework"] |
| 234 | + framework_versions_latest = groups.get("framework_versions_latest") or False |
216 | 235 |
|
217 | 236 | # collect python versions to test the framework in
|
218 |
| - raw_python_versions = set( |
219 |
| - raw_python_versions.replace("{", "").replace("}", "").split(",") |
220 |
| - ) |
221 |
| - if "latest" in framework_versions: |
| 237 | + raw_python_versions = set(raw_python_versions.split(",")) |
| 238 | + if framework_versions_latest: |
222 | 239 | py_versions_latest[framework] |= raw_python_versions
|
223 | 240 | else:
|
224 | 241 | py_versions_pinned[framework] |= raw_python_versions
|
225 | 242 |
|
226 |
| - except ValueError: |
| 243 | + except Exception: |
227 | 244 | print(f"ERROR reading line {line}")
|
| 245 | + parsed_correctly = False |
| 246 | + |
| 247 | + if not parsed_correctly: |
| 248 | + raise RuntimeError("Failed to parse tox.ini") |
228 | 249 |
|
229 | 250 | py_versions_pinned = _normalize_py_versions(py_versions_pinned)
|
230 | 251 | py_versions_latest = _normalize_py_versions(py_versions_latest)
|
|
0 commit comments