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..d74e607 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: Test + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: read + +env: + FORCE_COLOR: 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: Tox tests + run: | + uvx --with tox-uv tox -e py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..dba593f --- /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.29.2 + 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.2.3 + hooks: + - id: pyproject-fmt + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.19 + hooks: + - id: validate-pyproject + + - repo: https://github.com/tox-dev/tox-ini-fmt + rev: 1.4.0 + 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 4d12fa9..a3971a5 100755 --- a/build_docs.py +++ b/build_docs.py @@ -701,6 +701,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": @@ -777,7 +778,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, http: urllib3.PoolManager) -> None: """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, http: urllib3.PoolManager) -> None: purge(http, *prefixes) for prefix in prefixes: purge(http, *[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() @@ -1141,8 +1145,24 @@ 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 language and each version).""" + logging.info("Full build start.") + start_time = perf_counter() http = urllib3.PoolManager() versions = parse_versions_from_devguide(http) languages = parse_languages_from_config() @@ -1205,6 +1225,8 @@ def build_docs(args) -> bool: ) proofread_canonicals(args.www_root, args.skip_cache_invalidation, http) + logging.info("Full build done (%s).", format_seconds(perf_counter() - start_time)) + return all_built_successfully diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e85ab2e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[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..4457e95 --- /dev/null +++ b/tests/test_build_docs.py @@ -0,0 +1,26 @@ +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"), + (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: float, 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