From 97b0846746f6fcf9bfb31b1480e3a208598efa7e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 12 Apr 2026 05:09:22 +0100 Subject: [PATCH] fix(tooling): add fast mode to committer helper --- scripts/committer | 33 +++++++++++++++----- test/scripts/committer.test.ts | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/scripts/committer b/scripts/committer index 28589b1900d..1fa16ea3c53 100755 --- a/scripts/committer +++ b/scripts/committer @@ -4,7 +4,7 @@ set -euo pipefail # Disable glob expansion to handle brackets in file paths set -f usage() { - printf 'Usage: %s [--force] "commit message" "file" ["file" ...]\n' "$(basename "$0")" >&2 + printf 'Usage: %s [--force] [--fast] "commit message" "file" ["file" ...]\n' "$(basename "$0")" >&2 exit 2 } @@ -13,10 +13,22 @@ if [ "$#" -lt 2 ]; then fi force_delete_lock=false -if [ "${1:-}" = "--force" ]; then - force_delete_lock=true - shift -fi +fast_commit=false +while [[ "${1:-}" == --* ]]; do + case "${1:-}" in + --force) + force_delete_lock=true + shift + ;; + --fast) + fast_commit=true + shift + ;; + *) + usage + ;; + esac +done if [ "$#" -lt 2 ]; then usage @@ -190,8 +202,15 @@ if git diff --staged --quiet; then fi committed=false -if run_git_with_lock_retry "commit" git commit -m "$commit_message" -- "${files[@]}"; then - committed=true +if [ "$fast_commit" = true ]; then + declare -a commit_env=(FAST_COMMIT=1) + if run_git_with_lock_retry "commit" env "${commit_env[@]}" git commit -m "$commit_message" -- "${files[@]}"; then + committed=true + fi +else + if run_git_with_lock_retry "commit" git commit -m "$commit_message" -- "${files[@]}"; then + committed=true + fi fi if [ "$committed" = false ]; then diff --git a/test/scripts/committer.test.ts b/test/scripts/committer.test.ts index e3b25ea362d..3b0dee53a43 100644 --- a/test/scripts/committer.test.ts +++ b/test/scripts/committer.test.ts @@ -37,10 +37,24 @@ function writeRepoFile(repo: string, relativePath: string, contents: string) { writeFileSync(fullPath, contents); } +function installHook(repo: string, relativePath: string, contents: string) { + const fullPath = path.join(repo, relativePath); + mkdirSync(path.dirname(fullPath), { recursive: true }); + writeFileSync(fullPath, contents, { + encoding: "utf8", + mode: 0o755, + }); + git(repo, "config", "core.hooksPath", path.dirname(relativePath)); +} + function commitWithHelper(repo: string, commitMessage: string, ...args: string[]) { return run(repo, "bash", [scriptPath, commitMessage, ...args]); } +function commitWithHelperArgs(repo: string, ...args: string[]) { + return run(repo, "bash", [scriptPath, ...args]); +} + function committedPaths(repo: string) { const output = git(repo, "diff-tree", "--no-commit-id", "--name-only", "-r", "HEAD"); return output.split("\n").filter(Boolean).toSorted(); @@ -105,4 +119,45 @@ describe("scripts/committer", () => { expect(committedPaths(repo)).toEqual(["CHANGELOG.md"]); expect(git(repo, "status", "--short")).toContain("M unrelated.ts"); }); + + it("supports --fast before the commit message", () => { + const repo = createRepo(); + writeRepoFile(repo, "note.txt", "hello\n"); + + const output = commitWithHelperArgs(repo, "--fast", "test: fast helper", "note.txt"); + + expect(output).toContain('Committed "test: fast helper" with 1 files'); + expect(committedPaths(repo)).toEqual(["note.txt"]); + }); + + it("supports combining --force and --fast", () => { + const repo = createRepo(); + writeRepoFile(repo, "note.txt", "hello\n"); + + const output = commitWithHelperArgs( + repo, + "--force", + "--fast", + "test: fast forced helper", + "note.txt", + ); + + expect(output).toContain('Committed "test: fast forced helper" with 1 files'); + expect(committedPaths(repo)).toEqual(["note.txt"]); + }); + + it("passes FAST_COMMIT through to git hooks when using --fast", () => { + const repo = createRepo(); + installHook( + repo, + ".githooks/pre-commit", + '#!/usr/bin/env bash\nset -euo pipefail\n[ "${FAST_COMMIT:-}" = "1" ] || exit 91\n', + ); + writeRepoFile(repo, "note.txt", "hello\n"); + + const output = commitWithHelperArgs(repo, "--fast", "test: fast hook env", "note.txt"); + + expect(output).toContain('Committed "test: fast hook env" with 1 files'); + expect(committedPaths(repo)).toEqual(["note.txt"]); + }); });