Skip to content

Comments

fix: Add validation for stage attribute requiring fix command#327

Merged
jdx merged 5 commits intomainfrom
validate-stage-requires-fix
Oct 3, 2025
Merged

fix: Add validation for stage attribute requiring fix command#327
jdx merged 5 commits intomainfrom
validate-stage-requires-fix

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Oct 3, 2025

Summary

Implements validation logic to ensure that steps with a stage attribute must also have a fix command. This prevents misconfiguration where steps attempt to stage files without providing a way to fix them.

Addresses the requirement mentioned in recent discussion: "We should actually add some logic in hk that bails if a step has stage set without a fixer."

Changes

  • Config validation: Added logic in Config::validate() that iterates through all hooks and steps (including those in groups) to check for this condition
  • Early validation: Calls validate() in Config::get() so validation runs every time config is loaded, not just when explicitly running hk validate
  • Clear error messages: Provides specific error messages indicating which step in which hook (or group) has the invalid configuration

Test Coverage

Added comprehensive test suite in test/validation_errors.bats covering:

  • ✅ Steps with stage but no fix (should fail validation)
  • ✅ Steps with both stage and fix (should pass)
  • ✅ Steps with fix but no stage (should pass)
  • ✅ Steps with neither stage nor fix (should pass - check-only steps)
  • ✅ Steps in groups with stage but no fix (should fail validation)
  • ✅ Validation across multiple hooks (pre-commit, pre-push, etc.)

All 249 tests passing (including 6 new validation tests).

Example Error Message

Error: Step 'test-step' in hook 'pre-commit' has 'stage' attribute but no 'fix' command. Steps that stage files must have a fix command.

🤖 Generated with Claude Code


Note

Enforces validation that any step with stage must also define fix, runs it on config load, removes stage from built-in Pkl steps without fix, and adds focused tests.

  • Config Validation
    • Add Config::validate() to error when a step (or grouped step) has stage without fix.
    • Invoke validate() in Config::get() so validation runs on every load.
  • Built-ins
    • Remove stage = glob from pkl/builtins/{mix_compile.pkl,mix_test.pkl,pkl.pkl,shellcheck.pkl} to avoid invalid config (no fix).
  • Tests
    • Add test/validation_errors.bats covering valid/invalid stage+fix combinations and groups.
    • Adjust test/depends.bats to avoid staging in the non-fix check step.

Written by Cursor Bugbot for commit 214ee1d. This will update automatically on new commits. Configure here.

@jdx jdx changed the title Add validation for stage attribute requiring fix command fix: Add validation for stage attribute requiring fix command Oct 3, 2025
@jdx jdx enabled auto-merge (squash) October 3, 2025 16:01
claude and others added 2 commits October 3, 2025 16:18
Implements validation logic that ensures steps with a 'stage' attribute
must also have a 'fix' command. This prevents misconfiguration where
steps attempt to stage files without providing a way to fix them.

Changes:
- Add validation in Config::validate() that checks all steps (including
  those in groups) for this condition
- Call validate() in Config::get() so validation runs on every config load
- Add comprehensive tests covering various scenarios:
  - Steps with stage but no fix (should fail)
  - Steps with both stage and fix (should pass)
  - Steps with fix but no stage (should pass)
  - Steps with neither stage nor fix (should pass)
  - Steps in groups with stage but no fix (should fail)
  - Validation across multiple hooks

The validation provides clear error messages indicating which step in
which hook (or group) has the invalid configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The new validation requires steps with 'stage' to also have 'fix'.
These builtins only have check commands and don't modify files, so
they shouldn't have the stage attribute:

- shellcheck: Only lints shell scripts, doesn't fix them
- mix_compile: Only compiles and checks for errors
- mix_test: Only runs tests
- pkl: Only validates pkl syntax

This fixes the test failure in skip_steps.bats which was correctly
being caught by the new validation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@jdx jdx force-pushed the validate-stage-requires-fix branch from d8755c9 to 0c93b40 Compare October 3, 2025 16:19
jdx and others added 3 commits October 3, 2025 12:13
Step 'e' in the file depends test had a 'stage' attribute but only a 'check' command (no 'fix' command), which violates the new validation rule added in this PR. Since the step is check-only and doesn't modify files, the stage attribute was unnecessary and has been removed.
@jdx jdx merged commit 55624a7 into main Oct 3, 2025
7 checks passed
@jdx jdx deleted the validate-stage-requires-fix branch October 3, 2025 17:19
@jdx jdx mentioned this pull request Oct 3, 2025
jdx added a commit that referenced this pull request Oct 5, 2025
## [1.17.0](https://github.com/jdx/hk/compare/v1.16.0..v1.17.0) -
2025-10-05

