summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSviatoslav Sydorenko <webknjaz@redhat.com>2023-03-15 22:48:43 +0100
committerGitHub <noreply@github.com>2023-03-15 14:48:43 -0700
commit913db09fbb65caea4f098cde9560c6ae59fe0a4d (patch)
tree2b3e1fee9d4328748115915c75af598ebc01ae14
parent86ebd55a3cd48a8af1a284acfdedbcb28c83bcf9 (diff)
downloadansible-913db09fbb65caea4f098cde9560c6ae59fe0a4d.tar.gz
[backport-2.14] 🎨 Convert RST to manpage in-memory @ PEP 517 (#80237)
* Add _convert_rst_in_template_to_manpage arg types * 📦 Make manpage build dependencies conditional Previously, said dependencies were declared as unconditionally required even when manpages not needed to be built. This patch Makes it so they are only required when needed. * Correct _generate_rst_in_templates returned type It was marked as Path before this patch but in fact, it's iterable of paths. * 🎨 Convert RST to manpage in-memory @ PEP 517 Previously, the automation was writing a temporary templated RST on disk and calling a helper CLI script on that. But with this change, it happens with less unnecessary I/O. Co-Authored-By: Matt Davis <6775756+nitzmahone@users.noreply.github.com> * 📦Expose sdist manpage build deps unconditionally Due to a bug in pypa/build, the `get_requires_for_build_sdist()` hook is always invoked with `config_settings=None`. This means that we cannot conditionally extend build requirements in said hook. As a workaround, this patch makes hook pretend that `--built-manpages` is always passed. Ref: https://github.com/pypa/build/issues/559. --------- Co-authored-by: Matt Davis <6775756+nitzmahone@users.noreply.github.com> (cherry picked from commit 67bafafbc0d61751d2ec10b0aeccb6b01482a074) This is a backport of #80098.
-rw-r--r--packaging/pep517_backend/_backend.py68
1 files changed, 45 insertions, 23 deletions
diff --git a/packaging/pep517_backend/_backend.py b/packaging/pep517_backend/_backend.py
index 9adbc50f2f..973279d828 100644
--- a/packaging/pep517_backend/_backend.py
+++ b/packaging/pep517_backend/_backend.py
@@ -5,8 +5,11 @@ from __future__ import annotations
import os
import subprocess
import sys
+import typing as t
from configparser import ConfigParser
+from contextlib import suppress
from importlib.metadata import import_module
+from io import StringIO
from pathlib import Path
from setuptools.build_meta import (
@@ -14,16 +17,25 @@ from setuptools.build_meta import (
get_requires_for_build_sdist as _setuptools_get_requires_for_build_sdist,
)
+with suppress(ImportError):
+ # NOTE: Only available for sdist builds that bundle manpages. Declared by
+ # NOTE: `get_requires_for_build_sdist()` when `--build-manpages` is passed.
+ from docutils.core import publish_file
+ from docutils.writers import manpage
+
__all__ = ( # noqa: WPS317, WPS410
'build_sdist', 'get_requires_for_build_sdist',
)
+BUILD_MANPAGES_CONFIG_SETTING = '--build-manpages'
+"""Config setting name toggle that is used to request manpage in sdists."""
+
+
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
@@ -35,10 +47,11 @@ def _get_package_distribution_version() -> str:
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)
+ _make_in_tree_ansible_importable()
return getattr(import_module(version_mod_str), version_var_str)
-def _generate_rst_in_templates() -> Path:
+def _generate_rst_in_templates() -> t.Iterable[Path]:
"""Create ``*.1.rst.in`` files out of CLI Python modules."""
generate_man_cmd = (
sys.executable,
@@ -53,41 +66,43 @@ def _generate_rst_in_templates() -> Path:
return Path('docs/man/man1/').glob('*.1.rst.in')
-def _convert_rst_in_template_to_manpage(rst_in, version_number) -> None:
+def _convert_rst_in_template_to_manpage(
+ rst_doc_template: str,
+ destination_path: os.PathLike,
+ version_number: str,
+) -> 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))
+ templated_rst_doc = rst_doc_template.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()
+ with StringIO(templated_rst_doc) as in_mem_rst_doc:
+ publish_file(
+ source=in_mem_rst_doc,
+ destination_path=destination_path,
+ writer=manpage.Writer(),
+ )
def build_sdist( # noqa: WPS210, WPS430
sdist_directory: os.PathLike,
config_settings: dict[str, str] | None = None,
) -> str:
- build_manpages_requested = '--build-manpages' in (
+ build_manpages_requested = BUILD_MANPAGES_CONFIG_SETTING 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)
+ _convert_rst_in_template_to_manpage(
+ rst_doc_template=rst_in.read_text(),
+ destination_path=rst_in.with_suffix('').with_suffix(''),
+ version_number=version_number,
+ )
+ rst_in.unlink()
return _setuptools_build_sdist(
sdist_directory=sdist_directory,
@@ -98,11 +113,18 @@ def build_sdist( # noqa: WPS210, WPS430
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,
- ) + [
+ build_manpages_requested = BUILD_MANPAGES_CONFIG_SETTING in (
+ config_settings or {}
+ )
+ build_manpages_requested = True # FIXME: Once pypa/build#559 is addressed.
+
+ manpage_build_deps = [
'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/`
- ]
+ ] if build_manpages_requested else []
+
+ return _setuptools_get_requires_for_build_sdist(
+ config_settings=config_settings,
+ ) + manpage_build_deps