Initial parametric Feather case generator
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module FeatherCaseWizard
|
||||
class ToolError < StandardError; end
|
||||
|
||||
class Toolchain
|
||||
attr_reader :openscad, :blender
|
||||
|
||||
def initialize(env: ENV)
|
||||
@env = env
|
||||
@openscad = discover("OPENSCAD", "openscad")
|
||||
@blender = discover("BLENDER", "blender")
|
||||
end
|
||||
|
||||
def check!
|
||||
missing = []
|
||||
missing << "OpenSCAD (`sudo apt-get install openscad` or set OPENSCAD)" unless openscad
|
||||
missing << "Blender (`sudo apt-get install blender` or set BLENDER)" unless blender
|
||||
return self if missing.empty?
|
||||
|
||||
raise ToolError, "Missing required tools:\n - #{missing.join("\n - ")}"
|
||||
end
|
||||
|
||||
def run!(*command, chdir: nil, env: {})
|
||||
options = chdir ? {chdir: chdir} : {}
|
||||
stdout, stderr, status = Open3.capture3(env, *command, **options)
|
||||
return [stdout, stderr] if status.success?
|
||||
|
||||
detail = [stdout, stderr].reject(&:empty?).join("\n").strip
|
||||
result = status.exitstatus || "signal #{status.termsig}"
|
||||
raise ToolError, "Command failed (#{result}): #{command.first}\n#{detail}"
|
||||
rescue Errno::ENOENT => e
|
||||
raise ToolError, "Cannot run #{command.first}: #{e.message}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def discover(env_name, command)
|
||||
override = @env[env_name]
|
||||
return File.expand_path(override) if override && File.executable?(override)
|
||||
|
||||
@env.fetch("PATH", "").split(File::PATH_SEPARATOR).each do |directory|
|
||||
candidate = File.join(directory, command)
|
||||
return candidate if File.file?(candidate) && File.executable?(candidate)
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user