From d2d1ce217023f7c79eed1bcb65d1cdba82690a7d Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Tue, 24 Jan 2023 15:53:29 +0100 Subject: [PATCH] First implementation of tox_to_nox for tox 4 --- nox/tox4_to_nox.jinja2 | 34 ++++++++++++++++++++++++++ nox/tox_to_nox.py | 55 ++++++++++++++++++++++++++++++++++++------ pyproject.toml | 2 +- 3 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 nox/tox4_to_nox.jinja2 diff --git a/nox/tox4_to_nox.jinja2 b/nox/tox4_to_nox.jinja2 new file mode 100644 index 00000000..0579bded --- /dev/null +++ b/nox/tox4_to_nox.jinja2 @@ -0,0 +1,34 @@ +import nox + +{% for envname, envconfig in config.items()|sort: %} +@nox.session({%- if envconfig.base_python %}python='{{envconfig.base_python}}'{%- endif %}) +def {{fixname(envname)}}(session): + {%- if envconfig.description != '' %} + """{{envconfig.description}}""" + {%- endif %} + {%- set envs = envconfig.get('set_env', {}) -%} + {%- for key, value in envs.items()|sort: %} + session.env['{{key}}'] = '{{value}}' + {%- endfor %} + + {%- if envconfig.deps %} + session.install({{wrapjoin(envconfig.deps)}}) + {%- endif %} + + {%- if not envconfig.skip_install %} + {%- if envconfig.use_develop %} + session.install('-e', '.') + {%- else %} + session.install('.') + {%- endif -%} + {%- endif %} + + {#- TODO: implement session.chdir -#} + {%- if envconfig.changedir and config.toxinidir.bestrelpath(envconfig.changedir) != '.' %} + session.chdir('{{config.toxinidir.bestrelpath(envconfig.changedir)}}') + {%- endif %} + + {%- for command in envconfig.commands %} + session.run('{{command}}') + {%- endfor %} +{% endfor %} diff --git a/nox/tox_to_nox.py b/nox/tox_to_nox.py index a6591b4b..fe4b8d2e 100644 --- a/nox/tox_to_nox.py +++ b/nox/tox_to_nox.py @@ -21,12 +21,23 @@ from typing import Any, Iterator import jinja2 -import tox.config +from tox import __version__ as TOX_VERSION -_TEMPLATE = jinja2.Template( - pkgutil.get_data(__name__, "tox_to_nox.jinja2").decode("utf-8"), # type: ignore[union-attr] - extensions=["jinja2.ext.do"], -) +TOX3 = TOX_VERSION[0] == "3" + +if TOX3: + import tox.config + _TEMPLATE = jinja2.Template( + pkgutil.get_data(__name__, "tox_to_nox.jinja2").decode("utf-8"), # type: ignore[union-attr] + extensions=["jinja2.ext.do"], + ) +else: + from subprocess import check_output + from configparser import ConfigParser + _TEMPLATE = jinja2.Template( + pkgutil.get_data(__name__, "tox4_to_nox.jinja2").decode("utf-8"), # type: ignore[union-attr] + extensions=["jinja2.ext.do"], + ) def wrapjoin(seq: Iterator[Any]) -> str: @@ -34,7 +45,7 @@ def wrapjoin(seq: Iterator[Any]) -> str: def fixname(envname: str) -> str: - envname = envname.replace("-", "_") + envname = envname.replace("-", "_").replace(":", "_") if not envname.isidentifier(): print( f"Environment {envname!r} is not a valid nox session name.\n" @@ -49,7 +60,37 @@ def main() -> None: args = parser.parse_args() - config = tox.config.parseconfig([]) + if TOX3: + config = tox.config.parseconfig([]) + else: + output = check_output(["tox", "config"], text=True) + original_config = ConfigParser() + original_config.read_string(output) + config = {} + + for name, section in original_config.items(): + config[name] = dict(section) + # Convert set_env from string to dict + set_env = {} + for var in section.get("set_env", "").strip().splitlines(): + k, v = var.split("=") + if k not in ("PYTHONHASHSEED", "TOX_ENV_DIR", "TOX_ENV_NAME"): + set_env[k] = v + + if set_env: + config[name]["set_env"] = set_env + + for option in "deps", "commands": + if isinstance(config[name].get(option), str): + config[name][option] = config[name][option].strip().splitlines() + + for option in "skip_install", "use_develop": + if config[name].get(option): + if config[name][option] == "False": + config[name][option] = False + else: + config[name][option] = True + output = _TEMPLATE.render(config=config, wrapjoin=wrapjoin, fixname=fixname) with open(args.output, "w") as outfile: diff --git a/pyproject.toml b/pyproject.toml index f9b8ea88..bc6d449c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ classifiers = [ [project.optional-dependencies] tox_to_nox = [ "jinja2", - "tox<4", + "tox", ] [project.urls]