Documentation
¶
Overview ¶
Package hooks provides post-operation hook execution with placeholder substitution.
Hooks are shell commands defined in config that run after wt operations like checkout, pr checkout, prune, or merge. They enable workflow automation such as opening editors, installing dependencies, or sending notifications.
Hook Selection ¶
Hooks can run automatically or manually:
- Automatic: Hooks with "on" config matching the command type run automatically
- Manual: Use --hook=name to run a specific hook, --no-hook to skip all
Example config:
[hooks.vscode]
command = "code {worktree-dir}"
on = ["checkout", "pr"] # auto-run for checkout and pr commands
[hooks.cleanup]
command = "echo 'Done with {branch}'"
# no "on" - only runs via --hook=cleanup
Placeholder Substitution ¶
Static placeholders available in all hooks:
- {worktree-dir}: Absolute worktree path
- {repo-dir}: Absolute main repo path
- {branch}: Branch name
- {repo}: Folder name of git repo
- {origin}: Repository name from git origin (falls back to {repo})
- {trigger}: Command that triggered the hook (checkout, pr, prune, merge)
Custom variables via --arg key=value or --arg key (bare boolean):
- {key}: Value from --arg key=value
- {key:-default}: Value with fallback if not provided
- {key:+text}: Expands to text if key is set and non-empty, otherwise empty
Execution Context ¶
Hooks run with the working directory set to:
- Worktree path for checkout/pr hooks
- Main repo path for prune hooks (worktree is deleted)
Hook failures are logged but don't stop batch operations (RunForEach). Use RunSingle for individual hook execution where errors are returned to the caller.
Stdin Support ¶
Use --arg key=- to read stdin content into a variable:
echo "my content" | wt hook myhook --arg content=-
Index ¶
- func NeedsStdin(envSlice []string) bool
- func ParseEnvWithCachedStdin(envSlice []string, stdinContent string) (map[string]string, error)
- func ParseEnvWithStdin(envSlice []string) (map[string]string, error)
- func ReadStdinIfPiped() (string, error)
- func RunAllNonFatal(goCtx context.Context, matches []HookMatch, ctx Context, workDir string)
- func RunForEach(goCtx context.Context, matches []HookMatch, ctx Context, workDir string)
- func RunSingle(goCtx context.Context, name string, hook *config.Hook, ctx Context) error
- func SubstitutePlaceholders(command string, ctx Context) string
- type CommandType
- type Context
- type HookMatch
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NeedsStdin ¶ added in v0.10.0
NeedsStdin returns true if any env entry has "-" as value
func ParseEnvWithCachedStdin ¶ added in v0.10.0
ParseEnvWithCachedStdin parses a slice of "key=value" or bare "key" strings into a map, using pre-read stdin content for any "-" values. Bare keys without "=" are treated as boolean flags with value "true". Returns an error if stdin is needed but stdinContent is empty.
func ParseEnvWithStdin ¶
ParseEnvWithStdin parses a slice of "key=value" strings into a map. If any value is "-", reads stdin content and assigns it to all such keys. Returns an error if stdin is requested but not piped or empty.
func ReadStdinIfPiped ¶ added in v0.10.0
ReadStdinIfPiped reads all content from stdin if it's piped (not a TTY). Returns empty string and nil if stdin is a TTY (interactive).
func RunAllNonFatal ¶
RunAllNonFatal runs all matched hooks, logging failures as warnings instead of returning errors. Prints "No hooks matched" if matches is empty.
func RunForEach ¶
RunForEach runs all matched hooks for a single item (e.g., one worktree in a batch). Logs failures as warnings with branch context. Does NOT print "no hooks matched".
func RunSingle ¶
RunSingle runs a single hook by name with the given context. Used by `wt hook` to execute a specific hook manually.
func SubstitutePlaceholders ¶
SubstitutePlaceholders replaces {placeholder} with values from Context.
Static placeholders: {worktree-dir}, {repo-dir}, {branch}, {repo}, {origin}, {trigger} Env placeholders (from Context.Env via --arg key=value or --arg key):
- {key} - value from --arg key=value
- {key:-default} - value with default if key not set
- {key:+text} - expands to text if key is set and non-empty, otherwise empty
Types ¶
type CommandType ¶
type CommandType string
CommandType identifies which command is triggering the hook
const ( CommandCheckout CommandType = "checkout" CommandPR CommandType = "pr" CommandPrune CommandType = "prune" CommandMerge CommandType = "merge" )
type Context ¶
type Context struct {
WorktreeDir string // absolute worktree path
RepoDir string // absolute main repo path
Branch string // branch name
Repo string // folder name of git repo
Origin string // repo name from git origin URL (falls back to Repo)
Trigger string // command that triggered the hook (checkout, pr, prune, merge)
Env map[string]string // custom variables from --arg key=value flags
DryRun bool // if true, print command instead of executing
}
Context holds the values for placeholder substitution
type HookMatch ¶
HookMatch represents a hook that matched the current command
func SelectHooks ¶
func SelectHooks(cfg config.HooksConfig, hookNames []string, noHook bool, cmdType CommandType) ([]HookMatch, error)
SelectHooks determines which hooks to run based on config and CLI flags. Returns all matching hooks. If hookNames are specified, those hooks run. Otherwise, all hooks with matching "on" conditions run. Returns nil slice if no hooks should run, error if any specified hook doesn't exist.