Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

127 lines (110 sloc) 3.213 kB
module Cocaine
class CommandLine
class << self
attr_accessor :logger
def path
@supplemental_path
end
def path=(supplemental_path)
@supplemental_path = supplemental_path
@supplemental_environment ||= {}
@supplemental_environment['PATH'] = [ENV['PATH'], *supplemental_path].join(File::PATH_SEPARATOR)
end
def posix_spawn_available?
@posix_spawn_available ||= begin
require 'posix/spawn'
true
rescue LoadError => e
false
end
end
def environment
@supplemental_environment ||= {}
end
end
@environment = {}
attr_reader :exit_status, :runner
def initialize(binary, params = "", options = {})
@binary = binary.dup
@params = params.dup
@options = options.dup
@logger = @options.delete(:logger) || self.class.logger
@swallow_stderr = @options.delete(:swallow_stderr)
@expected_outcodes = @options.delete(:expected_outcodes)
@expected_outcodes ||= [0]
@runner = best_runner
end
def command
cmd = []
cmd << @binary
cmd << interpolate(@params, @options)
cmd << bit_bucket if @swallow_stderr
cmd.join(" ").strip
end
def run
output = ''
begin
@logger.info("\e[32mCommand\e[0m :: #{command}") if @logger
output = execute(command)
rescue Errno::ENOENT
raise Cocaine::CommandNotFoundError
ensure
@exit_status = $?.exitstatus
end
if $?.exitstatus == 127
raise Cocaine::CommandNotFoundError
end
unless @expected_outcodes.include?($?.exitstatus)
raise Cocaine::ExitStatusError, "Command '#{command}' returned #{$?.exitstatus}. Expected #{@expected_outcodes.join(", ")}"
end
output
end
def unix?
(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/).nil?
end
private
def execute(command)
runner.call(command, self.class.environment)
end
def best_runner
return PosixRunner.new if self.class.posix_spawn_available?
return ProcessRunner.new if Process.respond_to?(:spawn)
BackticksRunner.new
end
def interpolate(pattern, vars)
# interpolates :variables and :{variables}
pattern.gsub(%r#:(?:\w+|\{\w+\})#) do |match|
key = match[1..-1]
key = key[1..-2] if key[0,1] == '{'
if invalid_variables.include?(key)
raise InterpolationError,
"Interpolation of #{key} isn't allowed."
end
interpolation(vars, key) || match
end
end
def invalid_variables
%w(expected_outcodes swallow_stderr logger)
end
def interpolation(vars, key)
if vars.key?(key.to_sym)
shell_quote(vars[key.to_sym])
end
end
def shell_quote(string)
return "" if string.nil?
if unix?
if string.empty?
"''"
else
string.split("'").map{|m| "'#{m}'" }.join("\\'")
end
else
%{"#{string}"}
end
end
def bit_bucket
unix? ? "2>/dev/null" : "2>NUL"
end
end
end
Jump to Line
Something went wrong with that request. Please try again.