Module: Oximg::Binary

Defined in:
lib/oximg/binary.rb

Overview

Locates the oximg executable and runs it.

Resolution order, first hit wins:

1. +Oximg.executable=+, or +OXIMG_BIN+ — an explicit path always
 wins, and a wrong one raises rather than falling through: a
 silent fallback is how a process ends up running a different
 build than the one it was configured with.
2. the binary bundled in this gem — platform gems
 (+oximg-x.y.z-arm64-darwin+ and friends) ship one, so
 +bundle install+ is the whole installation.
3. +oximg+ on PATH — a Homebrew, +cargo install+ or Docker-image
 binary. This is what the plain-Ruby gem resolves to.

The gem deliberately does not declare spec.executables: RubyGems would generate a Ruby binstub around it, and this is a native binary, not a script. Ask for the path instead.

Constant Summary collapse

EXE =
"oximg#{RbConfig::CONFIG["EXEEXT"]}"
BUNDLED =

Populated by the platform gems at package time; absent in the plain-Ruby gem.

File.expand_path("../../exe/#{EXE}", __dir__)
NOT_FOUND =
<<~MSG.tr("\n", " ").strip
  The oximg executable was not found. Install a platform gem
  (it bundles one), a release binary
  (https://github.com/oximg/oximg/releases), `brew install
  oximg/tap/oximg` or `cargo install oximg` — or point OXIMG_BIN at
  the binary you already have.
MSG

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.pathObject



42
43
44
# File 'lib/oximg/binary.rb', line 42

def path
  @path ||= discover || raise(ExecutableNotFound, NOT_FOUND)
end

Class Method Details

.available?Boolean

True when a binary can be found — for a boot-time check, or for code that falls back to another processor.

Returns:

  • (Boolean)


48
49
50
51
52
# File 'lib/oximg/binary.rb', line 48

def available?
  !path.nil?
rescue ExecutableNotFound
  false
end

.reset!Object

Resets the memoized lookup. For tests, and for a process that changes OXIMG_BIN after boot.



75
76
77
78
# File 'lib/oximg/binary.rb', line 75

def reset!
  @path = nil
  @version = nil
end

.run(*args) ⇒ Object

Runs the binary with args passed as a real argv — no shell, so nothing in a filename can be interpreted as syntax. Returns [stdout, stderr]; a non-zero exit raises with the binary's own stderr, which already names what it refused.



63
64
65
66
67
68
69
70
71
# File 'lib/oximg/binary.rb', line 63

def run(*args)
  out, err, status = Open3.capture3(path, *args)
  unless status.success?
    message = err.strip
    message = "oximg exited #{status.exitstatus}" if message.empty?
    raise ProcessingError.new(message, status.exitstatus)
  end
  [out, err]
end

.versionObject

oximg --version, without the leading program name.



55
56
57
# File 'lib/oximg/binary.rb', line 55

def version
  @version ||= capture("--version").sub(/\Aoximg\s+/, "")
end