From: Tom de Vries Date: Fri, 25 Apr 2025 17:22:36 +0000 (+0200) Subject: [pre-commit] Add codespell-log commit-msg hook X-Git-Tag: binutils-2_45~776 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=129228c8b01a8fe0345e33fe07d185047721bd68;p=thirdparty%2Fbinutils-gdb.git [pre-commit] Add codespell-log commit-msg hook Now that we're using codespell to check spelling in gdb files, can we use codespell to bring this spelling warning: ... $ echo usuable | codespell - 1: usuable usuable ==> usable ... to: ... $ git commit -a -m "Usuable stuff" ... ? First, let's look at a straightforward commit-msg hook implementation: ... - id: codespell name: codespell-commit-msg verbose: true always_run: true stages: [commit-msg] ... installed using: ... $ pre-commit install -t commit-msg ... When trying the commit, we get: ... $ echo "/* bla */" >> gdb/gdb.c $ git commit -a -m "Usuable stuff" black................................................(no files to check)Skipped flake8...............................................(no files to check)Skipped isort................................................(no files to check)Skipped codespell............................................(no files to check)Skipped check-include-guards.................................(no files to check)Skipped black................................................(no files to check)Skipped flake8...............................................(no files to check)Skipped codespell............................................(no files to check)Skipped codespell-commit-msg.....................................................Failed - hook id: codespell - duration: 0.06s - exit code: 65 .git/COMMIT_EDITMSG:1: Usuable ==> Usable check-include-guards.................................(no files to check)Skipped $ ... The commit was aborted, but the commit message is still there: ... $ cat .git/COMMIT_EDITMSG Usuable stuff ... We can retry and edit the commit message to clean up the typo: ... $ git commit -e -F .git/COMMIT_EDITMSG -a ... but it's a bit cumbersome. Furthermore, say we fix a typo and want to document this in the commit log, and do: ... $ git commit -m "Fixed typo: useable -> usable" -a ... This commit cannot succeed, unless we add a codespell ignore tag, which feels like taking it too far. Both these problems can be addressed by setting things up in such a way that the commit always succeeds, and codespell output is shown as a hint. Ideally, we'd tell to pre-commit to implement this using some setting, but there doesn't seem to be one. So we use some indirection. Instead of using native codespell, use a local hook that calls a script gdb/contrib/codespell-log.sh, which calls pre-commit, which calls codespell. Using this approach, we get: ... $ echo "/* bla */" >> gdb/gdb.c $ git commit -a -m "Usuable stuff" black................................................(no files to check)Skipped flake8...............................................(no files to check)Skipped isort................................................(no files to check)Skipped codespell............................................(no files to check)Skipped check-include-guards.................................(no files to check)Skipped black................................................(no files to check)Skipped flake8...............................................(no files to check)Skipped codespell............................................(no files to check)Skipped check-include-guards.................................(no files to check)Skipped codespell-log............................................................Passed - hook id: codespell-log - duration: 0.18s codespell-log-internal...................................................Failed - hook id: codespell - exit code: 65 .git/COMMIT_EDITMSG:1: Usuable ==> Usable [codespell/codespell-log-2 d081bd25a40] Usuable stuff 1 file changed, 1 insertion(+) $ ... This is obviously convoluted, but it works. Perhaps we can propose a pre-commit improvement (always_pass) and simplify this eventually. Checked new script codespell-log.sh with shell-check. Approved-By: Simon Marchi --- diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b55685b5f70..7cb7008f2df 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,6 +38,7 @@ # See https://pre-commit.com/hooks.html for more hooks minimum_pre_commit_version: 3.2.0 +default_install_hook_types: [pre-commit, commit-msg] repos: - repo: https://github.com/psf/black-pre-commit-mirror rev: 25.1.0 @@ -80,3 +81,10 @@ repos: # All gdb header files, but not headers in the test suite. files: '^(gdb(support|server)?)/.*\.h$' exclude: '.*/testsuite/.*' + - id: codespell-log + name: codespell-log + language: script + entry: gdb/contrib/codespell-log.sh + verbose: true + always_run: true + stages: [commit-msg] diff --git a/gdb/contrib/codespell-log.sh b/gdb/contrib/codespell-log.sh new file mode 100755 index 00000000000..10780f86c5f --- /dev/null +++ b/gdb/contrib/codespell-log.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash + +# Copyright (C) 2025 Free Software Foundation, Inc. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Script to be used as pre-commit commit-msg hook to spell-check the commit +# log using codespell. +# +# Using codespell directly as a pre-commit commit-msg hook has the drawback +# that: +# - if codespell fails, the commit fails +# - if the commit log mentions a typo correction, it'll require a +# codespell:ignore annotation. +# +# This script works around these problems by treating codespell output as a +# hint, and ignoring codespell exit status. +# +# Implementation note: rather than using codespell directly, this script uses +# pre-commit to call codespell, because it allows us to control the codespell +# version that is used. + +# Exit on error. +set -e + +# Initialize temporary file names. +cfg="" +output="" + +cleanup() +{ + for f in "$cfg" "$output"; do + if [ "$f" != "" ]; then + rm -f "$f" + fi + done +} + +# Schedule cleanup. +trap cleanup EXIT + +# Create temporary files. +cfg=$(mktemp) +output=$(mktemp) + +gen_cfg () +{ + cat > "$1" < "$output" \ + 2>&1; then + # Command succeeded quietly, we're done. + exit 0 +fi + +# Command failed quietly, now show the output. +# +# Simply doing "cat $output" doesn't produce colored output, so we just +# run the command again, that should be fast enough. +# +# Ignore codespell exit status. +"${cmd[@]}" || true