Context
Roughly 11 Windows PowerShell chezmoiscripts each carry their own copy of "find this tool's binary" logic — a Resolve-*Path function or an inline candidate-paths array plus a Get-Command fallback. That's ~350 lines of near-identical lookup logic. Each script is shallow at the lookup seam: the same fallback search is duplicated everywhere with only the tool name and candidate paths varying.
A smaller, related duplication: Assert-LastExitCode is defined identically in at least run_after_90_package_updates_windows.ps1.tmpl and run_onchange_after_bootstrap_windows.ps1.tmpl.
Files
Scripts with bespoke tool resolution (non-exhaustive):
home/.chezmoiscripts/run_onchange_after_glazewm_reload_windows.ps1.tmpl (Resolve-GlazeExePath)
home/.chezmoiscripts/run_onchange_after_komorebi_reload_windows.ps1.tmpl (Resolve-KomorebicPath)
home/.chezmoiscripts/run_onchange_after_pi_packages_windows.ps1.tmpl (Get-PiCommand)
home/.chezmoiscripts/run_onchange_after_mise_install_windows.ps1.tmpl (inline $miseCandidates)
home/.chezmoiscripts/run_after_90_package_updates_windows.ps1.tmpl
home/.chezmoiscripts/run_onchange_after_bootstrap_windows.ps1.tmpl
home/.chezmoiscripts/run_onchange_after_choco_review_windows.ps1.tmpl ($bashCandidates)
- plus several more with inline variants
Shared template to extend:
home/.chezmoitemplates/windows-elevation.ps1.tmpl
What to do
- Add
home/.chezmoitemplates/windows-resolve-tool-path.ps1.tmpl: a parameterised helper that takes a tool name + candidate path list and returns a resolved path (Get-Command → candidate paths → fail), included the same way windows-elevation.ps1.tmpl is.
- Replace each bespoke
Resolve-* function / inline array with a call to the shared helper.
- Move
Assert-LastExitCode into windows-elevation.ps1.tmpl so callers inherit it instead of redefining it.
- Confirm every touched
.ps1.tmpl still renders to empty on non-Windows ({{ if eq .chezmoi.os "windows" }} guards intact).
Out of scope
- Changing what any script does once it has the binary path.
- Non-Windows scripts.
Context
Roughly 11 Windows PowerShell chezmoiscripts each carry their own copy of "find this tool's binary" logic — a
Resolve-*Pathfunction or an inline candidate-paths array plus aGet-Commandfallback. That's ~350 lines of near-identical lookup logic. Each script is shallow at the lookup seam: the same fallback search is duplicated everywhere with only the tool name and candidate paths varying.A smaller, related duplication:
Assert-LastExitCodeis defined identically in at leastrun_after_90_package_updates_windows.ps1.tmplandrun_onchange_after_bootstrap_windows.ps1.tmpl.Files
Scripts with bespoke tool resolution (non-exhaustive):
home/.chezmoiscripts/run_onchange_after_glazewm_reload_windows.ps1.tmpl(Resolve-GlazeExePath)home/.chezmoiscripts/run_onchange_after_komorebi_reload_windows.ps1.tmpl(Resolve-KomorebicPath)home/.chezmoiscripts/run_onchange_after_pi_packages_windows.ps1.tmpl(Get-PiCommand)home/.chezmoiscripts/run_onchange_after_mise_install_windows.ps1.tmpl(inline$miseCandidates)home/.chezmoiscripts/run_after_90_package_updates_windows.ps1.tmplhome/.chezmoiscripts/run_onchange_after_bootstrap_windows.ps1.tmplhome/.chezmoiscripts/run_onchange_after_choco_review_windows.ps1.tmpl($bashCandidates)Shared template to extend:
home/.chezmoitemplates/windows-elevation.ps1.tmplWhat to do
home/.chezmoitemplates/windows-resolve-tool-path.ps1.tmpl: a parameterised helper that takes a tool name + candidate path list and returns a resolved path (Get-Command → candidate paths → fail), included the same waywindows-elevation.ps1.tmplis.Resolve-*function / inline array with a call to the shared helper.Assert-LastExitCodeintowindows-elevation.ps1.tmplso callers inherit it instead of redefining it..ps1.tmplstill renders to empty on non-Windows ({{ if eq .chezmoi.os "windows" }}guards intact).Out of scope