Module: RosettAi::GitHooks::ScriptGenerator

Defined in:
lib/rosett_ai/git_hooks/script_generator.rb

Overview

Generates POSIX sh hook scripts that invoke rai commands.

Scripts include timeout handling, RAI_SKIP_HOOKS bypass, and chaining to pre-existing hooks via the backup mechanism.

Author:

  • hugo

  • claude

Constant Summary collapse

BACKUP_SUFFIX =
'.rosett-ai-backup'
DEFAULT_TIMEOUT =
30
DANGEROUS_PATTERN =

Pattern matching shell metacharacters that indicate potential injection. Matches: ; | & ` $( )

/[;|&`]|\$\(/

Class Method Summary collapse

Class Method Details

.blocking_hook?(hook_name) ⇒ Boolean

Returns true if the hook should block the git operation on failure.

Parameters:

  • hook_name (String)

Returns:

  • (Boolean)

    true if the hook should block the git operation on failure



56
57
58
# File 'lib/rosett_ai/git_hooks/script_generator.rb', line 56

def self.blocking_hook?(hook_name)
  ['pre-commit', 'pre-push'].include?(hook_name)
end

.generate(hook_name:, commands:, timeout: DEFAULT_TIMEOUT) ⇒ String

Generates a POSIX sh hook script.

Parameters:

  • hook_name (String)

    the git hook name (e.g. 'pre-commit')

  • commands (Array<String>)

    rai commands to run

  • timeout (Integer) (defaults to: DEFAULT_TIMEOUT)

    timeout in seconds (default 30)

Returns:

  • (String)

    the generated script content

Raises:

  • (ArgumentError)

    if any command contains shell metacharacters



44
45
46
47
48
49
50
51
52
# File 'lib/rosett_ai/git_hooks/script_generator.rb', line 44

def self.generate(hook_name:, commands:, timeout: DEFAULT_TIMEOUT)
  commands.each { |cmd| validate_command!(cmd) }
  blocking = blocking_hook?(hook_name)

  lines = [shebang, marker, skip_check, chain_call(hook_name)]
  commands.each { |cmd| lines << command_block(cmd, timeout, blocking) }
  lines << exit_line
  lines.join("\n")
end

.validate_command!(command)

This method returns an undefined value.

Validates a command string for shell safety.

Parameters:

  • command (String)

    the command to validate

Raises:

  • (ArgumentError)

    if the command contains dangerous shell metacharacters



30
31
32
33
34
35
# File 'lib/rosett_ai/git_hooks/script_generator.rb', line 30

def self.validate_command!(command)
  return unless command.match?(DANGEROUS_PATTERN)

  raise ArgumentError,
        "Hook command contains dangerous shell metacharacters: #{command.inspect}"
end