hooks

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2026 License: MIT Imports: 11 Imported by: 0

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 (matches -r flag)
  • {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:

  • {key}: Value from --arg key=value
  • {key:-default}: Value with fallback if not provided

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 RunAll when hook failure should stop execution.

Stdin Support

Use --arg key=- to read stdin content into a variable:

echo "my content" | wt hook myhook --arg content=-

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NeedsStdin added in v0.10.0

func NeedsStdin(envSlice []string) bool

NeedsStdin returns true if any env entry has "-" as value

func ParseEnv

func ParseEnv(envSlice []string) (map[string]string, error)

ParseEnv parses a slice of "key=value" strings into a map. Returns an error if any entry doesn't contain "=".

func ParseEnvWithCachedStdin added in v0.10.0

func ParseEnvWithCachedStdin(envSlice []string, stdinContent string) (map[string]string, error)

ParseEnvWithCachedStdin parses a slice of "key=value" strings into a map, using pre-read stdin content for any "-" values. Returns an error if stdin is needed but stdinContent is empty.

func ParseEnvWithStdin

func ParseEnvWithStdin(envSlice []string) (map[string]string, error)

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

func ReadStdinIfPiped() (string, error)

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 RunAll

func RunAll(matches []HookMatch, ctx Context) error

RunAll runs all matched hooks with the given context. Prints "No hooks matched" if matches is empty, otherwise runs each hook. Returns on first error.

func RunAllNonFatal

func RunAllNonFatal(matches []HookMatch, ctx Context, workDir string)

RunAllNonFatal runs all matched hooks, logging failures as warnings instead of returning errors. Prints "No hooks matched" if matches is empty.

func RunForEach

func RunForEach(matches []HookMatch, ctx Context, workDir string)

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

func RunSingle(name string, hook *config.Hook, ctx Context) error

RunSingle runs a single hook by name with the given context. Used by `wt hook` to execute a specific hook manually.

func SubstitutePlaceholders

func SubstitutePlaceholders(command string, ctx Context) string

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):

  • {key} - value from --arg key=value
  • {key:-default} - value with default if key not set

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"
	CommandCd       CommandType = "cd"
)

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 (matches -r flag)
	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

func ContextFromRepo added in v0.4.0

func ContextFromRepo(repoPath string, trigger CommandType, env map[string]string) Context

ContextFromRepo builds a Context for a repository (not worktree-specific).

func ContextFromWorktree added in v0.4.0

func ContextFromWorktree(target *resolve.Target, trigger CommandType, env map[string]string) Context

ContextFromWorktree builds a Context from a resolved worktree target.

type HookMatch

type HookMatch struct {
	Hook *config.Hook
	Name string
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL