From c102b4c6057fc82dee834aef759bca395e705c69 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Tue, 28 Jan 2025 15:27:23 -0300 Subject: [PATCH 1/6] Migrate build.sh to Python --- .github/workflows/check.yml | 2 +- scripts/build.sh | 28 ------- scripts/manage_translations.py | 146 +++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 29 deletions(-) delete mode 100755 scripts/build.sh create mode 100755 scripts/manage_translations.py diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 0ff197d01..592a83bfe 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -70,7 +70,7 @@ jobs: - name: Build docs id: build - run: ./scripts/build.sh + run: python ./scripts/manage-translations.py build - name: Upload artifact - docs if: steps.build.outcome == 'success' diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index ee338368e..000000000 --- a/scripts/build.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -# Build translated docs to pop up errors -# -# SPDX-License-Identifier: CC0-1.0 - -set -xeu - -# Fail earlier if required variables are not set -test -n ${PYDOC_LANGUAGE+x} - -cd "$(dirname $0)/.." -mkdir -p logs - -# If version is 3.12 or older, set gettext_compact. -# This confval is not needed since 3.12. -# In 3.13, its presence messes 3.13's syntax checking (?) -opts="-D language=${PYDOC_LANGUAGE} --keep-going -w ../../logs/sphinxwarnings.txt" -minor_version=$(git -C cpython/Doc branch --show-current | sed 's|^3\.||') -if [ $minor_version -lt 12 ]; then - opts="$opts -D gettext_compact=False" -fi - -make -C cpython/Doc html SPHINXOPTS="${opts}" - -# Remove empty file -if [ ! -s logs/sphinxwarnings.txt ]; then - rm logs/sphinxwarnings.txt -fi diff --git a/scripts/manage_translations.py b/scripts/manage_translations.py new file mode 100755 index 000000000..62f817942 --- /dev/null +++ b/scripts/manage_translations.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +""" +Manage translation for Python documentation +""" + +# SPDX-License-Identifier: CC0-1.0 + + +import argparse +import logging +import os +import shutil +import subprocess +import sys +from pathlib import Path +from typing import Optional + +ROOTDIR = Path(__file__).resolve().parent.parent +COMMANDS = { + "build", +} + +# Logger configuration +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) +logger = logging.getLogger(__name__) + + +def configure_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("command", choices=COMMANDS, help="The command to execute") + parser.add_argument( + "--language", "-l", help="Language for the translated documentation" + ) + parser.add_argument("--python-version", "-v", help="Python version to be used") + parser.add_argument( + "--logs-dir", + "-L", + default=ROOTDIR / "logs", + help="Directory for logs (default: 'logs')", + ) + parser.add_argument( + "--cpython-path", + "-c", + default=ROOTDIR / "cpython", + type=Path, + help="Path to the CPython repository (default: 'cpython')", + ) + return parser + + +def get_value(env_var_name: str, arg_value: Optional[str]) -> str: + """ + Return value passed via command-line interface arguments *arg_value*, + and if not passed, use the environment variable *env_var_name* instead. + """ + + value = arg_value or os.getenv(env_var_name) + if not value: + logger.error( + f"The environment variable {env_var_name} is not defined, and no value was provided by the command line." + ) + sys.exit(1) + return value + + +def get_minor_version(version: str) -> int: + """Return Python minor *version* assuming the schema as X.Y, e.g. 3.13""" + return int(version.split(".")[1]) + + +def build(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None: + minor_version = get_minor_version(version) + warning_log = logs_dir / "sphinxwarnings.txt" + + # Sphinx options. + # Append gettext_compact=False if python version is 3.11 or older, + # because this confval was added to conf.py only in 3.12. + opts = f"-E -D language={language} --keep-going -w {warning_log}" + if minor_version < 12: + opts += " -D gettext_compact=False" + + try: + # Run the make command + logger.info( + f"Building documentation for language {language}, Python version {version}." + ) + subprocess.run( + ["make", "-C", cpython_path / "Doc", "html", f"SPHINXOPTS={opts}"], + check=True, + ) + except subprocess.CalledProcessError as e: + logger.error(f"Error executing the make command: {e}") + raise + + # Remove the warning log file if it is empty + if warning_log.exists() and warning_log.stat().st_size == 0: + warning_log.unlink() + logger.info("The warning log file was empty and has been removed.") + + +def main() -> None: + # Configure ArgumentParser + parser = configure_parser() + args = parser.parse_args() + + # Get values from environment variables or arguments + language = get_value("PYDOC_LANGUAGE", args.language) + version = get_value("PYDOC_VERSION", args.python_version) + logs_dir = Path(get_value("PYDOC_LOGS", str(args.logs_dir))) + cpython_path = args.cpython_path + + # Validate contents of the CPython local checkout + conf_file = cpython_path / "Doc" / "conf.py" + if not conf_file.exists(): + logger.error( + f"Configuration file '{conf_file}' not found. Invalid CPython checkout directory." + ) + sys.exit(1) + + # Check if the command is one of those that use Sphinx + if args.command in [ + "build", + ]: + # make is required + if not shutil.which("make"): + logger.error("Executable 'make' not found, make sure it is installed.") + sys.exit(1) + + # Create the logs directory if it doesn't exist + logs_dir.mkdir(exist_ok=True) + logger.info(f"Logs will be stored in the directory: {logs_dir}") + + if args.command == "build": + # Build the documentation + try: + build(language, version, logs_dir, cpython_path) + logger.info("Documentation built successfully.") + except Exception as e: + logger.error(f"Error building the documentation: {e}") + raise + + +if __name__ == "__main__": + main() From ad44cc1955030ac5c2afd7ac3cf2ed0f3bf04800 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Tue, 28 Jan 2025 15:37:29 -0300 Subject: [PATCH 2/6] Fix manage_translations.py filename in check.yml --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 592a83bfe..ba6540839 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -70,7 +70,7 @@ jobs: - name: Build docs id: build - run: python ./scripts/manage-translations.py build + run: python ./scripts/manage_translations.py build - name: Upload artifact - docs if: steps.build.outcome == 'success' From ed63a34e14e752674a6e80b6c4783c2ac1cbf837 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Tue, 28 Jan 2025 23:10:38 -0300 Subject: [PATCH 3/6] refactor, reduce lines, improve readbility --- scripts/manage_translations.py | 131 ++++++++++++--------------------- 1 file changed, 46 insertions(+), 85 deletions(-) diff --git a/scripts/manage_translations.py b/scripts/manage_translations.py index 62f817942..e3b4cbfe9 100755 --- a/scripts/manage_translations.py +++ b/scripts/manage_translations.py @@ -1,12 +1,9 @@ #!/usr/bin/env python -""" -Manage translation for Python documentation -""" # SPDX-License-Identifier: CC0-1.0 - import argparse +import contextlib import logging import os import shutil @@ -16,131 +13,95 @@ from typing import Optional ROOTDIR = Path(__file__).resolve().parent.parent -COMMANDS = { - "build", -} - -# Logger configuration -logging.basicConfig( - level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" -) +COMMANDS = ["build"] + +logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) def configure_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser(description=__doc__) + """Configure and return the argument parser.""" + parser = argparse.ArgumentParser(description="Manage translation for Python documentation") parser.add_argument("command", choices=COMMANDS, help="The command to execute") - parser.add_argument( - "--language", "-l", help="Language for the translated documentation" - ) - parser.add_argument("--python-version", "-v", help="Python version to be used") - parser.add_argument( - "--logs-dir", - "-L", - default=ROOTDIR / "logs", - help="Directory for logs (default: 'logs')", - ) - parser.add_argument( - "--cpython-path", - "-c", - default=ROOTDIR / "cpython", - type=Path, - help="Path to the CPython repository (default: 'cpython')", - ) + parser.add_argument("-l", "--language", help="Language for the translated documentation") + parser.add_argument("-v", "--python-version", help="Python version to be used") + parser.add_argument("-L", "--logs-dir", default=ROOTDIR / "logs", type=Path, help="Directory for logs") + parser.add_argument("-c", "--cpython-path", default=ROOTDIR / "cpython", type=Path, help="Path to the CPython repository") return parser def get_value(env_var_name: str, arg_value: Optional[str]) -> str: - """ - Return value passed via command-line interface arguments *arg_value*, - and if not passed, use the environment variable *env_var_name* instead. - """ - + """Return a CLI argument or environment variable value.""" value = arg_value or os.getenv(env_var_name) if not value: - logger.error( - f"The environment variable {env_var_name} is not defined, and no value was provided by the command line." - ) + logger.error(f"The environment variable {env_var_name} is not defined, and no value was provided.") sys.exit(1) return value def get_minor_version(version: str) -> int: - """Return Python minor *version* assuming the schema as X.Y, e.g. 3.13""" - return int(version.split(".")[1]) + """Return the minor version number from a version string (e.g., '3.13').""" + try: + return int(version.split(".")[1]) + except (IndexError, ValueError) as e: + logger.error(f"Invalid version format '{version}': {e}") + sys.exit(1) -def build(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None: +def build_docs(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None: + """Build the documentation using Sphinx.""" minor_version = get_minor_version(version) warning_log = logs_dir / "sphinxwarnings.txt" - # Sphinx options. - # Append gettext_compact=False if python version is 3.11 or older, - # because this confval was added to conf.py only in 3.12. - opts = f"-E -D language={language} --keep-going -w {warning_log}" + sphinx_opts = f"-E -D language={language} --keep-going -w {warning_log}" if minor_version < 12: - opts += " -D gettext_compact=False" + sphinx_opts += "-D gettext_compact=False" try: - # Run the make command - logger.info( - f"Building documentation for language {language}, Python version {version}." - ) - subprocess.run( - ["make", "-C", cpython_path / "Doc", "html", f"SPHINXOPTS={opts}"], - check=True, - ) + logger.info(f"Building documentation for {language}, Python {version}.") + subprocess.run([ + "make", "-C", str(cpython_path / "Doc"), "html", f"SPHINXOPTS={sphinx_opts}" + ], check=True) + + if warning_log.exists() and not warning_log.stat().st_size: + warning_log.unlink() + logger.info("Empty warning log file removed.") + except subprocess.CalledProcessError as e: - logger.error(f"Error executing the make command: {e}") - raise + logger.error(f"Make command failed: {e}") + sys.exit(1) + - # Remove the warning log file if it is empty - if warning_log.exists() and warning_log.stat().st_size == 0: - warning_log.unlink() - logger.info("The warning log file was empty and has been removed.") +def validate_paths(cpython_path: Path) -> None: + """Validate necessary paths for handling documentation.""" + if not (cpython_path / "Doc" / "conf.py").exists(): + logger.error(f"Missing conf.py in {cpython_path}. Invalid CPython directory.") + sys.exit(1) def main() -> None: - # Configure ArgumentParser parser = configure_parser() args = parser.parse_args() - # Get values from environment variables or arguments language = get_value("PYDOC_LANGUAGE", args.language) version = get_value("PYDOC_VERSION", args.python_version) logs_dir = Path(get_value("PYDOC_LOGS", str(args.logs_dir))) cpython_path = args.cpython_path - # Validate contents of the CPython local checkout - conf_file = cpython_path / "Doc" / "conf.py" - if not conf_file.exists(): - logger.error( - f"Configuration file '{conf_file}' not found. Invalid CPython checkout directory." - ) - sys.exit(1) + validate_paths(cpython_path) - # Check if the command is one of those that use Sphinx - if args.command in [ - "build", - ]: - # make is required + if args.command == "build": if not shutil.which("make"): - logger.error("Executable 'make' not found, make sure it is installed.") + logger.error("'make' not found. Please install it.") sys.exit(1) - # Create the logs directory if it doesn't exist logs_dir.mkdir(exist_ok=True) - logger.info(f"Logs will be stored in the directory: {logs_dir}") + logger.info(f"Logs will be stored in: {logs_dir}") - if args.command == "build": - # Build the documentation - try: - build(language, version, logs_dir, cpython_path) - logger.info("Documentation built successfully.") - except Exception as e: - logger.error(f"Error building the documentation: {e}") - raise + build_docs(language, version, logs_dir, cpython_path) + logger.info("Documentation build completed successfully.") if __name__ == "__main__": main() + From bd49b562569f47eea946ffb688e49c3614db0d50 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Mon, 3 Feb 2025 13:36:56 -0300 Subject: [PATCH 4/6] Add --po-dir to be used by build_docs(), add generate_templates() target --- scripts/manage_translations.py | 133 +++++++++++++++++++++++++-------- 1 file changed, 103 insertions(+), 30 deletions(-) diff --git a/scripts/manage_translations.py b/scripts/manage_translations.py index e3b4cbfe9..01dbff42c 100755 --- a/scripts/manage_translations.py +++ b/scripts/manage_translations.py @@ -6,14 +6,17 @@ import contextlib import logging import os +import re import shutil import subprocess import sys from pathlib import Path from typing import Optional +from sphinx_intl.transifex import create_txconfig, update_txconfig_resources + ROOTDIR = Path(__file__).resolve().parent.parent -COMMANDS = ["build"] +COMMANDS = ["build", 'generate_templates'] logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) @@ -25,72 +28,135 @@ def configure_parser() -> argparse.ArgumentParser: parser.add_argument("command", choices=COMMANDS, help="The command to execute") parser.add_argument("-l", "--language", help="Language for the translated documentation") parser.add_argument("-v", "--python-version", help="Python version to be used") - parser.add_argument("-L", "--logs-dir", default=ROOTDIR / "logs", type=Path, help="Directory for logs") - parser.add_argument("-c", "--cpython-path", default=ROOTDIR / "cpython", type=Path, help="Path to the CPython repository") + parser.add_argument("-L", "--logs-dir", default=ROOTDIR / "logs", type=Path, help="Directory for logs (default: 'logs' in root directory") + parser.add_argument("-c", "--cpython-path", default=ROOTDIR / "cpython", type=Path, help="Path to the CPython repository (default: 'cpython' in root directory") + parser.add_argument("-p", "--po-dir", type=Path, help="Path to the language team repository containing PO files (default: CPYTHON_PATH/Doc/locales/LANGUAGE/LC_MESSAGES") + parser.add_argument('-t', '--tx-project', help="Name of the Transifex project under python-doc Transifex organization") return parser -def get_value(env_var_name: str, arg_value: Optional[str]) -> str: +def get_value(arg_value: Optional[str], arg_name: str, env_var_name: str) -> str: """Return a CLI argument or environment variable value.""" value = arg_value or os.getenv(env_var_name) if not value: - logger.error(f"The environment variable {env_var_name} is not defined, and no value was provided.") + logger.error(f"'{arg_name}' not provided and the environment variable {env_var_name} is not set.") sys.exit(1) return value -def get_minor_version(version: str) -> int: - """Return the minor version number from a version string (e.g., '3.13').""" - try: - return int(version.split(".")[1]) - except (IndexError, ValueError) as e: - logger.error(f"Invalid version format '{version}': {e}") +def validate_cpython_path(cpython_path: Path) -> None: + if not (cpython_path / "Doc" / "conf.py").exists(): + logger.error(f"Missing conf.py in {cpython_path}. Invalid CPython directory.") sys.exit(1) -def build_docs(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None: - """Build the documentation using Sphinx.""" - minor_version = get_minor_version(version) - warning_log = logs_dir / "sphinxwarnings.txt" +def validate_po_dir(po_dir: Path) -> None: + if not po_dir.exists() or not list(po_dir.glob("*.po")): + logger.error(f"Invalid locale directory '{po_dir}'. No PO files found.") + sys.exit(1) + - sphinx_opts = f"-E -D language={language} --keep-going -w {warning_log}" - if minor_version < 12: - sphinx_opts += "-D gettext_compact=False" +def validate_tx_config(tx_config: str) -> None: + if not re.match(r"python-(newest|\d+)", tx_config): + logger.error(f"Invalid Transifex project name: {tx_config}") + sys.exit(1) + + +# contextlib implemented chdir since Python 3.11 +@contextlib.contextmanager +def chdir(path: Path): + """Temporarily change the working directory.""" + original_dir = Path.cwd() + logger.info(path) + os.chdir(path) + try: + yield + finally: + os.chdir(original_dir) + + +def build_docs(language: str, version: str, po_dir: Path, logs_dir: Path, cpython_path: Path) -> None: + """Build the documentation using Sphinx.""" + warning_log = logs_dir / "sphinx_warnings_build_docs.txt" + sphinx_opts = ["-E", "-Dgettext_compact=0", f"-Dlanguage={language}", "--keep-going", "-w", f"{warning_log}"] + locale_dirs = cpython_path / "Doc/locales" + target_locale_dir = cpython_path / "Doc/locales" / language / "LC_MESSAGES" + + # TODO Fix symlinking when po_dir is not equal to target_locale_dir + #if not po_dir.relative_to(locale_dirs) and + # not target_locale_dir.readlink() == po_dir: + # if target_locale_dir.is_symlink(): + # target_locale_dir.unlink() # remove only if it is a symlink + # if not target_locale_dir.exists() and not target_locale_dir.is_symlink(): + # (locale_dirs / language).mkdir(parents=True, exist_ok=True) + # os.symlink(po_dir, target_locale_dir) try: logger.info(f"Building documentation for {language}, Python {version}.") subprocess.run([ - "make", "-C", str(cpython_path / "Doc"), "html", f"SPHINXOPTS={sphinx_opts}" + "make", "-C", str(cpython_path / "Doc"), "html", f"SPHINXOPTS={' '.join(sphinx_opts)}" ], check=True) if warning_log.exists() and not warning_log.stat().st_size: warning_log.unlink() - logger.info("Empty warning log file removed.") + logger.info("Removed empty warning log file.") except subprocess.CalledProcessError as e: logger.error(f"Make command failed: {e}") sys.exit(1) -def validate_paths(cpython_path: Path) -> None: - """Validate necessary paths for handling documentation.""" - if not (cpython_path / "Doc" / "conf.py").exists(): - logger.error(f"Missing conf.py in {cpython_path}. Invalid CPython directory.") +def generate_templates(logs_dir: Path, cpython_path: Path, tx_project: str) -> None: + """Generate translation template files (a.k.a. POT files) with Sphinx""" + warning_log = logs_dir / "sphinx_warnings_generate_templates.txt" + all_sphinx_opts = [ + "-E", "-b", "gettext", "-Dgettext_compact=0", "--keep-going", + "-w", f"{warning_log}", "-d", "build/.doctrees-gettext", ".", "build/gettext" + ] + + try: + logger.info("Generating template files for Python docs.") + subprocess.run([ + "make", "-C", str(cpython_path / "Doc"), "build", f"ALLSPHINXOPTS={' '.join(all_sphinx_opts)}" + ], check=True) + + if warning_log.exists() and not warning_log.stat().st_size: + warning_log.unlink() + logger.info("Removed empty warning log file.") + + except subprocess.CalledProcessError as e: + logger.error(f"Make command failed: {e}") sys.exit(1) + with chdir(cpython_path / "Doc/locales"): + logger.info("Updating Transifex's resources configuration file") + Path(".tx/config").unlink(missing_ok=True) + create_txconfig() + update_txconfig_resources( + transifex_organization_name='python-doc', + transifex_project_name=tx_project, + locale_dir=Path("."), + pot_dir=Path("../build/gettext") + ) + def main() -> None: parser = configure_parser() args = parser.parse_args() - language = get_value("PYDOC_LANGUAGE", args.language) - version = get_value("PYDOC_VERSION", args.python_version) - logs_dir = Path(get_value("PYDOC_LOGS", str(args.logs_dir))) + # Set and require variable depending on the command issued by the user cpython_path = args.cpython_path + logs_dir = Path(get_value(str(args.logs_dir), "--logs-dir", "PYDOC_LOGS")) - validate_paths(cpython_path) + if args.command == "generate_templates": + tx_project = get_value(args.tx_project, "--tx-project", "PYDOC_TX_PROJECT") if args.command == "build": + language = get_value(args.language, "--language", "PYDOC_LANGUAGE") + version = get_value(args.python_version, "--python-version", "PYDOC_VERSION") + po_dir = args.po_dir.absolute() or cpython_path / f"Doc/locales/{language}/LC_MESSAGES" + + if args.command in ["build", "generate_templates"]: if not shutil.which("make"): logger.error("'make' not found. Please install it.") sys.exit(1) @@ -98,8 +164,15 @@ def main() -> None: logs_dir.mkdir(exist_ok=True) logger.info(f"Logs will be stored in: {logs_dir}") - build_docs(language, version, logs_dir, cpython_path) - logger.info("Documentation build completed successfully.") + if args.command == "build": + validate_cpython_path(cpython_path) + validate_po_dir(po_dir) + build_docs(language, version, po_dir, logs_dir, cpython_path) + logger.info("Documentation build completed successfully.") + elif args.command == "generate_templates": + validate_cpython_path(cpython_path) + validate_tx_config(tx_project) + generate_templates(logs_dir, cpython_path, tx_project) if __name__ == "__main__": From 9d6d19d92d84ae4874272e98330dc068939f3481 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Mon, 3 Feb 2025 13:39:59 -0300 Subject: [PATCH 5/6] Remove generate_templates.sh in favor of Python script --- .github/workflows/sync.yml | 2 +- scripts/generate_templates.sh | 43 ----------------------------------- 2 files changed, 1 insertion(+), 44 deletions(-) delete mode 100755 scripts/generate_templates.sh diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 7ff462ff2..be0f37346 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -86,7 +86,7 @@ jobs: # 3- Pull translations - name: Generate template files and Transifex config file - run: ./scripts/generate_templates.sh + run: python ./scripts/manage_translations.py generate_templates - name: Pull translations from Transifex id: pull diff --git a/scripts/generate_templates.sh b/scripts/generate_templates.sh deleted file mode 100755 index d1878f411..000000000 --- a/scripts/generate_templates.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# Generate .pot files and Transifex .tx/config file -# -# SPDX-License-Identifier: CC0-1.0 -# -# The following need to be set: -# PYDOC_TX_PROJECT (e.g. python-newest) -# PYDOC_LANGUAGE (e.g. pt_BR) -# TX_TOKEN (or have a ~/.transifexrc file) - -set -xeu - -# Fail earlier if required variables are not set (do not expose TX_TOKEN) -test -n ${PYDOC_TX_PROJECT+x} -test -n ${PYDOC_LANGUAGE+x} - -# Make sure to run all commands from CPython docs locales directory -cd $(dirname $0)/../cpython/Doc/locales - -# Generate message catalog template (.pot) files -# TODO: use `make -C .. gettext` when there are only Python >= 3.12 -opts='-E -b gettext -D gettext_compact=0 -d build/.doctrees . build/gettext' -make -C .. build ALLSPHINXOPTS="$opts" - -# Generate updated Transifex project configuration file (.tx/config) -rm -rf ./.tx/config -sphinx-intl create-txconfig -sphinx-intl update-txconfig-resources \ - --transifex-organization-name=python-doc \ - --transifex-project-name=$PYDOC_TX_PROJECT \ - --locale-dir=. \ - --pot-dir=../build/gettext - -# Patch .tx/config and store in the repository to enable running tx command -# Explanation: -# - Adds 'trans.$PYDOC_LANGUAGE' to not need to pass tx pull with '-l LANGUAGE' -# - Don't remove 'file_filter' otherwise tx pull complains -# - Replace PO file path to a local directory (easier manual use of tx pull) -mkdir -p "${PYDOC_LANGUAGE}/LC_MESSAGES/.tx/" -sed .tx/config \ - -e 's|.//LC_MESSAGES/||' \ - -e "/^file_filter/{p;s/file_filter/trans.${PYDOC_LANGUAGE}/g;}" \ - > "${PYDOC_LANGUAGE}/LC_MESSAGES/.tx/config" From d1601831d9cff5c0aaa448f6208f234622a83601 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Fri, 6 Jun 2025 13:28:42 -0300 Subject: [PATCH 6/6] Fix case where args.po_dir is None --- scripts/manage_translations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/manage_translations.py b/scripts/manage_translations.py index 01dbff42c..49d016ac9 100755 --- a/scripts/manage_translations.py +++ b/scripts/manage_translations.py @@ -154,7 +154,7 @@ def main() -> None: if args.command == "build": language = get_value(args.language, "--language", "PYDOC_LANGUAGE") version = get_value(args.python_version, "--python-version", "PYDOC_VERSION") - po_dir = args.po_dir.absolute() or cpython_path / f"Doc/locales/{language}/LC_MESSAGES" + po_dir = args.po_dir.absolute() if args.po_dir else cpython_path / f"Doc/locales/{language}/LC_MESSAGES" if args.command in ["build", "generate_templates"]: if not shutil.which("make"): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy