Skip to content

Commit 5dd7ad5

Browse files
committed
Merge remote-tracking branch 'upstream/main' into clang-format
2 parents a86e93a + 9a01cb9 commit 5dd7ad5

24 files changed

Lines changed: 461 additions & 35 deletions

File tree

‎.gitattributes‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,11 @@ pixi.lock merge=binary linguist-language=YAML linguist-generated=true
1414
# `setuptools-scm` to correctly determine the version when building from a git
1515
# archive. See #1609.
1616
.git_archival.txt export-subst
17+
18+
# cuda.core compiles against the libcu++ headers of the vendored CCCL submodule
19+
# only; cuda_core/MANIFEST.in grafts those headers (and their licenses) into the
20+
# sdist explicitly. setuptools-scm 10 lists the files of an initialized
21+
# submodule, which would otherwise add the entire CCCL tree to the sdist and
22+
# make every egg_info walk it. "export-ignore" makes its file finder skip the
23+
# submodule. See #2940.
24+
cuda_core/third_party/cccl export-ignore

‎.github/actions/check-doc-links/action.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ runs:
2525
shell: bash --noprofile --norc -euo pipefail {0}
2626
env:
2727
KIND: ${{ inputs.kind }}
28-
LYCHEE_VERSION: v0.24.2 # Must match the pinned rev in .pre-commit-config.yaml
28+
LYCHEE_VERSION: v0.24.2 # Must match lychee-bin in .pre-commit-config.yaml
2929
POLICY_HASH: ${{ hashFiles('lychee.toml', '.github/actions/check-doc-links/action.yml', 'ci/tools/prepare_lychee_inputs.py', 'ci/tools/retry_lychee.py') }}
3030
# The first pass and all retries use the same inputs and cache policy.
3131
LYCHEE_ARGS: >-

‎.github/workflows/build-wheel.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ jobs:
246246
CC="/host/${{ env.SCCACHE_PATH }} cc"
247247
CXX="/host/${{ env.SCCACHE_PATH }} c++"
248248
SCCACHE_GHA_ENABLED=true
249+
SCCACHE_PREPROCESSOR_CACHE_GHA_ENABLED=true
249250
ACTIONS_RUNTIME_TOKEN=${{ env.ACTIONS_RUNTIME_TOKEN }}
250251
ACTIONS_RESULTS_URL=${{ env.ACTIONS_RESULTS_URL }}
251252
ACTIONS_CACHE_SERVICE_V2=${{ env.ACTIONS_CACHE_SERVICE_V2 }}
@@ -343,6 +344,7 @@ jobs:
343344
CC="/host/${{ env.SCCACHE_PATH }} cc"
344345
CXX="/host/${{ env.SCCACHE_PATH }} c++"
345346
SCCACHE_GHA_ENABLED=true
347+
SCCACHE_PREPROCESSOR_CACHE_GHA_ENABLED=true
346348
ACTIONS_RUNTIME_TOKEN=${{ env.ACTIONS_RUNTIME_TOKEN }}
347349
ACTIONS_RESULTS_URL=${{ env.ACTIONS_RESULTS_URL }}
348350
ACTIONS_CACHE_SERVICE_V2=${{ env.ACTIONS_CACHE_SERVICE_V2 }}
@@ -620,6 +622,7 @@ jobs:
620622
CC="/host/${{ env.SCCACHE_PATH }} cc"
621623
CXX="/host/${{ env.SCCACHE_PATH }} c++"
622624
SCCACHE_GHA_ENABLED=true
625+
SCCACHE_PREPROCESSOR_CACHE_GHA_ENABLED=true
623626
ACTIONS_RUNTIME_TOKEN=${{ env.ACTIONS_RUNTIME_TOKEN }}
624627
ACTIONS_RESULTS_URL=${{ env.ACTIONS_RESULTS_URL }}
625628
ACTIONS_CACHE_SERVICE_V2=${{ env.ACTIONS_CACHE_SERVICE_V2 }}

‎.github/workflows/pre-commit.yml‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ jobs:
5151
if: runner.os == 'Windows'
5252
run: git config --global core.symlinks true
5353

54+
# PR workflows run from the merge revision; check out that same revision
55+
# so their helper scripts and configuration stay in sync.
5456
- name: Checkout repository
5557
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
5658
with:
57-
ref: ${{ github.event.pull_request.head.sha || github.sha }}
5859
fetch-depth: 1
5960
persist-credentials: false
6061

@@ -85,6 +86,58 @@ jobs:
8586
- name: Install pre-commit
8687
run: python -m pip install --upgrade pip pre-commit
8788

