1 From 41387eda390183ed390f5a9e612cb0d47f68628e Mon Sep 17 00:00:00 2001
2 From: Lumir Balhar <lbalhar@redhat.com>
3 Date: Mon, 20 Feb 2023 15:26:06 +0100
4 Subject: [PATCH] to_to_nox implementation for tox 4
7 nox/tox4_to_nox.jinja2 | 33 +++++++++++++++++
8 nox/tox_to_nox.py | 84 ++++++++++++++++++++++++++++++++++++++----
10 3 files changed, 110 insertions(+), 9 deletions(-)
11 create mode 100644 nox/tox4_to_nox.jinja2
13 diff --git a/nox/tox4_to_nox.jinja2 b/nox/tox4_to_nox.jinja2
15 index 00000000..e5a67d9b
17 +++ b/nox/tox4_to_nox.jinja2
21 +{% for envname, envconfig in config.items()|sort: %}
22 +@nox.session({%- if envconfig.base_python %}python='{{envconfig.base_python}}'{%- endif %})
23 +def {{fixname(envname)}}(session):
24 + {%- if envconfig.description != '' %}
25 + """{{envconfig.description}}"""
27 + {%- set envs = envconfig.get('set_env', {}) -%}
28 + {%- for key, value in envs.items()|sort: %}
29 + session.env['{{key}}'] = '{{value}}'
32 + {%- if envconfig.deps %}
33 + session.install({{envconfig.deps}})
36 + {%- if not envconfig.skip_install %}
37 + {%- if envconfig.use_develop %}
38 + session.install('-e', '.')
40 + session.install('.')
44 + {%- if envconfig.change_dir %}
45 + session.chdir('{{envconfig.change_dir}}')
48 + {%- for command in envconfig.commands %}
49 + session.run({{command}})
52 diff --git a/nox/tox_to_nox.py b/nox/tox_to_nox.py
53 index a6591b4b..26b0146c 100644
54 --- a/nox/tox_to_nox.py
55 +++ b/nox/tox_to_nox.py
57 from __future__ import annotations
62 -from typing import Any, Iterator
64 +from configparser import ConfigParser
65 +from pathlib import Path
66 +from subprocess import check_output
67 +from typing import Any, Iterable
71 +from tox import __version__ as TOX_VERSION
73 -_TEMPLATE = jinja2.Template(
74 - pkgutil.get_data(__name__, "tox_to_nox.jinja2").decode("utf-8"), # type: ignore[union-attr]
75 - extensions=["jinja2.ext.do"],
77 +TOX4 = TOX_VERSION[0] == "4"
80 + _TEMPLATE = jinja2.Template(
81 + pkgutil.get_data(__name__, "tox4_to_nox.jinja2").decode("utf-8"), # type: ignore[union-attr]
82 + extensions=["jinja2.ext.do"],
85 + _TEMPLATE = jinja2.Template(
86 + pkgutil.get_data(__name__, "tox_to_nox.jinja2").decode("utf-8"), # type: ignore[union-attr]
87 + extensions=["jinja2.ext.do"],
90 -def wrapjoin(seq: Iterator[Any]) -> str:
92 +def wrapjoin(seq: Iterable[Any]) -> str:
93 return ", ".join([f"'{item}'" for item in seq])
96 def fixname(envname: str) -> str:
97 - envname = envname.replace("-", "_")
98 + envname = envname.replace("-", "_").replace("testenv:", "")
99 if not envname.isidentifier():
101 f"Environment {envname!r} is not a valid nox session name.\n"
102 @@ -49,7 +63,61 @@ def main() -> None:
104 args = parser.parse_args()
106 - config = tox.config.parseconfig([])
108 + output = check_output(["tox", "config"], text=True)
109 + original_config = ConfigParser()
110 + original_config.read_string(output)
111 + config: dict[str, dict[str, Any]] = {}
113 + for name, section in original_config.items():
114 + if name == "DEFAULT":
117 + config[name] = dict(section)
118 + # Convert set_env from string to dict
120 + for var in section.get("set_env", "").strip().splitlines():
121 + k, v = var.split("=")
124 + "PIP_DISABLE_PIP_VERSION_CHECK",
125 + "PYTHONIOENCODING",
129 + config[name]["set_env"] = set_env
131 + config[name]["commands"] = [
132 + wrapjoin(c.split()) for c in section["commands"].strip().splitlines()
135 + config[name]["deps"] = wrapjoin(section["deps"].strip().splitlines())
137 + for option in "skip_install", "use_develop":
138 + if section.get(option):
139 + if section[option] == "False":
140 + config[name][option] = False
142 + config[name][option] = True
144 + if os.path.isabs(section["base_python"]) or re.match(
145 + r"py\d+", section["base_python"]
148 + "python" if section["py_impl"] == "cpython" else section["py_impl"]
150 + config[name]["base_python"] = impl + section["py_dot_ver"]
152 + change_dir = Path(section.get("change_dir"))
153 + rel_to_cwd = change_dir.relative_to(Path.cwd())
154 + if str(rel_to_cwd) == ".":
155 + config[name]["change_dir"] = None
157 + config[name]["change_dir"] = rel_to_cwd
160 + config = tox.config.parseconfig([])
162 output = _TEMPLATE.render(config=config, wrapjoin=wrapjoin, fixname=fixname)
164 with open(args.output, "w") as outfile: