Module: Ukiryu::ToolFinder Private

Defined in:
lib/ukiryu/tool_finder.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Tool finding by name, interface, or alias

Provides methods to discover tools by various identifiers:

  • Exact name match

  • Interface implementation (e.g., :convert, :video_encoder)

  • Shell aliases

Class Method Summary collapse

Class Method Details

.extract_alias_target(alias_info) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Extract the command target from an alias definition

Parameters:

  • alias_info (Hash)

    the alias info with :target key

Returns:

  • (String)

    the extracted command



152
153
154
155
156
# File 'lib/ukiryu/tool_finder.rb', line 152

def extract_alias_target(alias_info)
  target = alias_info[:target]
  # Extract the first word from the target
  target.split(/\s+/).first
end

.find_all(tool_name, options = {}) ⇒ Array<Models::ExecutableInfo>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find all instances of a tool in PATH and aliases

This is an explicit operation - user must ask for it. Returns an array of ExecutableInfo for all matches found.

Parameters:

  • tool_name (String, Symbol)

    the tool to find

  • options (Hash) (defaults to: {})

    initialization options

Returns:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/ukiryu/tool_finder.rb', line 105

def find_all(tool_name, options = {})
  require_relative 'models/executable_info'
  require_relative 'shell/alias_detector' unless defined?(Shell::AliasDetector)

  shell = options[:shell]&.to_sym || Ukiryu::Runtime.instance.shell
  results = []

  # Check PATH using 'command -v' which can show multiple matches
  path_results = `command -v #{tool_name} 2>/dev/null`
  path_results&.split("\n")&.each do |line|
    line.strip!
    next if line.empty?

    results << Ukiryu::Models::ExecutableInfo.new(
      path: line,
      source: :path,
      shell: shell,
      alias_definition: nil
    )
  end

  # Check shell aliases
  alias_info = Shell::AliasDetector.detect(tool_name.to_s, shell)
  if alias_info
    results << Ukiryu::Models::ExecutableInfo.new(
      path: extract_alias_target(alias_info),
      source: :alias,
      shell: shell,
      alias_definition: alias_info[:definition]
    )
  end

  results
end

.find_by(identifier, options = {}) ⇒ Tool?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find a tool by name, alias, or interface

Searches for a tool that matches the given identifier by:

  1. Exact name match (fastest)

  2. Interface match via ToolIndex (O(1) lookup)

  3. Alias match via ToolIndex (O(1) lookup)

  4. Returns the first tool that is available on the current platform

Debug mode: Set UKIRYU_DEBUG=1 or UKIRYU_DEBUG=true to enable structured debug output

Parameters:

  • identifier (String, Symbol)

    the tool name, interface, or alias

  • options (Hash) (defaults to: {})

    initialization options

Returns:

  • (Tool, nil)

    the tool instance or nil if not found



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ukiryu/tool_finder.rb', line 27

def find_by(identifier, options = {})
  require_relative 'tool_cache'
  require_relative 'tool'

  identifier = identifier.to_s
  runtime = Ukiryu::Runtime.instance
  platform = options[:platform] || runtime.platform
  shell = options[:shell] || runtime.shell

  # Create logger instance
  logger = Ukiryu::Logger.new

  # 1. Try exact name match first (fastest path)
  begin
    tool = Ukiryu::Tool.get(identifier, options)
    if logger.debug_enabled?
      all_tools = Ukiryu::Register.tools
      logger.debug_section_tool_resolution(
        identifier: identifier,
        platform: platform,
        shell: shell,
        all_tools: all_tools,
        selected_tool: identifier,
        executable: tool.executable
      )
    end
    return tool
  rescue Ukiryu::Errors::ToolNotFoundError, Ukiryu::Errors::ProfileNotFoundError
    # Continue to search by interface/alias
  end

  # 2. Use ToolIndex for O(1) interface lookup
  index = Ukiryu::ToolIndex.instance
  interface_tool_names = index.find_all_by_interface(identifier.to_sym)
  if interface_tool_names.any?
    interface_tool_names.each do |tool_name|
      tool = Ukiryu::Tool.get(tool_name.to_s, options)
      # Return tool only if it's available (executable found)
      return tool if tool.available?
    rescue Ukiryu::Errors::ToolNotFoundError, Ukiryu::Errors::ProfileNotFoundError
      # Tool indexed but not available, continue to next
    end
  end

  # 3. Use ToolIndex for O(1) alias lookup
  alias_tool_name = index.find_by_alias(identifier)
  if alias_tool_name
    begin
      return Ukiryu::Tool.get(alias_tool_name.to_s, options)
    rescue Ukiryu::Errors::ToolNotFoundError, Ukiryu::Errors::ProfileNotFoundError
      # Alias indexed but tool not available, continue
    end
  end

  # 4. Fallback to exhaustive search (should rarely reach here)
  tool = exhaustive_search(identifier, options, platform, shell, logger)
  return tool if tool

  if logger.debug_enabled?
    all_tools = Ukiryu::Register.tools
    logger.debug_section_tool_not_found(
      identifier: identifier,
      platform: platform,
      shell: shell,
      all_tools: all_tools
    )
  end
  nil
end

.get_class(tool_name) ⇒ Class

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the tool-specific class (new OOP API)

Parameters:

  • tool_name (Symbol, String)

    the tool name

Returns:

  • (Class)

    the tool class (e.g., Ukiryu::Tools::Imagemagick)



144
145
146
# File 'lib/ukiryu/tool_finder.rb', line 144

def get_class(tool_name)
  Ukiryu::Tools::Generator.generate_and_const_set(tool_name)
end