Module: RubyLens::Clip::Toolchain

Defined in:
lib/rubylens/clip/toolchain.rb

Overview

Locates the two external tools clip rendering needs: a Chrome/Chromium binary and ffmpeg. Environment overrides win, then PATH, then well-known install locations. Discovery failures raise with install guidance so the command fails fast, before any indexing work.

Constant Summary collapse

CHROME_ENV =
"RUBYLENS_CHROME"
FFMPEG_ENV =
"RUBYLENS_FFMPEG"
CHROME_COMMANDS =
%w[google-chrome google-chrome-stable chromium chromium-browser chrome].freeze
CHROME_KNOWN_PATHS =
[
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
  "/Applications/Chromium.app/Contents/MacOS/Chromium",
  "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
].freeze
PLAYWRIGHT_CHROME_GLOBS =
%w[
  chromium
  chromium-*/chrome-linux/chrome
  chromium-*/chrome-mac/Chromium.app/Contents/MacOS/Chromium
].freeze

Class Method Summary collapse

Class Method Details

.chrome_pathObject



28
29
30
31
32
33
34
# File 'lib/rubylens/clip/toolchain.rb', line 28

def chrome_path
  from_environment(CHROME_ENV) ||
    from_path(CHROME_COMMANDS) ||
    from_known_paths(CHROME_KNOWN_PATHS + playwright_chrome_candidates) ||
    raise(Error, "clip rendering needs Chrome or Chromium; install Google Chrome, " \
                 "or point #{CHROME_ENV} at a Chrome-compatible browser binary")
end

.executable?(path) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/rubylens/clip/toolchain.rb', line 77

def executable?(path)
  File.file?(path) && File.executable?(path)
end

.ffmpeg_pathObject



36
37
38
39
40
41
# File 'lib/rubylens/clip/toolchain.rb', line 36

def ffmpeg_path
  from_environment(FFMPEG_ENV) ||
    from_path(%w[ffmpeg]) ||
    raise(Error, "clip rendering needs ffmpeg; install it (for example `brew install ffmpeg` " \
                 "or `apt install ffmpeg`), or point #{FFMPEG_ENV} at an ffmpeg binary")
end

.from_environment(name) ⇒ Object

Raises:



43
44
45
46
47
48
49
# File 'lib/rubylens/clip/toolchain.rb', line 43

def from_environment(name)
  value = ENV.fetch(name, nil)
  return nil if value.nil? || value.empty?
  raise Error, "#{name} is set to #{value}, which is not an executable file" unless executable?(value)

  value
end

.from_known_paths(paths) ⇒ Object



64
65
66
# File 'lib/rubylens/clip/toolchain.rb', line 64

def from_known_paths(paths)
  paths.find { |path| executable?(path) }
end

.from_path(commands) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rubylens/clip/toolchain.rb', line 51

def from_path(commands)
  directories = ENV.fetch("PATH", "").split(File::PATH_SEPARATOR)
  commands.each do |command|
    directories.each do |directory|
      next if directory.empty?

      candidate = File.join(directory, command)
      return candidate if executable?(candidate)
    end
  end
  nil
end

.playwright_chrome_candidatesObject



68
69
70
71
72
73
74
75
# File 'lib/rubylens/clip/toolchain.rb', line 68

def playwright_chrome_candidates
  root = ENV.fetch("PLAYWRIGHT_BROWSERS_PATH", nil)
  root = File.expand_path("~/.cache/ms-playwright") if root.nil? || root.empty?
  PLAYWRIGHT_CHROME_GLOBS.flat_map { |pattern| Dir.glob(File.join(root, pattern)) }.sort
rescue ArgumentError
  # File.expand_path("~") raises when HOME is unset.
  []
end