feat(config): add run field for hooks#9718
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new { run = "..." } syntax for hooks to explicitly define subprocess execution, separating it from shell-based scripts. The changes include updates to documentation, end-to-end tests, and the JSON schema, along with Rust implementation changes that add deprecation warnings for ambiguous or unsupported hook configurations. Feedback suggests refactoring the JSON schema to utilize $defs and $ref for hook definitions to improve maintainability and reduce redundancy.
Greptile SummaryThis PR introduces an explicit
Confidence Score: 5/5Safe to merge — all hook paths are well-covered, backward compatibility is preserved, and the one latent test gap has no impact on runtime correctness today. The HookAction enum refactor is clean and all hook routing paths correctly preserve backward compatibility. The regression fix for install hooks with script + shell is correct. No data-loss or incorrect-behavior paths were found. e2e/config/test_hooks_run_warnings — the { script = 'echo PRE_SCRIPT' } entry carries legacy_script: true and will produce a deprecated [hook_script_table_spawned_run] message once 2026.9.0 ships; no assertion currently covers that output. Important Files Changed
Reviews (9): Last reviewed commit: "Merge branch 'main' into feat/hooks-run-..." | Re-trigger Greptile |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Clarified deprecation notice for the 'script' alias in install hooks.
### 🚀 Features - **(cli)** add minimum release age flag to lock and ls-remote by @risu729 in [#9269](#9269) - **(config)** add run field for hooks by @risu729 in [#9718](#9718) - **(github)** add native oauth token source by @jdx in [#9654](#9654) - **(oci)** scope build to project config by default by @jdx in [#9766](#9766) - add support for prefixed latest version queries in outdated checks by @roele in [#9767](#9767) ### 🐛 Bug Fixes - **(activate)** guard bash chpwd hook under nounset by @risu729 in [#9716](#9716) - **(backend)** date-check latest stable fast path by @risu729 in [#9650](#9650) - **(config)** parse core tool options consistently by @risu729 in [#9742](#9742) - **(exec)** propagate __MISE_DIFF so nested mise recovers pristine PATH by @jdx in [#9765](#9765) - **(forgejo)** include prereleases when opted in by @risu729 in [#9717](#9717) - **(github)** avoid caching empty release assets by @risu729 in [#9616](#9616) - **(java)** resolve lockfile URLs from metadata by @risu729 in [#9719](#9719) - **(lock)** cache unavailable github attestations by @risu729 in [#9741](#9741) - **(pipx)** preserve options when reinstalling tools by @risu729 in [#9663](#9663) - **(python)** skip redundant lockfile provenance verification by @risu729 in [#9739](#9739) - **(vfox)** run pre_uninstall hook by @risu729 in [#9662](#9662) ### 🚜 Refactor - **(schema)** extract tool options definition by @risu729 in [#9649](#9649) ### ⚡ Performance - **(aqua)** bake rkyv aqua package blobs by @risu729 in [#9535](#9535) ### 📦️ Dependency Updates - lock file maintenance by @renovate[bot] in [#9773](#9773) ### 📦 Registry - add vector ([github:vectordotdev/vector](https://github.com/vectordotdev/vector)) by @kquinsland in [#9761](#9761) - add oc and openshift-install (http backend) by @konono in [#9669](#9669) ### New Contributors - @konono made their first contribution in [#9669](#9669) - @kquinsland made their first contribution in [#9761](#9761)
Summary
{ run = "..." }as the explicit inline-command hook form for all hook types.runshorthand, so existingenter = "echo hi"behavior is unchanged and remains documented.{ run = "...", shell = "bash -c" }to choose the inline shell command, matching taskshellsemantics.script + shellas the current-shell form forenter,leave, andcdhooks; hereshellis a shell-name selector such asbash, not an inline shell command.preinstall/postinstallhooks usingscriptstill run as legacy inline commands, andscript + shellwarns thatshellis ignored instead of silently skipping the hook.Split From #9604
This PR is the smaller first slice of #9604. It only introduces the scalar
runhook field and the compatibility behavior needed for existingscripthooks.Intentionally left for #9604 after this merges:
runentries such as{ task = "setup", args = [...] }and{ tasks = [...] }run = [...]arrays where each entry follows taskrunsemanticsrun_windowsscript = [...]current-shell hook arraysFixes Discussion #9636
This also fixes the behavior reported in #9636, which is linked from #9604:
postinstall = { script = "...", shell = "bash" }used to skip silently because install hooks do not have an active current shell.With this PR, install hooks that use
script + shellwarn thatshellis ignored and still run the script through the default inline shell. Users who want to choose the shell for an install hook should userunwith an inline shell command:Behavior Examples
String shorthand remains valid and is equivalent to a scalar
runhook:The explicit scalar form is useful when adding
shell:run.shelluses the same shape as taskshell: it replaces the default inline shell command and should include the command plus inline-eval argument, such asbash -c,zsh -c, orpwsh -Command. Withoutshell,runusesunix_default_inline_shell_argsorwindows_default_inline_shell_args.Current-shell hooks still use
script + shelland only apply to activation hooks:For current-shell hooks,
shellselects the activemise activateshell name. It is not the command used to spawn a subprocess.Tests
cargo fmt --all --checkCARGO_BUILD_JOBS=1 cargo check -qjq empty schema/mise.jsonshellcheck -x e2e/config/test_hooks_run_warningsshfmt -d --apply-ignore e2e/config/test_hooks_run_warningsgit diff --checkCARGO_BUILD_JOBS=1 mise run test:e2e e2e/config/test_hooks e2e/config/test_hooks_task_ref e2e/config/test_hooks_run_warningsCARGO_BUILD_JOBS=1 mise run test:e2e e2e/config/test_hooks_run_warnings