feat: add {{ hook_args }} template to pass to downstream commands#807
feat: add {{ hook_args }} template to pass to downstream commands#807
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the ability to pass hook arguments to various git hooks by capturing the HK_HOOK_ARGS environment variable and inserting it into the hook execution context. The changes are applied across multiple command files, and a new test suite has been added to verify the functionality. I agree with the reviewer's feedback that the logic for retrieving and inserting hook_args is currently duplicated across several files and should be refactored into a shared helper method or integrated into the HookOptions struct to improve maintainability.
Greptile SummaryThis PR adds a Confidence Score: 5/5Safe to merge — the previous P1 concerns (broken commit-msg/pre-push positional args, All dedicated hook handlers correctly parse positional args via clap and reconstruct hook_args manually. The install script retains "$@" so commit-msg, prepare-commit-msg, and pre-push continue to receive their required positional arguments. The single remaining finding is a cosmetic trailing-space edge case in pre_push.rs that only affects manual invocations, not real git-driven hook executions. src/cli/run/pre_push.rs — minor trailing-space formatting in hook_args when url is absent Important Files Changed
Sequence DiagramsequenceDiagram
participant Git
participant HookScript as "Hook Script"
participant HK as "hk run hook"
participant Handler as "Dedicated Handler"
participant Tera as "Tera Template"
participant Step as "Step Command"
Git->>HookScript: "invoke with positional args"
HookScript->>HK: "exec hk run hook $@"
HK->>Handler: "clap parses positional args"
Handler->>Handler: "construct hook_args from parsed fields"
Handler->>Tera: "tctx.insert(hook_args)"
Handler->>Step: "run step with rendered template"
Tera->>Step: "replace {{ hook_args }} in command"
Step->>Git: "e.g. git lfs post-checkout prev new flag"
Reviews (7): Last reviewed commit: "feat: {{ hook_args }} for prepare-commit..." | Re-trigger Greptile |
5d04373 to
d30c397
Compare
|
Tip: Greploop — Automatically fix all review issues by running Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal. |
9684900 to
31f846e
Compare
| if [ "$HK_LIBGIT2" = "0" ]; then | ||
| skip "libgit2 is not installed" | ||
| fi |
There was a problem hiding this comment.
ℹ️ This follows the same pattern as:
Lines 20 to 22 in 54d2112
| format!( | ||
| r#"#!/bin/sh | ||
| test "${{HK:-1}}" = "0" || exec {hk} run {hook} "$@" | ||
| test "${{HK:-1}}" = "0" || HK_HOOK_ARGS="$*" exec {hk} run {hook} "$@" |
There was a problem hiding this comment.
this isn't going to deal with spaces in args properly
There was a problem hiding this comment.
Thanks for the review! Understood. I reworked the PR to use dedicated clap handlers per hook instead of the HK_HOOK_ARGS env var, in order to match the existing PrepareCommitMsg pattern. What do you think?
31f846e to
d025efe
Compare
8399dd5 to
448ae3f
Compare
### 🚀 Features
- add {{ hook_args }} template to pass to downstream commands by
[@JohanLorenzo](https://github.com/JohanLorenzo) in
[#807](#807)
### 🐛 Bug Fixes
- **(step)** preserve cmd.exe quoting for {{files}} on Windows by
[@jdx](https://github.com/jdx) in
[#824](#824)
### 🛡️ Security
- **(deps)** update dependency eslint to v10 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#813](#813)
### 📦️ Dependency Updates
- update taiki-e/upload-rust-binary-action digest to 10c1cf6 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#810](#810)
- update nick-fields/retry action to v4 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#812](#812)
- update anthropics/claude-code-action digest to 657fb7c by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#809](#809)
- update dependency typescript to v6 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#814](#814)
- update rust crate demand to v2 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#815](#815)
- update rust crate expr-lang to v1 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#816](#816)
- update rust crate similar to v3 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#817](#817)
- update rust crate toml to v1 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#820](#820)
- update actions/upload-artifact digest to 043fb46 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#821](#821)
- update anthropics/claude-code-action digest to b47fd72 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#822](#822)
### New Contributors
- @JohanLorenzo made their first contribution in
[#807](#807)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk release bookkeeping: version bumps, regenerated CLI/docs, and
routine dependency lockfile updates with no functional code changes in
this PR.
>
> **Overview**
> Bumps `hk` to **v1.42.0** and adds the corresponding `CHANGELOG.md`
release notes.
>
> Regenerates versioned docs/CLI artifacts (`docs/cli/*`,
`hk.usage.kdl`) and updates all documentation/examples to reference the
`v1.42.0` Pkl package URLs. Updates `Cargo.lock` for minor dependency
revisions.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4b9834f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Co-authored-by: mise-en-dev <123107610+mise-en-dev@users.noreply.github.com>
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [hk](https://github.com/jdx/hk) | minor | `1.41.1` → `1.42.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>jdx/hk (hk)</summary> ### [`v1.42.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1420---2026-04-12) [Compare Source](jdx/hk@v1.41.1...v1.42.0) ##### 🚀 Features - add {{ hook\_args }} template to pass to downstream commands by [@​JohanLorenzo](https://github.com/JohanLorenzo) in [#​807](jdx/hk#807) ##### 🐛 Bug Fixes - **(step)** preserve cmd.exe quoting for {{files}} on Windows by [@​jdx](https://github.com/jdx) in [#​824](jdx/hk#824) ##### 🛡️ Security - **(deps)** update dependency eslint to v10 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​813](jdx/hk#813) ##### 📦️ Dependency Updates - update taiki-e/upload-rust-binary-action digest to [`10c1cf6`](jdx/hk@10c1cf6) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​810](jdx/hk#810) - update nick-fields/retry action to v4 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​812](jdx/hk#812) - update anthropics/claude-code-action digest to [`657fb7c`](jdx/hk@657fb7c) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​809](jdx/hk#809) - update dependency typescript to v6 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​814](jdx/hk#814) - update rust crate demand to v2 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​815](jdx/hk#815) - update rust crate expr-lang to v1 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​816](jdx/hk#816) - update rust crate similar to v3 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​817](jdx/hk#817) - update rust crate toml to v1 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​820](jdx/hk#820) - update actions/upload-artifact digest to [`043fb46`](jdx/hk@043fb46) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​821](jdx/hk#821) - update anthropics/claude-code-action digest to [`b47fd72`](jdx/hk@b47fd72) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​822](jdx/hk#822) ##### New Contributors - [@​JohanLorenzo](https://github.com/JohanLorenzo) made their first contribution in [#​807](jdx/hk#807) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMTMiLCJ1cGRhdGVkSW5WZXIiOiI0My4xMTAuMTMiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbIlJlbm92YXRlIEJvdCIsImF1dG9tYXRpb246Ym90LWF1dGhvcmVkIiwiZGVwZW5kZW5jeS10eXBlOjptaW5vciJdfQ==-->
Hey again! Thank you very much for merging and releasing #807! It's been working great with almost all `git lfs` hooks. There's one I missed in my original PR: `pre-push`. While `{{ hook_args }}` solved positional argument forwarding, `git lfs pre-push` also needs **stdin**. `git` pipes ref data through it so LFS knows which objects to upload. Currently, hk's `PrePush` handler consumes stdin for its own ref resolution, leaving nothing for step commands. This PR preserves the raw stdin as `{{ hook_stdin }}` so steps can pipe it via the existing `stdin` field. ## The problem `git lfs pre-push` receives ref data via stdin: refs/heads/main refs/heads/main Without it, `git lfs pre-push` exits 0 silently and uploads nothing. The remote then rejects the push: ``` $ git push origin main files - Fetching git status ✔ files - Fetching files between refs/remotes/origin/main and HEAD (1 file) ❯ git-lfs git-lfs – 0 files – – git lfs pre-push origin URL ✔ git-lfs remote: LFS objects are missing. Ensure LFS is properly set up or try a manual "git lfs push --all". ! [remote rejected] main -> main (pre-receive hook declined) ``` ## After the fix ``` $ git push origin main files - Fetching git status ✔ files - Fetching files between refs/remotes/origin/main and HEAD (1 file) ❯ git-lfs git-lfs – 0 files – – git lfs pre-push origin URL git-lfs – Uploading LFS objects: 100% (1/1), 0 B | 0 B/s, done. ✔ git-lfs To URL cdd0595..21798fe main -> main ``` ## Steps to reproduce locally ``` mkdir /tmp/hk-lfs-test && cd /tmp/hk-lfs-test git init && git lfs install echo "*.bin filter=lfs diff=lfs merge=lfs -text" > .gitattributes cat > hk.pkl << 'EOF' amends "package://github.com/jdx/hk/releases/download/v1.42.0/hk@1.42.0#/Config.pkl" hooks { ["pre-push"] { steps { ["git-lfs"] { check = "git lfs pre-push {{ hook_args }}" stdin = "{{ hook_stdin }}" } } } } EOF dd if=/dev/urandom bs=1024 count=5 of=big.bin 2>/dev/null git add .gitattributes hk.pkl big.bin && git commit -m "init" git init --bare ../hk-lfs-remote.git git remote add origin ../hk-lfs-remote.git HK=0 git push -u origin main # initial push without hk git remote set-head origin main hk install dd if=/dev/urandom bs=1024 count=5 of=big2.bin 2>/dev/null git add big2.bin && git commit -m "second" git push origin main # should show "Uploading LFS objects" ``` ## Usage ```pkl hooks { ["pre-push"] { steps { ["git-lfs"] { check = "git lfs pre-push {{ hook_args }}" stdin = "{{ hook_stdin }}" } } } } ```
Hi there! 👋
Thank you so much for quickly accepting and releasing jdx/mise#8961. I truly appreciate it and I got to use it already 🙂
I'm converting a personal project from pre-commit to hk and I stumbled upon an issue with
git lfs. git-lfs hooks (post-checkout,post-merge,pre-push) need the arguments that git passes to the hook script. Without this PR,git lfs post-checkoutfails with "This should be run through Git's post-checkout hook."Summary
{{ hook_args }}template variable that forwards git hook arguments to step commands$*viaHK_HOOK_ARGSenv var instead of positional argsHK_HOOK_ARGSand insert it into the template contextWith this change, users can configure git-lfs integration in
hk.pkl:Let me know what you think!