8ee7b7afdf
It's better to not force the use of a package manager. Better to add it to the global RUBYOPT if needed. Also, this fixes a dependency issue when using the .deb package (rubygems1.9.1 is not required, and should not be).
126 lines
3.0 KiB
Ruby
126 lines
3.0 KiB
Ruby
require "foreman"
|
|
|
|
class Foreman::Process
|
|
|
|
attr_reader :command
|
|
attr_reader :env
|
|
|
|
# Create a Process
|
|
#
|
|
# @param [String] command The command to run
|
|
# @param [Hash] options
|
|
#
|
|
# @option options [String] :cwd (./) Change to this working directory before executing the process
|
|
# @option options [Hash] :env ({}) Environment variables to set for this process
|
|
#
|
|
def initialize(command, options={})
|
|
@command = command
|
|
@options = options.dup
|
|
|
|
@options[:env] ||= {}
|
|
end
|
|
|
|
# Get environment-expanded command for a +Process+
|
|
#
|
|
# @param [Hash] custom_env ({}) Environment variables to merge with defaults
|
|
#
|
|
# @return [String] The expanded command
|
|
#
|
|
def expanded_command(custom_env={})
|
|
env = @options[:env].merge(custom_env)
|
|
expanded_command = command.dup
|
|
env.each do |key, val|
|
|
expanded_command.gsub!("$#{key}", val)
|
|
end
|
|
expanded_command
|
|
end
|
|
|
|
# Run a +Process+
|
|
#
|
|
# @param [Hash] options
|
|
#
|
|
# @option options :env ({}) Environment variables to set for this execution
|
|
# @option options :output ($stdout) The output stream
|
|
#
|
|
# @returns [Fixnum] pid The +pid+ of the process
|
|
#
|
|
def run(options={})
|
|
env = @options[:env].merge(options[:env] || {})
|
|
output = options[:output] || $stdout
|
|
|
|
if Foreman.windows?
|
|
Dir.chdir(cwd) do
|
|
Process.spawn env, expanded_command(env), :out => output, :err => output
|
|
end
|
|
elsif Foreman.jruby?
|
|
require "posix/spawn"
|
|
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
|
|
POSIX::Spawn.spawn env, wrapped_command, :out => output, :err => output
|
|
elsif Foreman.ruby_18?
|
|
fork do
|
|
$stdout.reopen output
|
|
$stderr.reopen output
|
|
env.each { |k,v| ENV[k] = v }
|
|
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
|
|
Kernel.exec wrapped_command
|
|
end
|
|
else
|
|
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
|
|
Process.spawn env, wrapped_command, :out => output, :err => output
|
|
end
|
|
end
|
|
|
|
# Exec a +Process+
|
|
#
|
|
# @param [Hash] options
|
|
#
|
|
# @option options :env ({}) Environment variables to set for this execution
|
|
#
|
|
# @return Does not return
|
|
def exec(options={})
|
|
env = @options[:env].merge(options[:env] || {})
|
|
env.each { |k, v| ENV[k] = v }
|
|
Dir.chdir(cwd)
|
|
Kernel.exec expanded_command(env)
|
|
end
|
|
|
|
# Send a signal to this +Process+
|
|
#
|
|
# @param [String] signal The signal to send
|
|
#
|
|
def kill(signal)
|
|
if Foreman.windows?
|
|
pid && Process.kill(signal, pid)
|
|
else
|
|
pid && Process.kill("-#{signal}", pid)
|
|
end
|
|
rescue Errno::ESRCH
|
|
false
|
|
end
|
|
|
|
# Test whether or not this +Process+ is still running
|
|
#
|
|
# @returns [Boolean]
|
|
#
|
|
def alive?
|
|
kill(0)
|
|
end
|
|
|
|
# Test whether or not this +Process+ has terminated
|
|
#
|
|
# @returns [Boolean]
|
|
#
|
|
def dead?
|
|
!alive?
|
|
end
|
|
|
|
# Returns the working directory for this +Process+
|
|
#
|
|
# @returns [String]
|
|
#
|
|
def cwd
|
|
File.expand_path(@options[:cwd] || ".")
|
|
end
|
|
|
|
end
|