From fca7aeb089f42ce7fd2bc57c48baabc59688f082 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 2 Jul 2026 10:52:31 -0400 Subject: [PATCH] Chore: Make installing the pre-commit hook "required" --- .pre-commit-config.yaml | 10 ++++- CONTRIBUTING.md | 19 ++++---- toolshed/check_precommit_installed.py | 62 +++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 toolshed/check_precommit_installed.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8d2a2731ed..1ac6754ae10 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ ci: autoupdate_branch: '' autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' autoupdate_schedule: quarterly - skip: [lychee] + skip: [lychee, check-precommit-installed] submodules: false # Please update the rev: SHAs below with this command: @@ -26,6 +26,14 @@ repos: - repo: local hooks: + - id: check-precommit-installed + name: Warn if the pre-commit git hook is not installed + entry: python ./toolshed/check_precommit_installed.py + language: python + always_run: true + pass_filenames: false + verbose: true + - id: check-spdx name: Check SPDX Headers entry: python ./toolshed/check_spdx.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 899dc5f0f74..012126cc842 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,21 +61,18 @@ This project uses [pre-commit.ci](https://pre-commit.ci/) with GitHub Actions. A To set yourself up for running pre-commit checks locally and to catch issues before pushing your changes, follow these steps: * Install pre-commit with: `pip install pre-commit` +* Run this once per checkout: `pre-commit install` * You can manually check all files at any time by running: `pre-commit run --all-files` This command runs all configured hooks (such as linters and formatters) across your repository, letting you review and address issues before committing. -**Optional: Enable automatic checks on every commit** -If you want pre-commit hooks to run automatically each time you make a commit, install the git hook with: - -`pre-commit install` - -This sets up a git pre-commit hook so that all configured checks will run before each commit is accepted. If any hook fails, the commit will be blocked until the issues are resolved. - -**Note on workflow flexibility** -Some contributors prefer to commit intermediate or work-in-progress changes that may not pass all pre-commit checks, and only clean up their commits before pushing (for example, by squashing and running `pre-commit run --all-files` manually at the end). If this fits your workflow, you may choose not to run `pre-commit install` and instead rely on manual checks. This approach avoids disruption during iterative development, while still ensuring code quality before code is shared or merged. - -Choose the setup that best fits your workflow and development style. +Installing the hook is required, not optional. Some of the automated checks +(the SPDX header updater and the `.pyi` stub generator for `cuda_core`) only +keep the tree consistent if they run on *every* commit. Relying on manual +`pre-commit run --all-files` invocations means these checks can be skipped +between commits, leaving stale headers or out-of-date stubs in the history. +If the hook isn't installed, `pre-commit run` (and CI) will print a visible +warning reminding you to run `pre-commit install`. ## Signing Your Work diff --git a/toolshed/check_precommit_installed.py b/toolshed/check_precommit_installed.py new file mode 100644 index 00000000000..19d7cfc20b6 --- /dev/null +++ b/toolshed/check_precommit_installed.py @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Warn (without failing) if the pre-commit git hook is not installed. + +This repo relies on pre-commit running on *every* commit: the SPDX header +updater and the .pyi stub generator only keep the tree consistent if they +run automatically via the installed git hook. Contributors who only run +`pre-commit run --all-files` manually (or never run pre-commit at all) can +end up with stale headers or stubs. This check can't block the commit +(if pre-commit isn't installed as a git hook, this script never runs +during `git commit` in the first place) but it does fire during manual +`pre-commit run` invocations and in CI, where it gives contributors a +visible nudge to run `pre-commit install`. +""" + +import subprocess +import sys + +MARKER = b"File generated by pre-commit" + + +def _git_hooks_dir() -> str: + result = subprocess.run( + ["git", "rev-parse", "--git-path", "hooks"], # noqa: S607 + capture_output=True, + check=True, + text=True, + ) + return result.stdout.strip() + + +def main() -> int: + hooks_dir = _git_hooks_dir() + hook_path = f"{hooks_dir}/pre-commit" + + try: + with open(hook_path, "rb") as f: + installed = MARKER in f.read() + except FileNotFoundError: + installed = False + + if not installed: + print( + "\n" + "==================== pre-commit WARNING ====================\n" + "The pre-commit git hook is not installed in this checkout.\n" + "Without it, checks only run when you invoke pre-commit\n" + "manually, and will NOT run automatically on `git commit`.\n" + "\n" + "Fix this by running:\n" + "\n" + " pre-commit install\n" + "==============================================================\n", + file=sys.stderr, + ) + + return 0 + + +if __name__ == "__main__": + sys.exit(main())