Escape hatch for arbitrary shell commands.
Options
:run— command string. Required. Supports template variables:{files}— space-separated paths passed to the hook (stage-specific source, e.g. staged files forpre_commit, the commit-message path forcommit_msg).{staged_files}—git diff --cached --name-only --diff-filter=ACMR, looked up at call time regardless of stage.{all_files}—git ls-files, looked up at call time.{push_files}— paths parsed frompre_pushstdin. Only valid in thepre_pushstage; the hook returns an error if used elsewhere.
:shell— shell executable. Default"sh".
Defaults
stage_fixed: false
Behaviour with no matching files
When the template references {files} or {push_files} and the hook is
invoked with an empty file list, the hook returns :ok without running
the shell command. This avoids "empty argument" substitutions like
mix sobelow --exit Low — a trailing space which mix sobelow
interprets as "scan the entire project", typically the opposite of what
the caller wanted. The same skip applies when {staged_files} is
referenced and git diff --cached returns no files.
Note that GitHoox.Runner already skips hooks whose :files glob matches
nothing, so this guard only fires when Shell.run/2 is invoked directly
or when a custom template asks for a file source that the current state
cannot satisfy.
Timeouts
Timeouts are enforced by GitHoox.Runner, not by this module. A shell
command exceeding the per-hook :timeout is killed brutally and surfaces
as {:error, {:timeout, ms}}. The default timeout is 30 000 ms —
override per hook via the :timeout option in the global hook schema.