Skip to content

Commit

Permalink
foreman run can run things from the Procfile like heroku run.
Browse files Browse the repository at this point in the history
  • Loading branch information
danp committed Sep 14, 2012
1 parent 6c04dab commit e99f317
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
11 changes: 10 additions & 1 deletion lib/foreman/cli.rb
Expand Up @@ -75,10 +75,19 @@ def check


def run(*args) def run(*args)
load_environment! load_environment!

if File.exist?(procfile)
engine.load_procfile(procfile)
end

pid = fork do pid = fork do
begin begin
engine.env.each { |k,v| ENV[k] = v } engine.env.each { |k,v| ENV[k] = v }
exec args.shelljoin if args.size == 1 && process = engine.process(args.first)
process.exec(:env => engine.env)
else
exec args.shelljoin
end
rescue Errno::EACCES rescue Errno::EACCES
error "not executable: #{args.first}" error "not executable: #{args.first}"
rescue Errno::ENOENT rescue Errno::ENOENT
Expand Down
39 changes: 32 additions & 7 deletions lib/foreman/process.rb
Expand Up @@ -21,6 +21,21 @@ def initialize(command, options={})
@options[:env] ||= {} @options[:env] ||= {}
end 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+ # Run a +Process+
# #
# @param [Hash] options # @param [Hash] options
Expand All @@ -31,16 +46,12 @@ def initialize(command, options={})
# @returns [Fixnum] pid The +pid+ of the process # @returns [Fixnum] pid The +pid+ of the process
# #
def run(options={}) def run(options={})
env = options[:env] ? @options[:env].merge(options[:env]) : @options[:env] env = @options[:env].merge(options[:env] || {})
output = options[:output] || $stdout output = options[:output] || $stdout


if Foreman.windows? if Foreman.windows?
Dir.chdir(cwd) do Dir.chdir(cwd) do
expanded_command = command.dup Process.spawn env, expanded_command(env), :out => output, :err => output
env.each do |key, val|
expanded_command.gsub!("$#{key}", val)
end
Process.spawn env, expanded_command, :out => output, :err => output
end end
elsif Foreman.jruby? elsif Foreman.jruby?
require "posix/spawn" require "posix/spawn"
Expand All @@ -52,14 +63,28 @@ def run(options={})
$stderr.reopen output $stderr.reopen output
env.each { |k,v| ENV[k] = v } env.each { |k,v| ENV[k] = v }
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}" wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
exec wrapped_command Kernel.exec wrapped_command
end end
else else
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}" wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
Process.spawn env, wrapped_command, :out => output, :err => output Process.spawn env, wrapped_command, :out => output, :err => output
end end
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+ # Send a signal to this +Process+
# #
# @param [String] signal The signal to send # @param [String] signal The signal to send
Expand Down
4 changes: 4 additions & 0 deletions spec/foreman/cli_spec.rb
Expand Up @@ -73,6 +73,10 @@
forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n" forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
end end


it "can run a command from the Procfile" do
forked_foreman("run -f #{resource_path("Procfile")} test").should == "testing\n"
end

it "exits with the same exit code as the command" do it "exits with the same exit code as the command" do
fork_and_get_exitstatus("run echo 1").should == 0 fork_and_get_exitstatus("run echo 1").should == 0
fork_and_get_exitstatus("run date 'invalid_date'").should == 1 fork_and_get_exitstatus("run date 'invalid_date'").should == 1
Expand Down

0 comments on commit e99f317

Please sign in to comment.