From dd8a562a500e2f41ef378ae1ebf19076115fc0b1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:17:21 +0300 Subject: [PATCH 1/9] Show elapsed time for build and publishing --- .github/workflows/lint.yml | 22 ++++++++++++++++++ .github/workflows/test.yml | 39 +++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 47 ++++++++++++++++++++++++++++++++++++++ build_docs.py | 25 +++++++++++++++++--- pyproject.toml | 7 ++++++ tests/test_build_docs.py | 21 +++++++++++++++++ tox.ini | 25 ++++++++++++++++++++ 7 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test.yml create mode 100644 .pre-commit-config.yaml create mode 100644 pyproject.toml create mode 100644 tests/test_build_docs.py create mode 100644 tox.ini diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..d553e49 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,22 @@ +name: Lint + +on: [push, pull_request, workflow_dispatch] + +env: + FORCE_COLOR: 1 + PIP_DISABLE_PIP_VERSION_CHECK: 1 + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + cache: pip + - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..668336d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,39 @@ +name: Test + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: read + +env: + FORCE_COLOR: 1 + PIP_DISABLE_PIP_VERSION_CHECK: 1 + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13"] + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + + - name: Install uv + uses: hynek/setup-cached-uv@v2 + + - name: Install dependencies + run: | + uv pip install --system -U tox-uv + + - name: Tox tests + run: | + tox -e py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..db47c50 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,47 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-merge-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: forbid-submodules + - id: requirements-txt-fixer + - id: trailing-whitespace + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.28.6 + hooks: + - id: check-github-workflows + + - repo: https://github.com/rhysd/actionlint + rev: v1.7.1 + hooks: + - id: actionlint + + - repo: https://github.com/tox-dev/pyproject-fmt + rev: 2.1.3 + hooks: + - id: pyproject-fmt + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.18 + hooks: + - id: validate-pyproject + + - repo: https://github.com/tox-dev/tox-ini-fmt + rev: 1.3.1 + hooks: + - id: tox-ini-fmt + + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes + +ci: + autoupdate_schedule: quarterly diff --git a/build_docs.py b/build_docs.py index 212989e..701beb1 100755 --- a/build_docs.py +++ b/build_docs.py @@ -28,7 +28,7 @@ import json import logging import logging.handlers -from functools import total_ordering +from functools import total_ordering, cache from os import readlink import platform import re @@ -702,6 +702,7 @@ def translation_branch(self): def build(self): """Build this version/language doc.""" logging.info("Build start.") + start_time = perf_counter() sphinxopts = list(self.language.sphinxopts) sphinxopts.extend(["-q"]) if self.language.tag != "en": @@ -778,7 +779,7 @@ def is_mac(): setup_switchers( self.versions, self.languages, self.checkout / "Doc" / "build" / "html" ) - logging.info("Build done.") + logging.info("Build done (%s).", format_seconds(perf_counter() - start_time)) def build_venv(self): """Build a venv for the specific Python version. @@ -800,6 +801,7 @@ def build_venv(self): def copy_build_to_webroot(self): """Copy a given build to the appropriate webroot with appropriate rights.""" logging.info("Publishing start.") + start_time = perf_counter() self.www_root.mkdir(parents=True, exist_ok=True) if self.language.tag == "en": target = self.www_root / self.version.name @@ -912,7 +914,9 @@ def copy_build_to_webroot(self): purge(*prefixes) for prefix in prefixes: purge(*[prefix + p for p in changed]) - logging.info("Publishing done") + logging.info( + "Publishing done (%s).", format_seconds(perf_counter() - start_time) + ) def should_rebuild(self): state = self.load_state() @@ -1147,6 +1151,21 @@ def build_docs(args) -> bool: return all_built_successfully +@cache +def format_seconds(seconds: float) -> str: + hours, remainder = divmod(seconds, 3600) + minutes, seconds = divmod(remainder, 60) + seconds = round(seconds) + + match (hours, minutes, seconds): + case 0, 0, s: + return f"{s}s" + case 0, m, s: + return f"{m}m {s}s" + case h, m, s: + return f"{h}h {m}m {s}s" + + def main(): """Script entry point.""" args = parse_args() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6c56bf0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[tool.pytest.ini_options] +pythonpath = [ + ".", +] +testpaths = [ + "tests", +] diff --git a/tests/test_build_docs.py b/tests/test_build_docs.py new file mode 100644 index 0000000..975e03c --- /dev/null +++ b/tests/test_build_docs.py @@ -0,0 +1,21 @@ +import pytest + +from build_docs import format_seconds + + +@pytest.mark.parametrize( + "seconds, expected", + [ + (0.4, "0s"), + (0.5, "0s"), + (0.6, "1s"), + (1.5, "2s"), + (30, "30s"), + (60, "1m 0s"), + (185, "3m 5s"), + (454, "7m 34s"), + (7456, "2h 4m 16s"), + ], +) +def test_format_seconds(seconds: int, expected: str) -> None: + assert format_seconds(seconds) == expected diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..40a034d --- /dev/null +++ b/tox.ini @@ -0,0 +1,25 @@ +[tox] +requires = + tox>=4.2 +env_list = + lint + py{313, 312, 311, 310} + +[testenv] +package = wheel +wheel_build_env = .pkg +skip_install = true +deps = + -r requirements.txt + pytest +commands = + {envpython} -m pytest {posargs} + +[testenv:lint] +skip_install = true +deps = + pre-commit +pass_env = + PRE_COMMIT_COLOR +commands = + pre-commit run --all-files --show-diff-on-failure From 3ef52a6613cac9a265c0920c24aa9178b92f3b4c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:20:07 +0300 Subject: [PATCH 2/9] Fix hours and minutes for float input --- build_docs.py | 2 +- tests/test_build_docs.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/build_docs.py b/build_docs.py index 701beb1..0e67d7b 100755 --- a/build_docs.py +++ b/build_docs.py @@ -1155,7 +1155,7 @@ def build_docs(args) -> bool: def format_seconds(seconds: float) -> str: hours, remainder = divmod(seconds, 3600) minutes, seconds = divmod(remainder, 60) - seconds = round(seconds) + hours, minutes, seconds = int(hours), int(minutes), round(seconds) match (hours, minutes, seconds): case 0, 0, s: diff --git a/tests/test_build_docs.py b/tests/test_build_docs.py index 975e03c..4457e95 100644 --- a/tests/test_build_docs.py +++ b/tests/test_build_docs.py @@ -15,7 +15,12 @@ (185, "3m 5s"), (454, "7m 34s"), (7456, "2h 4m 16s"), + (30.1, "30s"), + (60.2, "1m 0s"), + (185.3, "3m 5s"), + (454.4, "7m 34s"), + (7456.5, "2h 4m 16s"), ], ) -def test_format_seconds(seconds: int, expected: str) -> None: +def test_format_seconds(seconds: float, expected: str) -> None: assert format_seconds(seconds) == expected From 6c194eb105f49728cc19d58f3c999eb8dbfc1ebf Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:04:34 +0300 Subject: [PATCH 3/9] Remove functools.cache --- build_docs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build_docs.py b/build_docs.py index 0e67d7b..c72c56c 100755 --- a/build_docs.py +++ b/build_docs.py @@ -28,7 +28,7 @@ import json import logging import logging.handlers -from functools import total_ordering, cache +from functools import total_ordering from os import readlink import platform import re @@ -1151,7 +1151,6 @@ def build_docs(args) -> bool: return all_built_successfully -@cache def format_seconds(seconds: float) -> str: hours, remainder = divmod(seconds, 3600) minutes, seconds = divmod(remainder, 60) From 124693f58f4cc22b9a5d40aaab73f1cb26195cb0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 25 Aug 2024 12:57:12 +0300 Subject: [PATCH 4/9] Keep build_docs() near main() --- build_docs.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/build_docs.py b/build_docs.py index c72c56c..006b050 100755 --- a/build_docs.py +++ b/build_docs.py @@ -1104,6 +1104,20 @@ def parse_languages_from_config(): return languages +def format_seconds(seconds: float) -> str: + hours, remainder = divmod(seconds, 3600) + minutes, seconds = divmod(remainder, 60) + hours, minutes, seconds = int(hours), int(minutes), round(seconds) + + match (hours, minutes, seconds): + case 0, 0, s: + return f"{s}s" + case 0, m, s: + return f"{m}m {s}s" + case h, m, s: + return f"{h}h {m}m {s}s" + + def build_docs(args) -> bool: """Build all docs (each languages and each versions).""" versions = parse_versions_from_devguide() @@ -1151,20 +1165,6 @@ def build_docs(args) -> bool: return all_built_successfully -def format_seconds(seconds: float) -> str: - hours, remainder = divmod(seconds, 3600) - minutes, seconds = divmod(remainder, 60) - hours, minutes, seconds = int(hours), int(minutes), round(seconds) - - match (hours, minutes, seconds): - case 0, 0, s: - return f"{s}s" - case 0, m, s: - return f"{m}m {s}s" - case h, m, s: - return f"{h}h {m}m {s}s" - - def main(): """Script entry point.""" args = parse_args() From 21d094e2a2e97985ad3690f8066f5f080ec19a16 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:01:47 +0300 Subject: [PATCH 5/9] Show elapsed time for full docs build --- build_docs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_docs.py b/build_docs.py index 006b050..35b794e 100755 --- a/build_docs.py +++ b/build_docs.py @@ -1120,6 +1120,8 @@ def format_seconds(seconds: float) -> str: def build_docs(args) -> bool: """Build all docs (each languages and each versions).""" + logging.info("Full build start.") + start_time = perf_counter() versions = parse_versions_from_devguide() languages = parse_languages_from_config() todo = [ @@ -1162,6 +1164,8 @@ def build_docs(args) -> bool: dev_symlink(args.www_root, args.group, versions, languages, args.skip_cache_invalidation) proofread_canonicals(args.www_root, args.skip_cache_invalidation) + logging.info("Full build done (%s).", format_seconds(perf_counter() - start_time)) + return all_built_successfully From f2d2ffb83ce8f3dac961a75d2069033b668b6dc7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:22:21 +0300 Subject: [PATCH 6/9] Update pre-commit --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db47c50..dba593f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.28.6 + rev: 0.29.2 hooks: - id: check-github-workflows @@ -24,17 +24,17 @@ repos: - id: actionlint - repo: https://github.com/tox-dev/pyproject-fmt - rev: 2.1.3 + rev: 2.2.3 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.18 + rev: v0.19 hooks: - id: validate-pyproject - repo: https://github.com/tox-dev/tox-ini-fmt - rev: 1.3.1 + rev: 1.4.0 hooks: - id: tox-ini-fmt From 652c561ac48ef8f3924ad188482058aa7be1ac11 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:44:46 +0300 Subject: [PATCH 7/9] Simplify uv + tox-uv setup --- .github/workflows/test.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 668336d..b2686a7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,10 +30,6 @@ jobs: - name: Install uv uses: hynek/setup-cached-uv@v2 - - name: Install dependencies - run: | - uv pip install --system -U tox-uv - - name: Tox tests run: | - tox -e py + uvx --with tox-uv tox -e py From c6a8855c0fba7ba7408fc4b1969ca90e3ce43c1e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:18:54 +0300 Subject: [PATCH 8/9] Using uv not pip --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b2686a7..d74e607 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,6 @@ permissions: env: FORCE_COLOR: 1 - PIP_DISABLE_PIP_VERSION_CHECK: 1 jobs: test: From b0921bd556d9b25637019184085e5e13e2830fc7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:42:11 +0300 Subject: [PATCH 9/9] Reformat pyproject.toml --- pyproject.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6c56bf0..e85ab2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,3 @@ [tool.pytest.ini_options] -pythonpath = [ - ".", -] -testpaths = [ - "tests", -] +pythonpath = [ "." ] +testpaths = [ "tests" ]