Class: RosettAi::GitHooks::ChainDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/git_hooks/chain_detector.rb

Overview

Detects existing git hook managers and hook scripts in a repository.

Identifies overcommit, husky, lefthook, and plain shell hooks to inform the installer about chaining requirements.

Author:

  • hugo

  • claude

Constant Summary collapse

KNOWN_MANAGERS =
{
  'overcommit' => { marker: /overcommit/i, config: '.overcommit.yml' },
  'husky' => { marker: /husky/i, config: '.husky' },
  'lefthook' => { marker: /lefthook/i, config: 'lefthook.yml' }
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(project_root:) ⇒ ChainDetector

Returns a new instance of ChainDetector.

Parameters:

  • project_root (Pathname)

    path to the project root



23
24
25
26
# File 'lib/rosett_ai/git_hooks/chain_detector.rb', line 23

def initialize(project_root:)
  @project_root = Pathname.new(project_root)
  @hooks_dir = @project_root.join('.git', 'hooks')
end

Instance Method Details

#all_existingHash{String => Hash}

Checks all supported hooks for existing non-rosett-ai scripts.

Returns:

  • (Hash{String => Hash})

    map of hook names to existing hook info



65
66
67
68
69
70
# File 'lib/rosett_ai/git_hooks/chain_detector.rb', line 65

def all_existing
  Installer::SUPPORTED_HOOKS.each_with_object({}) do |hook, result|
    info = existing_hook(hook)
    result[hook] = info if info
  end
end

#detectArray<Hash>

Detects which hook managers are present in the project.

Returns:

  • (Array<Hash>)

    list of detected managers with :name and :type



31
32
33
34
35
36
37
38
39
40
# File 'lib/rosett_ai/git_hooks/chain_detector.rb', line 31

def detect
  managers = []

  KNOWN_MANAGERS.each do |name, info|
    config_path = @project_root.join(info[:config])
    managers << { name: name, type: :config } if config_path.exist?
  end

  managers
end

#existing_hook(hook_name) ⇒ Hash?

Checks if a specific hook has an existing non-rosett-ai script.

Parameters:

  • hook_name (String)

    the git hook name

Returns:

  • (Hash, nil)

    info about the existing hook or nil



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/rosett_ai/git_hooks/chain_detector.rb', line 46

def existing_hook(hook_name)
  path = @hooks_dir.join(hook_name)
  return nil unless path.exist?
  return nil if rai_managed?(path)

  content = File.read(path)
  manager = identify_manager(content)

  {
    path: path.to_s,
    manager: manager,
    symlink: path.symlink?,
    executable: path.executable?
  }
end