Class: EnhanceSwarm::CommandExecutor

Inherits:
Object
  • Object
show all
Defined in:
lib/enhance_swarm/command_executor.rb

Defined Under Namespace

Classes: CommandError

Class Method Summary collapse

Class Method Details

.command_available?(command) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
# File 'lib/enhance_swarm/command_executor.rb', line 59

def self.command_available?(command)
  execute('which', command, timeout: 5)
  true
rescue CommandError
  false
end

.execute(command, *args, timeout: 30, input: nil) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/enhance_swarm/command_executor.rb', line 19

def self.execute(command, *args, timeout: 30, input: nil)
  # Sanitize command and arguments
  safe_command = sanitize_command(command)
  safe_args = args.map { |arg| sanitize_argument(arg) }

  begin
    Timeout.timeout(timeout) do
      stdout, stderr, status = Open3.capture3(safe_command, *safe_args,
                                              stdin_data: input)

      unless status.success?
        raise CommandError.new(
          "Command failed: #{safe_command} #{safe_args.join(' ')}",
          exit_status: status.exitstatus,
          stderr: stderr
        )
      end

      stdout.strip
    end
  rescue Timeout::Error
    raise CommandError.new("Command timed out after #{timeout} seconds")
  rescue Errno::ENOENT
    raise CommandError.new("Command not found: #{safe_command}")
  end
end

.execute_async(command, *args) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/enhance_swarm/command_executor.rb', line 46

def self.execute_async(command, *args)
  safe_command = sanitize_command(command)
  safe_args = args.map { |arg| sanitize_argument(arg) }

  begin
    pid = Process.spawn(safe_command, *safe_args)
    Process.detach(pid)
    pid
  rescue Errno::ENOENT
    raise CommandError.new("Command not found: #{safe_command}")
  end
end

.sanitize_argument(arg) ⇒ Object



73
74
75
76
# File 'lib/enhance_swarm/command_executor.rb', line 73

def self.sanitize_argument(arg)
  # Convert to string and escape shell metacharacters
  Shellwords.escape(arg.to_s)
end

.sanitize_command(command) ⇒ Object

Raises:

  • (ArgumentError)


66
67
68
69
70
71
# File 'lib/enhance_swarm/command_executor.rb', line 66

def self.sanitize_command(command)
  # Only allow alphanumeric, dash, underscore, and slash
  raise ArgumentError, "Invalid command: #{command}" unless command.match?(%r{\A[a-zA-Z0-9_\-/]+\z})

  command
end