[2/2,pre-commit] Add check-copies
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
Commit Message
Instead of using symlinks we maintain identical files, which is
error-prone [1].
Add pre-commit hook check-copies:
...
$ pre-commit run check-copies --all-files -v
check-copies............................................................Passed
- hook id: check-copies
- duration: 0.51s
...
that checks that:
- files that need to be copies are in fact copies, and
- no other files are copies.
I've excluded the testsuite from this check, to avoid having to handle:
...
Accidental copies found: [ \
'gdb/testsuite/config/arm-ice.exp', 'gdb/testsuite/config/bfin.exp', \
'gdb/testsuite/config/cygmon.exp', 'gdb/testsuite/config/h8300.exp', \
'gdb/testsuite/config/i386-bozo.exp']
Accidental copies found: [ \
'gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.c', \
'gdb/testsuite/gdb.base/run-after-attach.c']
Accidental copies found: [ \
'gdb/testsuite/gdb.rocm/addr-bp-gpu-no-deb-info.cpp', \
'gdb/testsuite/gdb.rocm/break-kernel-no-debug-info.cpp']
...
[1] https://sourceware.org/pipermail/gdb-patches/2026-September/229897.html
---
.pre-commit-config.yaml | 11 ++++++--
gdb/contrib/check-copies.py | 54 +++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 2 deletions(-)
create mode 100755 gdb/contrib/check-copies.py
@@ -123,14 +123,14 @@ repos:
entry: gdb/check-include-guards.py
# All gdb header files, but not headers in the test suite.
files: '^(gdb(support|server)?)/.*\.h$'
- exclude: '.*/testsuite/.*'
+ exclude: &testsuite_files '.*/testsuite/.*'
- id: &id1 check-gnu-style
name: *id1
language: python
additional_dependencies: ['termcolor', 'unidiff']
entry: gdb/contrib/check-gnu-style-pre-commit.sh
files: '^(gdb(support|server)?)/.*\.(c|h|cc)$'
- exclude: '.*/testsuite/.*'
+ exclude: *testsuite_files
verbose: true
- id: &id2 check-whitespace
name: *id2
@@ -173,6 +173,13 @@ repos:
args: [--config-check]
additional_dependencies: ["pyyaml"]
files: *pre_commit_config_file
+ - id: &id7 check-copies
+ name: *id7
+ language: unsupported_script
+ entry: gdb/contrib/check-copies.py
+ files: *gdb_files
+ exclude: *testsuite_files
+ require_serial: true
# Local Variables:
# indent-tabs-mode: nil
new file mode 100755
@@ -0,0 +1,54 @@
+#! /usr/bin/env python3
+
+import subprocess
+import sys
+from itertools import chain
+
+# These files are required to be identical.
+required_list = [
+ ["gdb/.dir-locals.el", "gdbserver/.dir-locals.el", "gdbsupport/.dir-locals.el"],
+ ["gdb/.shellcheckrc", "gdbserver/.shellcheckrc", "gdbsupport/.shellcheckrc"],
+]
+
+
+def run_cmd(cmd, **kwargs):
+ res = subprocess.run(cmd, **kwargs)
+ if res.returncode != 0:
+ raise RuntimeError(
+ "command %s failed with exit status %s" % (cmd, res.returncode)
+ )
+ return res
+
+
+files = sys.argv[1:]
+always_check_files = list(chain.from_iterable(required_list))
+cmd = ["git", "ls-files", "--stage"] + files + always_check_files
+res = run_cmd(cmd, capture_output=True, text=True)
+
+hash_dict = {}
+for line in res.stdout.splitlines():
+ parts = line.split(maxsplit=3)
+ hash = parts[1]
+ file = parts[3]
+ hash_dict.setdefault(hash, []).append(file)
+
+copies = []
+for hash in hash_dict:
+ files = hash_dict[hash]
+ if len(files) == 1:
+ continue
+ copies.append(set(files))
+
+required_set = [set(r) for r in required_list]
+
+for required in required_set:
+ if required in copies:
+ continue
+ print("No longer copies: %s" % required)
+ sys.exit(1)
+
+for copy in copies:
+ if copy in required_set:
+ continue
+ print("Accidental copies found: %s" % copy)
+ sys.exit(1)