fix(hook): remove dup output and preserve check_first diagnostics#784
fix(hook): remove dup output and preserve check_first diagnostics#784
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors script failure handling to ensure consistent output and preserve diagnostics during early exits. It removes the redundant handle_script_failed function, updates write_output_file to handle its own errors, and introduces logic in the execution step to save check outputs if a hook is cancelled by fail_fast. New tests verify that error messages are not duplicated in the summary. Feedback was provided to harden write_output_file against potential panics when resolving parent directories and to optimize string allocations when stripping ANSI codes.
Greptile SummaryThis PR fixes two output correctness issues: it removes the Confidence Score: 5/5Safe to merge — all prior review concerns are resolved and no new issues found. All P0/P1 concerns from the previous review round (combined interleaved output, silent error demotion, redundant CLI flag) are fixed. The let-chain syntax used in execution.rs is valid since the project pins rust-version = 1.88.0. No new defects introduced. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Step with check_first] --> B[Run check / check_list_files]
B -->|Ok| C[Return early — nothing to fix]
B -->|CheckListFailed| D[Stash check_first_output\nstdout + stderr + combined]
D --> E{fail_fast cancelled?}
E -->|Yes| F[save_output_summary\nwith check diagnostics\nis_failure = true]
E -->|No| G[Run fixer / second pass]
G -->|Ok| H[save_output_summary\nsecond-run output]
G -->|Err| I[status_errored\nreturn Err]
J[friendly_error] --> K{ScriptFailed\nin chain?}
K -->|Yes| L[write_output_file\nprocess::exit]
K -->|No| M[Return Err —\nfull eyre trace]
Reviews (3): Last reviewed commit: "Merge branch 'main' into fix/friendly-er..." | Re-trigger Greptile |
4522b34 to
29094f5
Compare
…heck_first output Three fixes for step output display: 1. Remove handle_script_failed output dump from friendly_error. The per-step output_by_step summary already shows all failing steps' output. friendly_error was duplicating the first failing step's output after the summary, causing misattribution (e.g., ghalint output appearing to be part of zizmor's section). 2. Preserve check_first diagnostic output when cancelled by fail_fast. For check_diff/check_list_files steps with check_first, the check output was lost if another step failed first (triggering fail_fast cancellation before the second run). Now the check output is stashed and saved to the summary if the second run is skipped. 3. Add regression tests for output display bugs. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
2391a9d to
c428282
Compare
PR #772 forced Combined output on failure to avoid losing diagnostics, but this changed the summary header label (e.g., "lint output:" instead of "lint stderr:"), breaking #784's tests. Use combined content on failure but keep the configured label. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
## Summary - PR #772 forced `Combined` output on failure to avoid losing diagnostics, but this changed the summary header label (e.g., `lint output:` instead of `lint stderr:`), breaking #784's tests. - Uses combined *content* on failure (preserving #772's intent) but keeps the configured *label* so the header matches `output_summary`. - Fixes CI failures on #806. ## Test plan - [x] `test/output_summary_no_duplicate.bats` passes locally (both tests) - [ ] CI passes on this PR 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk, small change limited to end-of-run output summarization; main risk is subtle behavior differences in how failure output is labeled (and stored) for downstream consumers/tests. > > **Overview** > On step failure, the summary now saves **combined output content** to avoid losing diagnostics, but preserves the step’s configured `output_summary` *mode/label* instead of forcing `Combined`. > > `output_summary = "hide"` is still respected even on failure, preventing any summary output from being recorded. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f0090e4. 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: Claude Opus 4.6 (1M context) <[email protected]>
### 🐛 Bug Fixes - **(hook)** remove dup output and preserve check_first diagnostics by [@nkakouros](https://github.com/nkakouros) in [#784](#784) - **(hook)** show combined output for failed steps by [@nkakouros](https://github.com/nkakouros) in [#772](#772) - **(hook)** preserve configured output_summary label on failure by [@jdx](https://github.com/jdx) in [#808](#808) ### 📦️ Dependency Updates - update rust crate pklr to 0.4.1 by [@jhult](https://github.com/jhult) in [#805](#805) ### New Contributors - @jhult made their first contribution in [#805](#805) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily a version bump and doc/metadata regeneration, plus routine dependency lockfile updates; minimal behavioral risk beyond potential upstream crate changes. > > **Overview** > Bumps `hk` to **v1.41.1** and adds the corresponding `CHANGELOG.md` release entry. > > Regenerates/version-aligns published artifacts and docs (CLI docs JSON/markdown, `hk.usage.kdl`, and all docs/examples that reference the release `package://.../v1.41.1` URLs). > > Updates `Cargo.lock` for dependency bumps (notably `pklr 0.4.1`, `indexmap 2.14.0`/`hashbrown 0.17.0`, and `tokio 1.51.1`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0a2a092. 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 <[email protected]>
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [hk](https://github.com/jdx/hk) | patch | `1.41.0` → `1.41.1` | 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.41.1`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1411---2026-04-10) [Compare Source](jdx/hk@v1.41.0...v1.41.1) ##### 🐛 Bug Fixes - **(hook)** remove dup output and preserve check\_first diagnostics by [@​nkakouros](https://github.com/nkakouros) in [#​784](jdx/hk#784) - **(hook)** show combined output for failed steps by [@​nkakouros](https://github.com/nkakouros) in [#​772](jdx/hk#772) - **(hook)** preserve configured output\_summary label on failure by [@​jdx](https://github.com/jdx) in [#​808](jdx/hk#808) ##### 📦️ Dependency Updates - update rust crate pklr to 0.4.1 by [@​jhult](https://github.com/jhult) in [#​805](jdx/hk#805) ##### New Contributors - [@​jhult](https://github.com/jhult) made their first contribution in [#​805](jdx/hk#805) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever MR is behind base branch, 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:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuOCIsInVwZGF0ZWRJblZlciI6IjQzLjExMC44IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6cGF0Y2giXX0=-->
Summary
handle_script_failedoutput dump fromfriendly_errorinmain.rs. The per-stepoutput_by_stepsummary already displays all failing steps' output —friendly_errorwas printing the first failing step's combined output again, causing duplication and misattribution (e.g., ghalint output appearing to be part of zizmor's section).check_firstdiagnostic output when cancelled byfail_fast. Forcheck_diff/check_list_filessteps, the check output was lost if another step failed first (triggering cancellation before the second run).Context
When multiple steps fail, the end-of-run output looked like:
handle_script_failedonly showed the firstScriptFailedin the error chain, so withfail_fast=falseonly one step's output was repeated while others were ignored.Test plan
test/output_bugs_repro.bats— 4 regression tests covering duplicateoutput, multi-step failures, stdout output_summary, and HK_SUMMARY_TEXT
test/output_summary.batsandtest/output_summary_check_first.batspasscargo test— 152 passedtest:batssuite — no new failures🤖 Generated with Claude Code