|
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