From d9caa1805e0aa245ddab88c92dcf8e7e578f7c3c Mon Sep 17 00:00:00 2001 From: egeakman Date: Tue, 26 Sep 2023 00:03:46 +0300 Subject: [PATCH 1/8] Changes for the upcoming release --- .github/workflows/tests.yaml | 6 +++--- .pre-commit-config.yaml | 8 +++++--- README.md | 4 ++++ bootstrapper/data/Makefile | 4 +--- bootstrapper/data/README.md | 13 +++++++++++-- setup.py | 2 +- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e025e55..981de94 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -15,11 +15,11 @@ jobs: strategy: matrix: os: [macos-latest, windows-latest, ubuntu-latest] - python-version: ["3.10", "3.11", "3.12-dev"] + python-version: ["3.11", "3.12-dev"] steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 @@ -42,7 +42,7 @@ jobs: run: pip install . - name: Run the package - run: bootstrapper tr -b 3.12 + run: bootstrapper tr -b ${{ matrix.python-version }} - name: See results (non-Windows) if: matrix.os != 'windows-latest' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f0f99b1..aa59032 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,14 +5,16 @@ repos: - id: isort name: isort (python) - - repo: https://github.com/psf/black - rev: 23.7.0 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.9.1 hooks: - id: black - name: black (python) - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: + - id: check-case-conflict + - id: check-merge-conflict + - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace diff --git a/README.md b/README.md index 675324f..70d74f2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ This repository contains the scripts and data used to bootstrap a new translation of the Python documentation. +## Why python-docs-bootstrapper? + +... + ## Installation ```bash diff --git a/bootstrapper/data/Makefile b/bootstrapper/data/Makefile index 3cd30f1..cdc2c23 100644 --- a/bootstrapper/data/Makefile +++ b/bootstrapper/data/Makefile @@ -10,9 +10,7 @@ # - make clean # To remove build artifacts # - make fuzzy # To find fuzzy strings # -# Modes are: autobuild-stable, autobuild-dev, and autobuild-html, -# documented in gen/src/3.6/Doc/Makefile as we're only delegating the -# real work to the Python Doc Makefile. +# Modes are: autobuild-stable, autobuild-dev, and autobuild-html # Configuration diff --git a/bootstrapper/data/README.md b/bootstrapper/data/README.md index 4181a41..63c91ba 100644 --- a/bootstrapper/data/README.md +++ b/bootstrapper/data/README.md @@ -2,16 +2,25 @@ Hello! This is the repository of the {{translation.language}} translation of the Python documentation. -You can refer to the following resources throughout this journey: +**You can refer to the following resources throughout this journey:** - [DevGuide Translating Section](https://devguide.python.org/documentation/translating/) (add your translation to the list!) - [PEP 545](https://www.python.org/dev/peps/pep-0545/) (the PEP that describes the translation process) - [Other Translations](https://github.com/orgs/python/repositories?q=python-docs) (see how other translations are doing it) - [Python Docs Discord Server](https://discord.com/invite/sMWqvzXvde) (especially the `#translations` channel) +**Tips for the maintainers:** + +... + +**The ultimate checklist to get you started:** + +... + + ## Documentation Contribution Agreement Python's documentation is maintained using a global network of volunteers. By posting this project on Transifex, Github, and other public places, and inviting you to participate, we are proposing an agreement that you will provide your improvements to Python's documentation or the translation of Python's documentation for the PSF's use under the CC0 license (available at https://creativecommons.org/publicdomain/zero/1.0/legalcode). In return, you may publicly claim credit for the portion of the translation you contributed and if your translation is accepted by the PSF, you may (but are not required to) submit a patch including an appropriate annotation in the Misc/ACKS or TRANSLATORS file. Although nothing in this Documentation Contribution Agreement obligates the PSF to incorporate your textual contribution, your participation in the Python community is welcomed and appreciated. You signify acceptance of this agreement by submitting your work to the PSF for inclusion in the documentation. -**Do not forget to replace this file with your own README that describes your translation and community!** +***Do not forget to replace this file with your own README that describes your translation and community, while keeping the above agreement!*** diff --git a/setup.py b/setup.py index 75b3bea..5b89749 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import find_packages, setup -version = "0.1.1" +version = "0.1.2" with open("README.md", "r", encoding="utf-8") as f: long_description = f.read() From 94b69f2d821981f38609a1e11db9de3a491f2818 Mon Sep 17 00:00:00 2001 From: egeakman Date: Tue, 26 Sep 2023 00:39:03 +0300 Subject: [PATCH 2/8] optimize cloning sequence --- .github/workflows/tests.yaml | 4 ++-- bootstrapper/bootstrapper.py | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 981de94..16d8a48 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [macos-latest, windows-latest, ubuntu-latest] - python-version: ["3.11", "3.12-dev"] + python-version: ["3.11", "3.12"] steps: - name: Checkout repo @@ -41,7 +41,7 @@ jobs: - name: Install the package run: pip install . - - name: Run the package + - name: Run the bootstrapper run: bootstrapper tr -b ${{ matrix.python-version }} - name: See results (non-Windows) diff --git a/bootstrapper/bootstrapper.py b/bootstrapper/bootstrapper.py index d39124b..af39729 100644 --- a/bootstrapper/bootstrapper.py +++ b/bootstrapper/bootstrapper.py @@ -59,19 +59,18 @@ def setup_cpython_repo(self) -> None: "clone", "https://github.com/python/cpython.git", self.cpython_repo, + f"--branch={self.branch}", "-q", ], check=True, ) - print("✅") - subprocess.run( - ["git", "-C", self.cpython_repo, "checkout", self.branch, "-q"], check=True - ) subprocess.run( ["git", "-C", self.cpython_repo, "pull", "--ff-only", "-q"], check=True ) + print("✅") + logger.info("Building gettext files...") subprocess.run( [ From 98d68576b8570ad88e36fcedd3451ca5baba387a Mon Sep 17 00:00:00 2001 From: egeakman Date: Tue, 26 Sep 2023 00:53:50 +0300 Subject: [PATCH 3/8] fix tests --- .github/workflows/tests.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 16d8a48..04866bd 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -15,7 +15,8 @@ jobs: strategy: matrix: os: [macos-latest, windows-latest, ubuntu-latest] - python-version: ["3.11", "3.12"] + python-version: ["3.11", "3.12-dev"] + build-version: ["3.11", "3.12"] steps: - name: Checkout repo @@ -42,7 +43,7 @@ jobs: run: pip install . - name: Run the bootstrapper - run: bootstrapper tr -b ${{ matrix.python-version }} + run: bootstrapper tr -b ${{ matrix.build-version }} - name: See results (non-Windows) if: matrix.os != 'windows-latest' From 34e69b4d6650863b3cc7442a206ebd133a1a053f Mon Sep 17 00:00:00 2001 From: egeakman Date: Tue, 26 Sep 2023 01:04:59 +0300 Subject: [PATCH 4/8] add pre-commit checks --- .github/workflows/pre-commit.yaml | 17 +++++++++++++++++ .github/workflows/tests.yaml | 10 ++-------- 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/pre-commit.yaml diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 0000000..7f45b41 --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,17 @@ +name: pre-commit checks + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 04866bd..ae72a43 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,12 +1,6 @@ name: Tests -on: - workflow_dispatch: - push: - branches: - - "**" - pull_request: - branches: - - "**" + +on: [push, pull_request, workflow_dispatch] jobs: test: From 196c70e9cb3338491043ad369caf77cea335d4a8 Mon Sep 17 00:00:00 2001 From: egeakman Date: Tue, 26 Sep 2023 01:06:13 +0300 Subject: [PATCH 5/8] update pre-commit.yaml --- .github/workflows/pre-commit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 7f45b41..3bcf53d 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -6,7 +6,7 @@ permissions: contents: read jobs: - lint: + check: runs-on: ubuntu-latest steps: From d35f9a15124caf804c0d2fb3edb2c7b15ec6a411 Mon Sep 17 00:00:00 2001 From: Ege Akman Date: Wed, 8 Nov 2023 00:38:37 +0300 Subject: [PATCH 6/8] Update .github/workflows/tests.yaml --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ae72a43..d73657f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [macos-latest, windows-latest, ubuntu-latest] - python-version: ["3.11", "3.12-dev"] + python-version: ["3.11", "3.12"] build-version: ["3.11", "3.12"] steps: From 8cef98247a00531647000ed85c557a2bbff8b079 Mon Sep 17 00:00:00 2001 From: egeakman Date: Thu, 9 Nov 2023 00:20:29 +0300 Subject: [PATCH 7/8] Optimized folder discovery and creation --- README.md | 4 ---- bootstrapper/bootstrapper.py | 33 ++++++++++++++------------------- bootstrapper/data/README.md | 9 --------- 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 70d74f2..675324f 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,6 @@ This repository contains the scripts and data used to bootstrap a new translation of the Python documentation. -## Why python-docs-bootstrapper? - -... - ## Installation ```bash diff --git a/bootstrapper/bootstrapper.py b/bootstrapper/bootstrapper.py index af39729..2ae40f5 100644 --- a/bootstrapper/bootstrapper.py +++ b/bootstrapper/bootstrapper.py @@ -46,7 +46,7 @@ def create_dirs(self) -> None: logger.info("Creating directories...") os.makedirs(self.translation_repo, exist_ok=True) os.makedirs(self.cpython_repo, exist_ok=True) - print("✅") + logger.info("✅\n") def setup_cpython_repo(self) -> None: if not os.path.exists(f"{self.cpython_repo}/.git") and not os.path.isdir( @@ -64,12 +64,13 @@ def setup_cpython_repo(self) -> None: ], check=True, ) + logger.info("✅\n") + logger.info("Updating CPython repo...") subprocess.run( ["git", "-C", self.cpython_repo, "pull", "--ff-only", "-q"], check=True ) - - print("✅") + logger.info("✅\n") logger.info("Building gettext files...") subprocess.run( @@ -84,7 +85,7 @@ def setup_cpython_repo(self) -> None: cwd=self.cpython_repo, check=True, ) - print("✅") + logger.info("✅\n") def setup_translation_repo(self) -> None: logger.info("Initializing translation repo...") @@ -92,13 +93,10 @@ def setup_translation_repo(self) -> None: subprocess.run( ["git", "branch", "-m", self.branch], cwd=self.translation_repo, check=True ) - print("✅") + logger.info("✅\n") logger.info("Copying gettext files...") - files = glob.glob(f"{self.cpython_repo}/pot/**/*.pot") + glob.glob( - f"{self.cpython_repo}/pot/*.pot" - ) - + files = glob.glob(f"{self.cpython_repo}/pot/**/*.pot", recursive=True) files = [path.replace("\\", "/") for path in files] for file in files: @@ -107,13 +105,10 @@ def setup_translation_repo(self) -> None: ".pot", ".po" ) ) - - if len(file.split("/")) > 5: - os.makedirs("/".join(dest_path.split("/")[:2]), exist_ok=True) - + os.makedirs(os.path.dirname(dest_path), exist_ok=True) shutil.copyfile(file, dest_path) files[files.index(file)] = dest_path - print("✅") + logger.info("✅\n") logger.info("Cleaning up gettext files...") for file in files: @@ -122,7 +117,7 @@ def setup_translation_repo(self) -> None: contents = re.sub("^#: .*Doc/", "#: ", contents, flags=re.M) with open(file, "w", encoding="utf-8") as f: f.write(contents) - print("✅") + logger.info("✅\n") def create_readme(self) -> None: logger.info("Creating README.md...") @@ -140,7 +135,7 @@ def create_readme(self) -> None: with open(f"{self.translation_repo}/README.md", "w", encoding="utf-8") as f: f.write(readme) - print("✅") + logger.info("✅\n") def create_gitignore(self) -> None: logger.info("Creating .gitignore...") @@ -156,10 +151,10 @@ def create_gitignore(self) -> None: with open(f"{self.translation_repo}/.gitignore", "w", encoding="utf-8") as f: f.write(gitignore) - print("✅") + logger.info("✅\n") def create_makefile(self) -> None: - logging.info("Creating .makefile...") + logging.info("Creating Makefile...") try: makefile = self._request(self.makefile_url) except (urllib.error.HTTPError, urllib.error.URLError): @@ -186,7 +181,7 @@ def create_makefile(self) -> None: with open(f"{self.translation_repo}/Makefile", "w", encoding="utf-8") as f: f.write(makefile) - print("✅") + logger.info("✅\n") def run(self) -> None: try: diff --git a/bootstrapper/data/README.md b/bootstrapper/data/README.md index 63c91ba..7328c5d 100644 --- a/bootstrapper/data/README.md +++ b/bootstrapper/data/README.md @@ -9,15 +9,6 @@ Hello! This is the repository of the {{translation.language}} translation of the - [Other Translations](https://github.com/orgs/python/repositories?q=python-docs) (see how other translations are doing it) - [Python Docs Discord Server](https://discord.com/invite/sMWqvzXvde) (especially the `#translations` channel) -**Tips for the maintainers:** - -... - -**The ultimate checklist to get you started:** - -... - - ## Documentation Contribution Agreement Python's documentation is maintained using a global network of volunteers. By posting this project on Transifex, Github, and other public places, and inviting you to participate, we are proposing an agreement that you will provide your improvements to Python's documentation or the translation of Python's documentation for the PSF's use under the CC0 license (available at https://creativecommons.org/publicdomain/zero/1.0/legalcode). In return, you may publicly claim credit for the portion of the translation you contributed and if your translation is accepted by the PSF, you may (but are not required to) submit a patch including an appropriate annotation in the Misc/ACKS or TRANSLATORS file. Although nothing in this Documentation Contribution Agreement obligates the PSF to incorporate your textual contribution, your participation in the Python community is welcomed and appreciated. From eda66d8a5199db51d6a2cf000fe4e9b0f48fdea3 Mon Sep 17 00:00:00 2001 From: egeakman Date: Thu, 9 Nov 2023 00:51:41 +0300 Subject: [PATCH 8/8] Make the logger customizable --- bootstrapper/bootstrapper.py | 76 ++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/bootstrapper/bootstrapper.py b/bootstrapper/bootstrapper.py index 2ae40f5..8708a4e 100644 --- a/bootstrapper/bootstrapper.py +++ b/bootstrapper/bootstrapper.py @@ -21,17 +21,16 @@ def emit(self, record): self.flush() -logger = logging.getLogger() -logger.setLevel(logging.INFO) -handler = _NoNewLine() -handler.setFormatter(logging.Formatter("%(message)s")) -logger.addHandler(handler) - - class Bootstrapper: - def __init__(self, language: str, branch: str = "3.12") -> None: + def __init__( + self, + language: str, + branch: str = "3.12", + logger: logging.Logger = logging.getLogger(), + ) -> None: self.language = language self.branch = branch + self.logger = logger self.translation_repo = f"python-docs-{self.language}" self.cpython_repo = f"{self.translation_repo}/venv/cpython" self.readme_url = "https://raw.githubusercontent.com/egeakman/python-docs-bootstrapper/master/bootstrapper/data/README.md" @@ -43,16 +42,16 @@ def _request(self, url: str) -> str: return response.read().decode() def create_dirs(self) -> None: - logger.info("Creating directories...") + self.logger.info("Creating directories...") os.makedirs(self.translation_repo, exist_ok=True) os.makedirs(self.cpython_repo, exist_ok=True) - logger.info("✅\n") + self.logger.info("✅\n") def setup_cpython_repo(self) -> None: if not os.path.exists(f"{self.cpython_repo}/.git") and not os.path.isdir( f"{self.cpython_repo}/.git" ): - logger.info("Cloning CPython repo...") + self.logger.info("Cloning CPython repo...") subprocess.run( [ "git", @@ -64,15 +63,15 @@ def setup_cpython_repo(self) -> None: ], check=True, ) - logger.info("✅\n") + self.logger.info("✅\n") - logger.info("Updating CPython repo...") + self.logger.info("Updating CPython repo...") subprocess.run( ["git", "-C", self.cpython_repo, "pull", "--ff-only", "-q"], check=True ) - logger.info("✅\n") + self.logger.info("✅\n") - logger.info("Building gettext files...") + self.logger.info("Building gettext files...") subprocess.run( [ "sphinx-build", @@ -85,17 +84,17 @@ def setup_cpython_repo(self) -> None: cwd=self.cpython_repo, check=True, ) - logger.info("✅\n") + self.logger.info("✅\n") def setup_translation_repo(self) -> None: - logger.info("Initializing translation repo...") + self.logger.info("Initializing translation repo...") subprocess.run(["git", "init", "-q"], cwd=self.translation_repo, check=True) subprocess.run( ["git", "branch", "-m", self.branch], cwd=self.translation_repo, check=True ) - logger.info("✅\n") + self.logger.info("✅\n") - logger.info("Copying gettext files...") + self.logger.info("Copying gettext files...") files = glob.glob(f"{self.cpython_repo}/pot/**/*.pot", recursive=True) files = [path.replace("\\", "/") for path in files] @@ -108,63 +107,59 @@ def setup_translation_repo(self) -> None: os.makedirs(os.path.dirname(dest_path), exist_ok=True) shutil.copyfile(file, dest_path) files[files.index(file)] = dest_path - logger.info("✅\n") + self.logger.info("✅\n") - logger.info("Cleaning up gettext files...") + self.logger.info("Cleaning up gettext files...") for file in files: with open(file, "r", encoding="utf-8") as f: contents = f.read() contents = re.sub("^#: .*Doc/", "#: ", contents, flags=re.M) with open(file, "w", encoding="utf-8") as f: f.write(contents) - logger.info("✅\n") + self.logger.info("✅\n") def create_readme(self) -> None: - logger.info("Creating README.md...") + self.logger.info("Creating README.md...") try: readme = self._request(self.readme_url) except (urllib.error.HTTPError, urllib.error.URLError): - logger.warning( + self.logger.warning( "\n ⚠️ Failed to fetch README.md from GitHub, using local copy..." ) readme = Path(f"{os.path.dirname(__file__)}/data/README.md").read_text( encoding="utf-8" ) - readme = readme.replace("{{translation.language}}", self.language) - with open(f"{self.translation_repo}/README.md", "w", encoding="utf-8") as f: f.write(readme) - logger.info("✅\n") + self.logger.info("✅\n") def create_gitignore(self) -> None: - logger.info("Creating .gitignore...") + self.logger.info("Creating .gitignore...") try: gitignore = self._request(self.gitignore_url) except (urllib.error.HTTPError, urllib.error.URLError): - logger.warning( + self.logger.warning( "\n ⚠️ Failed to fetch .gitignore from GitHub, using local copy..." ) gitignore = Path(f"{os.path.dirname(__file__)}/data/.gitignore").read_text( encoding="utf-8" ) - with open(f"{self.translation_repo}/.gitignore", "w", encoding="utf-8") as f: f.write(gitignore) - logger.info("✅\n") + self.logger.info("✅\n") def create_makefile(self) -> None: logging.info("Creating Makefile...") try: makefile = self._request(self.makefile_url) except (urllib.error.HTTPError, urllib.error.URLError): - logger.warning( + self.logger.warning( "\n ⚠️ Failed to fetch Makefile from GitHub, using local copy..." ) makefile = Path(f"{os.path.dirname(__file__)}/data/Makefile").read_text( encoding="utf-8" ) - head = ( subprocess.run( ["git", "-C", self.cpython_repo, "rev-parse", "HEAD"], @@ -174,14 +169,12 @@ def create_makefile(self) -> None: .stdout.strip() .decode() ) - makefile = makefile.replace("{{translation.language}}", self.language) makefile = makefile.replace("{{translation.branch}}", self.branch) makefile = makefile.replace("{{translation.head}}", head) - with open(f"{self.translation_repo}/Makefile", "w", encoding="utf-8") as f: f.write(makefile) - logger.info("✅\n") + self.logger.info("✅\n") def run(self) -> None: try: @@ -191,9 +184,11 @@ def run(self) -> None: self.create_readme() self.create_gitignore() self.create_makefile() - logger.info(f"🎉 Done bootstrapping the {self.language} translation ✅\n") + self.logger.info( + f"🎉 Done bootstrapping the {self.language} translation ✅\n" + ) except Exception as e: - logger.critical( + self.logger.critical( f"❌ Bootstrapping of the {self.language} translation failed: {e}\n" ) sys.exit(1) @@ -212,6 +207,11 @@ def main() -> None: "-b", "--branch", type=str, default="3.12", help="CPython branch (e.g. 3.12)" ) args = parser.parse_args() + logger = logging.getLogger() + logger.setLevel(logging.INFO) + handler = _NoNewLine() + handler.setFormatter(logging.Formatter("%(message)s")) + logger.addHandler(handler) Bootstrapper(args.language.lower().replace("_", "-"), args.branch).run()