Documentation
¶
Overview ¶
Package hooks provides secure command execution for before/after hooks.
Hooks are executed without shell interpretation for security:
- No pipes (|)
- No redirects (>, <, >>)
- No variable expansion ($VAR)
- No subshell execution
Commands are parsed as simple space-separated arguments with basic quoting support. For complex operations, users should create scripts and call them from hooks.
Example usage:
hooks := &config.Hooks{
Before: []string{"mkdir -p logs"},
After: []string{"make setup", "echo done"},
}
err := hooks.Execute(ctx, hooks, "before", "/path/to/workdir", logger)
if err != nil {
return fmt.Errorf("before hooks failed: %w", err)
}
Security considerations:
- 30 second timeout per command
- Direct exec.Command (no shell)
- Working directory must exist
- Environment inherited from parent process
Index ¶
- Constants
- func Execute(ctx context.Context, hooks *config.Hooks, phase, workDir string, logger Logger) error
- func ExecuteCommands(ctx context.Context, commands []string, workDir string, logger Logger) error
- func HasUnsafeCharacters(cmd string) bool
- func Merge(global, local *config.Hooks) *config.Hooks
- func ParseCommand(cmd string) []string
- func Validate(hooks *config.Hooks) error
- func ValidateCommands(commands []string) error
- type Logger
Constants ¶
const DefaultTimeout = 30 * time.Second
DefaultTimeout is the default timeout for hook commands (30 seconds).
Variables ¶
This section is empty.
Functions ¶
func Execute ¶
Execute runs hook commands in the specified directory. It runs hooks for the specified phase ("before" or "after"). Returns error if any hook fails (marks operation as failed). Uses direct exec without shell for security (no pipes, redirects, variables).
func ExecuteCommands ¶
ExecuteCommands runs a list of commands in the specified directory. Returns error if any command fails.
func HasUnsafeCharacters ¶
HasUnsafeCharacters checks if a command contains potentially dangerous characters. Returns true if pipes, redirects, or variable expansion are detected.
func Merge ¶
Merge combines global and workspace-level hooks. Global hooks run first, then workspace hooks. Returns nil if both inputs are nil.
func ParseCommand ¶
ParseCommand splits a hook command string into executable and arguments. Supports simple quoting but NOT shell features (pipes, redirects, variables). This is intentional for security - use scripts for complex commands.
Examples:
"make build" → ["make", "build"] "echo 'hello world'" → ["echo", "hello world"] "cmd \"arg with spaces\"" → ["cmd", "arg with spaces"]
func Validate ¶
Validate checks if hooks configuration is safe. Returns error if any command contains unsafe shell characters.
func ValidateCommands ¶
ValidateCommands checks if all commands in a hook list are safe. Returns an error describing which command has unsafe characters.