From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [RFC 1/3] [pre-commit] Add shfmt
Date: Wed, 2 Sep 2026 15:17:37 +0200 [thread overview]
Message-ID: <20260902131739.2125928-2-tdevries@suse.de> (raw)
In-Reply-To: <20260902131739.2125928-1-tdevries@suse.de>
Add a new pre-commit hook shfmt, disabled.
A few notable changes in formatting compared to 'emacs' style are:
...
$ cat test.sh.bak
case "$1" in
foo \
| bar )
:
;;
esac
var=$(foo \
bar)
$ cp test.sh.bak test.sh; ./gdb/contrib/shfmt.sh test.sh
$ diff -u test.sh.bak test.sh
@@ -1,11 +1,11 @@
case "$1" in
- foo \
- | bar )
+ foo | \
+ bar)
:
;;
esac
var=$(foo \
- bar)
+ bar)
...
The hook uses https://github.com/scop/pre-commit-shfmt.git, which provides a
.pre-commit-hooks.yaml file. The file presents three alternatives:
- shfmt (prebuilt upstream executable)
- shfmt-src (build from source)
- shfmt-docker (Docker image)
I've chosen the shfmt-src one. It relies on dependency
mvdan.cc/sh/v3/cmd/shfmt@v3.13.1, which points to go package
https://pkg.go.dev/mvdan.cc/sh/v3/cmd/shfmt, which uses repository
https://github.com/mvdan/sh.
---
.pre-commit-config.yaml | 12 ++++++
gdb/contrib/pre-commit.py | 6 ++-
gdb/contrib/shfmt.sh | 83 +++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 1 deletion(-)
create mode 100755 gdb/contrib/shfmt.sh
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0b4285e6c82..2d2b5e38ca1 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -114,6 +114,18 @@ repos:
# Enable strict mode to make sure we see and fix warnings.
args: [--strict]
+ # Shell script hooks.
+ - repo: https://github.com/scop/pre-commit-shfmt.git
+ rev: v3.13.1-1
+ hooks:
+ - id: shfmt-src
+ alias: shfmt
+ entry: gdb/contrib/shfmt.sh
+ files: *gdb_files
+ args: []
+ # Disabled.
+ stages: [manual]
+
# Local hooks.
- repo: local
hooks:
diff --git a/gdb/contrib/pre-commit.py b/gdb/contrib/pre-commit.py
index f3ad6f803b0..66b8667a2f2 100755
--- a/gdb/contrib/pre-commit.py
+++ b/gdb/contrib/pre-commit.py
@@ -49,7 +49,11 @@ def config_check_repo(repo):
# Check version number. Don't allow pre-releases like 9.0.0b1.
# We currently only need to support x.y.z, but that could change.
- if not re.fullmatch(r"\d+[.]\d+[.]\d+", rev):
+ re_rev = r"\d+[.]\d+[.]\d+"
+ if name == "https://github.com/scop/pre-commit-shfmt.git":
+ re_rev += r"-\d+"
+
+ if not re.fullmatch(re_rev, rev):
print("Revision %s for repo %s not allowed." % (rev, name))
return False
diff --git a/gdb/contrib/shfmt.sh b/gdb/contrib/shfmt.sh
new file mode 100755
index 00000000000..9cdf863b4d1
--- /dev/null
+++ b/gdb/contrib/shfmt.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+f2=()
+f4=()
+
+for f in "$@"; do
+ # The gdb/config/djgpp/* pattern matches the explicitly mentioned
+ # djcheck.sh and djconfig.sh. Allow this.
+ # shellcheck disable=SC2221,SC2222
+ case "$f" in
+ */configure)
+ # Generated.
+ continue
+ ;;
+ gdb/config/djgpp/*)
+ # For now, these scripts prefer `...` over $(...). See
+ # gdb/config/djgpp/.shellcheckrc.
+ # Shfmt automatically rewrites to $(...), so skip these.
+ continue
+ ;;
+ gdb/config/djgpp/djcheck.sh)
+ # Mixed 2/4 indentation.
+ continue
+ ;;
+ gdb/config/djgpp/djconfig.sh \
+ | gdb/contrib/expect-read1.sh \
+ | gdb/features/feature_to_c.sh \
+ | gdb/gdb_buildall.sh )
+ f2=("${f2[@]}" "$f")
+ ;;
+ *)
+ f4=("${f4[@]}" "$f")
+ ;;
+ esac
+done
+
+with_indent()
+{
+ indent="$1"
+ shift
+
+ if [ $# -eq 0 ]; then
+ return
+ fi
+
+ shfmt \
+ --language-dialect=auto \
+ --indent="$indent" \
+ --func-next-line \
+ --space-redirects \
+ --case-indent \
+ --binary-next-line \
+ --write \
+ "$@"
+}
+
+with_indent 2 "${f2[@]}"
+with_indent 4 "${f4[@]}"
+
+tmp=""
+
+cleanup()
+{
+ if [ "$tmp" != "" ]; then
+ rm -f "$tmp"
+ fi
+}
+
+# Schedule cleanup.
+trap cleanup EXIT
+
+tmp=$(mktemp)
+
+for f in "${f2[@]}" "${f4[@]}"; do
+ unexpand \
+ --first-only \
+ --tabs=8 \
+ "$f" \
+ > "$tmp"
+
+ # Use cat to preserve permissions on $f.
+ cat "$tmp" > "$f"
+done
--
2.51.0
next prev parent reply other threads:[~2026-09-02 13:18 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 13:17 [RFC 0/3] " Tom de Vries
2026-09-02 13:17 ` Tom de Vries [this message]
2026-09-02 13:17 ` [RFC 2/3] [pre-commit] Enable shfmt Tom de Vries
2026-09-02 13:17 ` [RFC 3/3] [gdb/contrib] Use shfmt --simplify in shfmt.sh Tom de Vries
2026-09-15 7:26 ` Tom de Vries
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260902131739.2125928-2-tdevries@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox