|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 |
| -from configparser import ConfigParser |
| 3 | +from configparser import ConfigParser, SectionProxy |
4 | 4 | from functools import partial
|
5 | 5 | from typing import Callable, Mapping
|
6 | 6 |
|
7 |
| -from .util import fix_and_reorder, to_boolean, to_list_of_env_values, to_py_dependencies |
| 7 | +from packaging.requirements import Requirement |
| 8 | +from packaging.version import Version |
| 9 | + |
| 10 | +from .requires import requires |
| 11 | +from .util import collect_multi_line, fix_and_reorder, to_boolean, to_list_of_env_values, to_py_dependencies |
8 | 12 |
|
9 | 13 |
|
10 | 14 | def format_tox_section(parser: ConfigParser, pin_toxenvs: list[str]) -> None:
|
11 | 15 | if not parser.has_section("tox"):
|
12 |
| - return |
| 16 | + parser.add_section("tox") |
| 17 | + tox = parser["tox"] |
| 18 | + _handle_min_version(tox) |
| 19 | + tox.pop("isolated_build", None) |
| 20 | + |
13 | 21 | tox_section_cfg: Mapping[str, Callable[[str], str]] = {
|
14 |
| - "minversion": str, |
15 | 22 | "min_version": str,
|
16 | 23 | "requires": to_py_dependencies,
|
17 | 24 | "provision_tox_env": str,
|
18 | 25 | "env_list": partial(to_list_of_env_values, pin_toxenvs),
|
19 |
| - "envlist": partial(to_list_of_env_values, pin_toxenvs), |
20 |
| - "isolated_build": to_boolean, |
21 | 26 | "package_env": str,
|
22 | 27 | "isolated_build_env": str,
|
23 | 28 | "no_package": to_boolean,
|
24 |
| - "skipsdist": to_boolean, |
25 | 29 | "skip_missing_interpreters": to_boolean,
|
26 | 30 | "ignore_base_python_conflict": to_boolean,
|
27 |
| - "ignore_basepython_conflict": to_boolean, |
28 | 31 | }
|
29 |
| - fix_and_reorder(parser, "tox", tox_section_cfg) |
| 32 | + upgrade = { |
| 33 | + "envlist": "env_list", |
| 34 | + "toxinidir": "tox_root", |
| 35 | + "toxworkdir": "work_dir", |
| 36 | + "skipsdist": "no_package", |
| 37 | + "isolated_build_env": "package_env", |
| 38 | + "setupdir": "package_root", |
| 39 | + "ignore_basepython_conflict": "ignore_base_python_conflict", |
| 40 | + } |
| 41 | + fix_and_reorder(parser, "tox", tox_section_cfg, upgrade) |
| 42 | + |
| 43 | + |
| 44 | +def _handle_min_version(tox: SectionProxy) -> None: |
| 45 | + min_version = next((tox.pop(i) for i in ("minversion", "min_version") if i in tox), None) |
| 46 | + if min_version is None or int(min_version.split(".")[0]) < 4: |
| 47 | + min_version = "4.2" |
| 48 | + tox_requires = [ |
| 49 | + Requirement(i) |
| 50 | + for i in collect_multi_line( |
| 51 | + tox.get("requires", ""), |
| 52 | + line_split=None, |
| 53 | + normalize=lambda groups: {k: requires(v) for k, v in groups.items()}, |
| 54 | + )[0] |
| 55 | + ] |
| 56 | + for _at, entry in enumerate(tox_requires): |
| 57 | + if entry.name == "tox": |
| 58 | + break |
| 59 | + else: |
| 60 | + _at = -1 |
| 61 | + if _at == -1: |
| 62 | + tox_requires.append(Requirement(f"tox>={min_version}")) |
| 63 | + else: |
| 64 | + specifiers = list(tox_requires[_at].specifier) |
| 65 | + if len(specifiers) == 0 or Version(specifiers[0].version) < Version(min_version): |
| 66 | + tox_requires[_at] = Requirement(f"tox>={min_version}") |
| 67 | + tox["requires"] = "\n".join(str(i) for i in tox_requires) |
0 commit comments