### 🚀 Features

- Add hk util trailing-whitespace command by
[@jdx](https://github.com/jdx) in
[#319](#319)
- add mixed_line_ending builtin by [@jdx](https://github.com/jdx) in
[#324](#324)
- add check_symlinks builtin by [@jdx](https://github.com/jdx) in
[#326](#326)
- add check_executables_have_shebangs builtin by
[@jdx](https://github.com/jdx) in
[#325](#325)
- Add check-merge-conflict util command and builtin by
[@jdx](https://github.com/jdx) in
[#322](#322)
- add check_case_conflict builtin by [@jdx](https://github.com/jdx) in
[#323](#323)
- add detect_private_key builtin by [@jdx](https://github.com/jdx) in
[#332](#332)
- add check_added_large_files builtin by [@jdx](https://github.com/jdx)
in [#329](#329)
- add python_debug_statements builtin by [@jdx](https://github.com/jdx)
in [#331](#331)
- add python_check_ast builtin by [@jdx](https://github.com/jdx) in
[#330](#330)
- add no_commit_to_branch builtin by [@jdx](https://github.com/jdx) in
[#333](#333)
- add check_byte_order_marker and fix_byte_order_marker builtins by
[@jdx](https://github.com/jdx) in
[#328](#328)
- add regex pattern support for glob and exclude by
[@jdx](https://github.com/jdx) in
[#336](#336)
- automatically batch large file lists to prevent ARG_MAX errors by
[@jdx](https://github.com/jdx) in
[#338](#338)

### 🐛 Bug Fixes

- Add validation for stage attribute requiring fix command by
[@jdx](https://github.com/jdx) in
[#327](#327)
- display stderr when check_list_files returns empty list by
[@jdx](https://github.com/jdx) in
[#334](#334)
- added new builtins to Builtins.pkl by [@jdx](https://github.com/jdx)
in
[b8a2b17](b8a2b17)
- enable experimental settings in mise.toml for swift support by
[@jdx](https://github.com/jdx) in
[#342](#342)
- correct airflow migration test to expect local imports by
[@jdx](https://github.com/jdx) in
[#343](#343)
- make final CI check always run and fail if dependencies fail by
[@jdx](https://github.com/jdx) in
[#344](#344)
- add ruff format to ruff builtin by [@jdx](https://github.com/jdx) in
[#340](#340)

### 🚜 Refactor

- Split util module into separate files by
[@jdx](https://github.com/jdx) in
[#321](#321)

### 🛡️ Security

- migrate pre-commit by [@jdx](https://github.com/jdx) in
[#318](#318)

### 🔍 Other Changes

- split CI runs into parallel jobs and add docs-sync mise task by
[@jdx](https://github.com/jdx) in
[#337](#337)
- remove v0 pkl files from docs/public by [@jdx](https://github.com/jdx)
in [#341](#341)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Release 1.17.0 with new migrate command, many util subcommands,
refreshed docs, and dependency updates.
> 
> - **Version**: bump `hk` to `1.17.0` (Cargo.toml, usage specs, docs).
> - **CLI**:
> - **New Command**: `migrate pre-commit` with flags (`--config`,
`--output`, `--force`, `--hk-pkl-root`).
> - **Util Subcommands**: add `check-added-large-files`,
`check-byte-order-marker`, `fix-byte-order-marker`,
`check-case-conflict`, `check-executables-have-shebangs`,
`check-merge-conflict`, `check-symlinks`, `detect-private-key`,
`end-of-file-fixer`, `mixed-line-ending`, `no-commit-to-branch`,
`python-check-ast`, `python-debug-statements`, `trailing-whitespace`.
> - **Docs**:
> - Update `docs/cli/index.md`, regenerate `docs/cli/commands.json`, and
`hk.usage.kdl`.
>   - Split `util` docs into per-command pages and add `migrate` docs.
> - **Dependencies**: update `Cargo.lock` crate versions and set `hk`
crate version to `1.17.0`.
> - **Changelog**: add `CHANGELOG.md` entry for `1.17.0` with
features/bug fixes.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
75b972a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: mise-en-dev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants