]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[pre-commit] Add pre-commit setup check
authorTom de Vries <tdevries@suse.de>
Thu, 11 Dec 2025 21:38:30 +0000 (22:38 +0100)
committerTom de Vries <tdevries@suse.de>
Thu, 11 Dec 2025 21:38:30 +0000 (22:38 +0100)
I wrote a patch and accidentally introduced a typo in the commit message.

This didn't get detected because codespell-log didn't run.

I installed pre-commit on that setup a while back, before codespell-log was
around and consequently only the .git/hooks/pre-commit script was installed.

This is a bit hard to notice given that all other hooks do run.

Add a pre-commit check that checks for this situation:
...
$ rm .git/hooks/commit-msg
$ git commit --amend
  ...
pre-commit-setup........................................................Failed
- hook id: pre-commit-setup
- exit code: 1

missing hook: .git/hooks/commit-msg (please run pre-commit install)
  ...
$
...

This is a bit niche, but worthwhile if you're using a dozen build and test
installations.

.pre-commit-config.yaml
gdb/contrib/pre-commit-setup.py [new file with mode: 0755]
gdb/testsuite/gdb.src/pre-commit.exp

index 62af6f5d2f9fc22a469be1f0979414da611468fd..6757d872ce3fdbc04db20c2b6e17d17f55639b0e 100644 (file)
@@ -104,6 +104,12 @@ repos:
       files: '^(gdb(support|server)?)/.*$'
       pass_filenames: true
       stages: [pre-commit]
+    - id: pre-commit-setup
+      name: pre-commit-setup
+      language: script
+      entry: gdb/contrib/pre-commit-setup.py
+      always_run: true
+      require_serial: true
   - repo: https://github.com/nmoroze/tclint
     rev: v0.6.2
     hooks:
diff --git a/gdb/contrib/pre-commit-setup.py b/gdb/contrib/pre-commit-setup.py
new file mode 100755 (executable)
index 0000000..71f19bc
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+
+# 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 <http://www.gnu.org/licenses/>.
+
+# Occasionally we add new stages to default_install_hook_types in
+# .pre-commit-config.yaml.  The new stages are not used until somebody runs
+# pre-commit install again.  This script, meant to run as a pre-commit hook in
+# the pre-commit stage, detects this situation.
+
+import os
+import re
+import sys
+
+import yaml
+
+cfg = ".pre-commit-config.yaml"
+with open(cfg, "r") as f:
+    data = yaml.load(f, Loader=yaml.SafeLoader)
+stages = data.get("default_install_hook_types", ["pre-commit"])
+
+if os.path.isfile(".git"):
+    # Handle worktrees.
+    fp = open(".git")
+    text = fp.read()
+    m = re.search("gitdir: (.*)", text)
+    dir = os.path.join(m.group(1), "..", "..")
+else:
+    dir = ".git"
+
+if not os.path.isdir(dir):
+    # Not a git repository.
+    print("no .git dir found, skipping")
+    sys.exit(0)
+
+for val in stages:
+    f = os.path.join(dir, "hooks", val)
+
+    if not (os.path.isfile(f)):
+        if val == "pre-commit":
+            print("pre-commit framework hooks not installed, skipping")
+            sys.exit(0)
+        print("missing hook: " + val + " (please run pre-commit install)")
+        sys.exit(1)
+
+    fp = open(f)
+    text = fp.read()
+    m = re.search("File generated by pre-commit", text)
+    if not m:
+        print("not a pre-commit framework hook: " + f)
+        sys.exit(1)
index 8745b31272e9c49c5ca5c6e4765183f818e885fe..7c8cb6b363c231bae5bc3e5fcaec0cb7d4332e8c 100644 (file)
@@ -31,6 +31,10 @@ with_cwd $repodir {
        return
     }
 
+    # Skip the pre-commit-setup check.  It checks the repository setup, not
+    # the sources.
+    setenv SKIP pre-commit-setup
+
     set result [remote_exec build "pre-commit run --all-files -v"]
     set status [lindex $result 0]
     gdb_assert {$status == 0} "pre-commit checks"