89+
# Keep this offline hook smoke check before network-dependent Lychee steps,
90+
# so hook setup and invocation failures surface before link-check retries.
91+
# Invoke pre-commit directly to cover each shell's command lookup and quoting.
92+
# Each runner's shells reuse one offline configuration and hook environment.
93+
- name: Prepare offline Lychee configuration
94+
id: lychee-smoke
95+
# pre-commit needs the config on the checkout's drive; spaces exercise quoting.
96+
run: |
97+
directory="$(mktemp -d 'lychee offline smoke XXXXXX')"
98+
echo "directory=$directory" >> "${GITHUB_OUTPUT}"
99+
python ci/tools/smoke_test_lychee_precommit.py --prepare "$directory"
100+
101+
- name: Smoke-test Lychee in ${{ runner.os == 'Windows' && 'Git Bash' || 'Bash' }}
102+
if: ${{ !cancelled() && steps.lychee-smoke.outcome == 'success' }}
103+
shell: bash
104+
env:
105+
LYCHEE_SMOKE_DIR: ${{ steps.lychee-smoke.outputs.directory }}
106+
SKIP: ""
107+
PYTHONUTF8: "1"
108+
run: |
109+
status=0
110+
pre-commit run lychee --config "$LYCHEE_SMOKE_DIR/pre-commit.yaml" --files README.md --verbose > "$LYCHEE_SMOKE_DIR/bash.log" 2>&1 || status=$?
111+
python ci/tools/smoke_test_lychee_precommit.py --verify "$LYCHEE_SMOKE_DIR/bash.log" "$status"
112+
113+
- name: Smoke-test Lychee in PowerShell (Windows)
114+
if: ${{ !cancelled() && runner.os == 'Windows' && steps.lychee-smoke.outcome == 'success' }}
115+
shell: pwsh
116+
env:
117+
LYCHEE_SMOKE_DIR: ${{ steps.lychee-smoke.outputs.directory }}
118+
SKIP: ""
119+
PYTHONUTF8: "1"
120+
run: |
121+
pre-commit run lychee --config "$env:LYCHEE_SMOKE_DIR/pre-commit.yaml" --files README.md --verbose > "$env:LYCHEE_SMOKE_DIR/pwsh.log" 2>&1
122+
python ci/tools/smoke_test_lychee_precommit.py --verify "$env:LYCHEE_SMOKE_DIR/pwsh.log" $LASTEXITCODE
123+
124+
- name: Smoke-test Lychee in cmd (Windows)
125+
if: ${{ !cancelled() && runner.os == 'Windows' && steps.lychee-smoke.outcome == 'success' }}
126+
shell: cmd
127+
env:
128+
LYCHEE_SMOKE_DIR: ${{ steps.lychee-smoke.outputs.directory }}
129+
SKIP: ""
130+
PYTHONUTF8: "1"
131+
run: |
132+
pre-commit run lychee --config "%LYCHEE_SMOKE_DIR%\pre-commit.yaml" --files README.md --verbose > "%LYCHEE_SMOKE_DIR%\cmd.log" 2>&1
133+
python ci/tools/smoke_test_lychee_precommit.py --verify "%LYCHEE_SMOKE_DIR%\cmd.log" %ERRORLEVEL%
134+
135+
- name: Remove offline Lychee configuration
136+
if: ${{ always() && steps.lychee-smoke.outputs.directory != '' }}
137+
env:
138+
LYCHEE_SMOKE_DIR: ${{ steps.lychee-smoke.outputs.directory }}
139+
run: python ci/tools/smoke_test_lychee_precommit.py --cleanup "$LYCHEE_SMOKE_DIR"
140+
88141
- name: Run pre-commit
89142
run: pre-commit run --all-files --show-diff-on-failure
90143

‎.pre-commit-config.yaml‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,17 @@ repos:
112112
- Cython==3.2.9
113113

