diff options
author | Sviatoslav Sydorenko <wk.cvs.github@sydorenko.org.ua> | 2023-02-23 21:37:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-23 21:37:02 +0100 |
commit | 56036013cd09db0f1b20402a69be44345ddafb22 (patch) | |
tree | 707e6bd8d194e52e91a7e92ac9ba3a126a91e5ee /packaging | |
parent | Docs: Clarify note on tags (#80079) (diff) | |
download | ansible-56036013cd09db0f1b20402a69be44345ddafb22.tar.xz ansible-56036013cd09db0f1b20402a69be44345ddafb22.zip |
๐ฆ Integrate manpage builds into PEP 517 build backend
This patch creates a thin wrapper around the `setuptools`' PEP 517
build backend in-tree. It features an ability to request generating
the manpage files in the process of building a source distribution.
This toggle is implemented using the `config_settings` mechanism of
PEP 517.
One must explicitly pass it a CLI option to the build front-end to
trigger said behavior. The packagers are expected to use the
following call:
python -m build --config-setting=--build-manpages
This option has no effect on building wheels.
๐งช The change includes integration tests
This test runs building and re-building sdists and wheels with and
without the `--build-manpages` config setting under the
oldest-supported and new `setuptools` pinned.
It is intended to preserve the interoperability of the packaging setup
across Python runtimes.
An extra smoke test also verifies that non PEP 517 interfaces remain functional.
PR #79606
Co-authored-by: Matt Clay <matt@mystile.com>
Diffstat (limited to 'packaging')
-rw-r--r-- | packaging/pep517_backend/__init__.py | 1 | ||||
-rw-r--r-- | packaging/pep517_backend/_backend.py | 108 | ||||
-rw-r--r-- | packaging/pep517_backend/hooks.py | 9 |
3 files changed, 118 insertions, 0 deletions
diff --git a/packaging/pep517_backend/__init__.py b/packaging/pep517_backend/__init__.py new file mode 100644 index 0000000000..1d3bc14c82 --- /dev/null +++ b/packaging/pep517_backend/__init__.py @@ -0,0 +1 @@ +"""PEP 517 build backend for optionally pre-building docs before setuptools.""" diff --git a/packaging/pep517_backend/_backend.py b/packaging/pep517_backend/_backend.py new file mode 100644 index 0000000000..9adbc50f2f --- /dev/null +++ b/packaging/pep517_backend/_backend.py @@ -0,0 +1,108 @@ +"""PEP 517 build backend wrapper for optionally pre-building docs for sdist.""" + +from __future__ import annotations + +import os +import subprocess +import sys +from configparser import ConfigParser +from importlib.metadata import import_module +from pathlib import Path + +from setuptools.build_meta import ( + build_sdist as _setuptools_build_sdist, + get_requires_for_build_sdist as _setuptools_get_requires_for_build_sdist, +) + + +__all__ = ( # noqa: WPS317, WPS410 + 'build_sdist', 'get_requires_for_build_sdist', +) + + +def _make_in_tree_ansible_importable() -> None: + """Add the library directory to module lookup paths.""" + lib_path = str(Path.cwd() / 'lib/') + os.environ['PYTHONPATH'] = lib_path # NOTE: for subprocesses + sys.path.insert(0, lib_path) # NOTE: for the current runtime session + + +def _get_package_distribution_version() -> str: + """Retrieve the current version number from setuptools config.""" + setup_cfg_path = Path.cwd() / 'setup.cfg' + setup_cfg = ConfigParser() + setup_cfg.read_string(setup_cfg_path.read_text()) + cfg_version = setup_cfg.get('metadata', 'version') + importable_version_str = cfg_version.removeprefix('attr: ') + version_mod_str, version_var_str = importable_version_str.rsplit('.', 1) + return getattr(import_module(version_mod_str), version_var_str) + + +def _generate_rst_in_templates() -> Path: + """Create ``*.1.rst.in`` files out of CLI Python modules.""" + generate_man_cmd = ( + sys.executable, + 'hacking/build-ansible.py', + 'generate-man', + '--template-file=docs/templates/man.j2', + '--output-dir=docs/man/man1/', + '--output-format=man', + *Path('lib/ansible/cli/').glob('*.py'), + ) + subprocess.check_call(tuple(map(str, generate_man_cmd))) + return Path('docs/man/man1/').glob('*.1.rst.in') + + +def _convert_rst_in_template_to_manpage(rst_in, version_number) -> None: + """Render pre-made ``*.1.rst.in`` templates into manpages. + + This includes pasting the hardcoded version into the resulting files. + The resulting ``in``-files are wiped in the process. + """ + templated_rst_doc = rst_in.with_suffix('') + templated_rst_doc.write_text( + rst_in.read_text().replace('%VERSION%', version_number)) + + rst_in.unlink() + + rst2man_cmd = ( + sys.executable, + Path(sys.executable).parent / 'rst2man.py', + templated_rst_doc, + templated_rst_doc.with_suffix(''), + ) + subprocess.check_call(tuple(map(str, rst2man_cmd))) + templated_rst_doc.unlink() + + +def build_sdist( # noqa: WPS210, WPS430 + sdist_directory: os.PathLike, + config_settings: dict[str, str] | None = None, +) -> str: + build_manpages_requested = '--build-manpages' in ( + config_settings or {} + ) + if build_manpages_requested: + Path('docs/man/man1/').mkdir(exist_ok=True, parents=True) + _make_in_tree_ansible_importable() + version_number = _get_package_distribution_version() + for rst_in in _generate_rst_in_templates(): + _convert_rst_in_template_to_manpage(rst_in, version_number) + + return _setuptools_build_sdist( + sdist_directory=sdist_directory, + config_settings=config_settings, + ) + + +def get_requires_for_build_sdist( + config_settings: dict[str, str] | None = None, +) -> list[str]: + return _setuptools_get_requires_for_build_sdist( + config_settings=config_settings, + ) + [ + 'docutils', # provides `rst2man` + 'jinja2', # used in `hacking/build-ansible.py generate-man` + 'straight.plugin', # used in `hacking/build-ansible.py` for subcommand + 'pyyaml', # needed for importing in-tree `ansible-core` from `lib/` + ] diff --git a/packaging/pep517_backend/hooks.py b/packaging/pep517_backend/hooks.py new file mode 100644 index 0000000000..b834338a6d --- /dev/null +++ b/packaging/pep517_backend/hooks.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +"""PEP 517 build backend for optionally pre-building docs before setuptools.""" + +from setuptools.build_meta import * # Re-exporting PEP 517 hooks # pylint: disable=unused-wildcard-import,wildcard-import + +from ._backend import ( # noqa: WPS436 # Re-exporting PEP 517 hooks + build_sdist, get_requires_for_build_sdist, +) |