lib/foreman/engine.rb in foreman-0.2.0 vs lib/foreman/engine.rb in foreman-0.3.0
- old
+ new
@@ -1,24 +1,31 @@
require "foreman"
require "foreman/process"
+require "pty"
require "tempfile"
+require "term/ansicolor"
class Foreman::Engine
attr_reader :procfile
attr_reader :directory
+ extend Term::ANSIColor
+
+ COLORS = [ cyan, yellow, green, magenta, on_blue ]
+
def initialize(procfile)
@procfile = read_procfile(procfile)
@directory = File.expand_path(File.dirname(procfile))
end
def processes
@processes ||= begin
procfile.split("\n").inject({}) do |hash, line|
next if line.strip == ""
process = Foreman::Process.new(*line.split(" ", 2))
+ process.color = next_color
hash.update(process.name => process)
end
end
end
@@ -30,11 +37,11 @@
end
trap("TERM") { kill_and_exit("TERM") }
trap("INT") { kill_and_exit("INT") }
- run_loop
+ watch_for_termination
end
def screen
tempfile = Tempfile.new("foreman")
tempfile.puts "sessionname foreman"
@@ -67,27 +74,33 @@
proctitle "ruby: foreman #{process.name}"
Dir.chdir directory do
FileUtils.mkdir_p "log"
command = process.command
- command << " >>log/#{process.name}.log 2>&1" if log_to_file
- system command
- exit $?.exitstatus || 255
+
+ PTY.spawn("#{process.command} 2>&1") do |stdin, stdout, pid|
+ until stdin.eof?
+ info stdin.gets, process
+ end
+ end
end
end
def kill_and_exit(signal="TERM")
info "termination requested"
running_processes.each do |pid, process|
- info "killing pid #{pid}", process
+ info "killing #{process.name} in pid #{pid}"
Process.kill(signal, pid)
end
exit 0
end
def info(message, process=nil)
- puts "[foreman] [#{Time.now.utc}] [#{process ? process.name : "system"}] #{message}"
+ print process.color if process
+ print "[#{Time.now.strftime("%H:%M:%S")}] [#{process ? process.name : "system"}] #{message.chomp}"
+ print Term::ANSIColor.reset
+ puts
end
def print_info
info "currently running processes:"
running_processes.each do |pid, process|
@@ -101,19 +114,23 @@
def read_procfile(procfile)
File.read(procfile)
end
- def run_loop
- while true
- pid, status = Process.wait2
- process = running_processes.delete(pid)
- info "exited with code #{status}", process
- fork process
- end
+ def watch_for_termination
+ pid, status = Process.wait2
+ process = running_processes.delete(pid)
+ info "process terminated", process
+ kill_and_exit
end
def running_processes
@running_processes ||= {}
+ end
+
+ def next_color
+ @current_color ||= -1
+ @current_color += 1
+ @current_color >= COLORS.length ? "" : COLORS[@current_color]
end
end