114114
# Link checking for authored documentation files
115-
- repo: https://github.com/lycheeverse/lychee
116-
rev: 2bba271688c1abb1503097a064e6c3bc1d1b6a9b # frozen: lychee-v0.24.2
115+
- repo: local
117116
hooks:
118117
- id: lychee
118+
name: lychee
119+
entry: python ./ci/tools/run_lychee.py
120+
language: python
121+
additional_dependencies:
122+
- lychee-bin==0.24.2 # Must match check-doc-links/action.yml
123+
types: [text]
124+
require_serial: true
119125
args:
120-
- LYCHEE_VERSION=0.24.2 # Must match the pinned rev above
121126
- --cache
122127
- --max-concurrency=4
123128
- --max-retries=3

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ Thank you for your interest in contributing to CUDA Python! Based on the type of
2626
- [Symptoms of a bad clone](#symptoms-of-a-bad-clone)
2727
- [Development on Windows](#development-on-windows)
2828
- [Enabling git symlinks](#enabling-git-symlinks)
29-
- [Pre-commit lychee workaround](#pre-commit-lychee-workaround)
3029
- [Type stubs for cuda.core](#type-stubs-for-cudacore)
3130
- [Pre-commit](#pre-commit)
3231
- [Pixi lockfiles](#pixi-lockfiles)
@@ -192,19 +191,6 @@ $ reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /v
192191

193192
Then return to [Recommended clone](#recommended-clone).
194193

195-
### Pre-commit lychee workaround
196-
197-
For development on Windows (not WSL), the `lychee` pre-commit task will not
198-
work when running `pre-commit run --all-files`. This problem does not occur
199-
if you install the pre-commit hook and run it automatically as part of your
200-
`git commit` workflow. To resolve this, you can either:
201-
202-
1. Run `pre-commit` in Git Bash, rather than directly in PowerShell or cmd
203-
204-
2. Skip it by setting the environment variable `SKIP` to `lychee`. This would
205-
be `$env:SKIP = "lychee"` in PowerShell or `set SKIP=lychee` in cmd.
206-
207-
208194
## Type stubs for cuda.core
209195

210196
`cuda.core` is a PEP 561-compliant package: it ships a `py.typed` marker and
@@ -237,6 +223,8 @@ To set yourself up for running pre-commit checks locally and to catch issues bef
237223
* Run this once per checkout: `pre-commit install`
238224
* You can manually check all files at any time by running: `pre-commit run --all-files`
239225

226+
On Windows, these commands work from PowerShell, cmd, or Git Bash.
227+
240228
This command runs all configured hooks (such as linters and formatters) across your repository, letting you review and address issues before committing.
241229

242230
Installing the hook is required, not optional. Some of the automated checks
@@ -256,8 +244,6 @@ hook environment, so no system-wide installation is required. Vendored code
256244
`.pre-commit-config.yaml`. To format in your editor, install the same version
257245
with `pip install clang-format==23.1.3`.
258246

259-
Windows contributors: see [Pre-commit lychee workaround](#pre-commit-lychee-workaround) under Development on Windows.
260-
261247
## Pixi lockfiles
262248

263249
The repository checks in a `pixi.lock` next to each `pixi.toml`. Those lockfiles

‎ci/test-matrix.yml‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ linux:
5757
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest' }
5858
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
5959
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
60+
- { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '12.9.1', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
6061
- { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
62+
- { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '12.9.1', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
6163
- { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
6264
# linux-aarch64
6365
- { ARCH: 'arm64', PY_VER: '3.11', CUDA_VER: '12.9.1', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
@@ -68,14 +70,18 @@ linux:
6870
- { ARCH: 'arm64', PY_VER: '3.12', CUDA_VER: '13.0.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
6971
- { ARCH: 'arm64', PY_VER: '3.12', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
7072
- { ARCH: 'arm64', PY_VER: '3.13', CUDA_VER: '12.9.1', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
71-
- { ARCH: 'arm64', PY_VER: '3.13', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest' }
73+
- { ARCH: 'arm64', PY_VER: '3.13', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest' }
7274
- { ARCH: 'arm64', PY_VER: '3.13', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
7375
- { ARCH: 'arm64', PY_VER: '3.14', CUDA_VER: '12.9.1', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
7476
- { ARCH: 'arm64', PY_VER: '3.14', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
75-
- { ARCH: 'arm64', PY_VER: '3.14', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest' }
77+
- { ARCH: 'arm64', PY_VER: '3.14', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest' }
7678
- { ARCH: 'arm64', PY_VER: '3.14t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
7779
- { ARCH: 'arm64', PY_VER: '3.14t', CUDA_VER: '13.0.2', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
7880
- { ARCH: 'arm64', PY_VER: '3.14t', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
81+
- { ARCH: 'arm64', PY_VER: '3.15', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
82+
- { ARCH: 'arm64', PY_VER: '3.15', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
83+
- { ARCH: 'arm64', PY_VER: '3.15t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
84+
- { ARCH: 'arm64', PY_VER: '3.15t', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
7985
# special runners
8086
- { ARCH: 'amd64', PY_VER: '3.13', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 'h100', GPU_COUNT: '1', DRIVER: 'latest' }
8187
- { ARCH: 'amd64', PY_VER: '3.13', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 'h100', GPU_COUNT: '1', DRIVER: 'latest' }
@@ -129,7 +135,10 @@ windows:
129135
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'TCC' }
130136
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.0.2', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
131137
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
132-
- { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
138+
- { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '12.9.1', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
139+
- { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
140+
- { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'v100', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'TCC' }
141+
- { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'rtx2080', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'WDDM' }
133142
# special runners
134143
- { ARCH: 'amd64', PY_VER: '3.14', CUDA_VER: '13.4.2', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '2', DRIVER: 'latest', DRIVER_MODE: 'TCC' }
135144
- { ARCH: 'amd64', PY_VER: '3.14', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'h100', GPU_COUNT: '2', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }

‎ci/tools/run_lychee.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""Run pre-commit's pinned native Lychee executable.
5+
6+
The upstream Lychee hook uses a shell launcher, which requires a compatible
7+
shell on Windows. We configure a Python hook so pre-commit installs the pinned
8+
lychee-bin wheel in an isolated environment. This wrapper runs that
9+
environment's native executable, passing through arguments and returning
10+
its exit status. The same hook works on Linux and in Windows shells such as
11+
PowerShell, cmd, and Git Bash.
12+
"""
13+
14+
from __future__ import annotations
15+
16+
import subprocess
17+
import sys
18+
import sysconfig
19+
from pathlib import Path
20+
21+
22+
def main(arguments: list[str] | None = None) -> int:
23+
# Resolve the executable from this hook's environment to honor the pin.
24+
executable = Path(sysconfig.get_path("scripts")) / ("lychee.exe" if sys.platform == "win32" else "lychee")
25+
if not executable.is_file():
26+
raise SystemExit(
27+
f"lychee was not found at {executable}; run this script through the configured pre-commit hook"
28+
)
29+
arguments = sys.argv[1:] if arguments is None else arguments
30+
return subprocess.run([str(executable), *arguments], check=False).returncode # noqa: S603
31+
32+
33+
if __name__ == "__main__":
34+
raise SystemExit(main())
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""Offline smoke check for the configured native Lychee hook.
5+
6+
Exercise the hook's environment, Python launcher, and native executable against
7+
the README's local links without making external link requests. As an accepted
8+
tradeoff for using a real document, a broken local README link also fails this
9+
check even when the hook itself works.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import argparse
15+
import shutil
16+
from pathlib import Path
17+
18+
import yaml
19+
from retry_lychee import read_report
20+
21+
ROOT = Path(__file__).resolve().parents[2]
22+
REPORT_NAME = "lychee.json"
23+
24+
25+
def write_config(directory: Path) -> None:
26+
# Use the checked-in hook, including its entry point and pinned dependency.
27+
# PyYAML is already installed as a dependency of pre-commit.
28+
config = yaml.safe_load((ROOT / ".pre-commit-config.yaml").read_text(encoding="utf-8"))
29+
[hook] = [hook for repo in config["repos"] for hook in repo["hooks"] if hook["id"] == "lychee"]
30+
report = directory / REPORT_NAME
31+
hook.setdefault("args", []).extend(["--offline", "--format", "json", "--output", str(report)])
32+
config_path = directory / "pre-commit.yaml"
33+
config_path.write_text(yaml.safe_dump(config), encoding="utf-8")
34+
35+
36+
def verify(log: Path, exit_code: int) -> int:
37+
report = log.with_name(REPORT_NAME)
38+
try:
39+
print(log.read_text(encoding="utf-8"), end="")
40+
if exit_code != 0:
41+
return exit_code
42+
if not report.is_file():
43+
raise SystemExit(f"The configured Lychee hook produced no report ({report}); was it skipped?")
44+
read_report(report, exit_code)
45+
return 0
46+
finally:
47+
# Consume each shell's report so a later skipped hook cannot reuse it.
48+
report.unlink(missing_ok=True)
49+
50+
51+
def main() -> int:
52+
# CI uses separate phases so each shell invokes pre-commit directly.
53+
parser = argparse.ArgumentParser(description=__doc__)
54+
mode = parser.add_mutually_exclusive_group(required=True)
55+
mode.add_argument("--prepare", type=Path, metavar="DIRECTORY")
56+
mode.add_argument("--verify", nargs=2, metavar=("LOG", "EXIT_CODE"))
57+
mode.add_argument("--cleanup", type=Path, metavar="DIRECTORY")
58+
args = parser.parse_args()
59+
if args.prepare is not None:
60+
write_config(ROOT / args.prepare)
61+
return 0
62+
if args.verify is not None:
63+
log, exit_code = args.verify
64+
return verify(ROOT / log, int(exit_code))
65+
directory = (ROOT / args.cleanup).resolve()
66+
if directory.parent != ROOT or not directory.name.startswith("lychee offline smoke "):
67+
raise SystemExit("Refusing to remove a directory outside the smoke check's temporary files")
68+
shutil.rmtree(directory)
69+
return 0
70+
71+
72+
if __name__ == "__main__":
73+
raise SystemExit(main())

0 commit comments

Comments
 (0)