Compare commits

...
12 Commits
Author SHA1 Message Date
David Dollar 185617dddc 0.9.2 2010-11-09 13:42:18 -05:00
David Dollar 9e4cc02827 upgrade dependencies 2010-11-09 13:41:18 -05:00
David Dollar 8b6e2481f4 ruby 1.8.6 compatibility 2010-11-09 13:41:08 -05:00
David Dollar 79f376368c 0.9.1 2010-11-03 15:00:59 -07:00
David Dollar 3576ae82af use process order to determine port assignments 2010-11-03 15:00:35 -07:00
David Dollar 303d54155f uniq the order for safety 2010-11-03 14:13:06 -07:00
David Dollar 2e36cbf045 0.9.0 2010-11-03 14:11:37 -07:00
David Dollar d3059ca563 always run processes in order they are defined in the procfile 2010-11-03 14:11:30 -07:00
David Dollar 9e42dfb253 change back to Procfile 2010-11-03 14:05:06 -07:00
David Dollar eca48170a5 fixing specs 2010-10-15 17:26:18 -07:00
David Dollar 86e3cd12dd using Psfile 2010-10-15 17:25:12 -07:00
David Dollar efd5a786f5 showing PORT here can be confusing 2010-10-15 16:29:40 -07:00
10 changed files with 69 additions and 56 deletions
+2 -2
View File
@@ -9,8 +9,8 @@ end
group :test do group :test do
gem 'fakefs', '~> 0.2.1' gem 'fakefs', '~> 0.2.1'
gem 'rcov', '~> 0.9.8' gem 'rcov', '~> 0.9.8'
gem 'rr', '~> 0.10.11' gem 'rr', '~> 1.0.2'
gem 'rspec', '~> 2.0.0.beta.19' gem 'rspec', '~> 2.0.0'
end end
gem 'term-ansicolor', '~> 1.0.5' gem 'term-ansicolor', '~> 1.0.5'
+3 -3
View File
@@ -18,7 +18,7 @@ GEM
hpricot (>= 0.8.2) hpricot (>= 0.8.2)
mustache (>= 0.7.0) mustache (>= 0.7.0)
rdiscount (>= 1.5.8) rdiscount (>= 1.5.8)
rr (0.10.11) rr (1.0.2)
rspec (2.0.0.beta.19) rspec (2.0.0.beta.19)
rspec-core (= 2.0.0.beta.19) rspec-core (= 2.0.0.beta.19)
rspec-expectations (= 2.0.0.beta.19) rspec-expectations (= 2.0.0.beta.19)
@@ -39,7 +39,7 @@ DEPENDENCIES
rake rake
rcov (~> 0.9.8) rcov (~> 0.9.8)
ronn ronn
rr (~> 0.10.11) rr (~> 1.0.2)
rspec (~> 2.0.0.beta.19) rspec (~> 2.0.0)
term-ansicolor (~> 1.0.5) term-ansicolor (~> 1.0.5)
thor (~> 0.13.6) thor (~> 0.13.6)
+1 -1
View File
@@ -1,6 +1,6 @@
module Foreman module Foreman
VERSION = "0.9.0.beta.1" VERSION = "0.9.2"
class AppDoesNotExist < Exception; end class AppDoesNotExist < Exception; end
+10 -10
View File
@@ -5,7 +5,7 @@ require "thor"
class Foreman::CLI < Thor class Foreman::CLI < Thor
class_option :pstypes, :type => :string, :aliases => "-f", :desc => "Default: Pstypes" class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
desc "start [PROCESS]", "Start the application, or a specific process" desc "start [PROCESS]", "Start the application, or a specific process"
@@ -14,7 +14,7 @@ class Foreman::CLI < Thor
:banner => '"alpha=5,bar=3"' :banner => '"alpha=5,bar=3"'
def start(process=nil) def start(process=nil)
check_pstypes! check_procfile!
if process if process
engine.execute(process, options) engine.execute(process, options)
@@ -33,7 +33,7 @@ class Foreman::CLI < Thor
:banner => '"alpha=5,bar=3"' :banner => '"alpha=5,bar=3"'
def export(format, location=nil) def export(format, location=nil)
check_pstypes! check_procfile!
formatter = case format formatter = case format
when "upstart" then Foreman::Export::Upstart when "upstart" then Foreman::Export::Upstart
@@ -49,16 +49,16 @@ class Foreman::CLI < Thor
private ###################################################################### private ######################################################################
def check_pstypes! def check_procfile!
error("#{pstypes} does not exist.") unless File.exist?(pstypes) error("#{procfile} does not exist.") unless File.exist?(procfile)
end end
def engine def engine
@engine ||= Foreman::Engine.new(pstypes) @engine ||= Foreman::Engine.new(procfile)
end end
def pstypes def procfile
options[:pstypes] || "Pstypes" options[:procfile] || "Procfile"
end end
private ###################################################################### private ######################################################################
@@ -68,8 +68,8 @@ private ######################################################################
exit 1 exit 1
end end
def pstypes_exists?(pstypes) def procfile_exists?(procfile)
File.exist?(pstypes) File.exist?(procfile)
end end
end end
+23 -10
View File
@@ -8,34 +8,47 @@ require "fileutils"
class Foreman::Engine class Foreman::Engine
attr_reader :pstypes attr_reader :procfile
attr_reader :directory attr_reader :directory
extend Term::ANSIColor extend Term::ANSIColor
COLORS = [ cyan, yellow, green, magenta, red ] COLORS = [ cyan, yellow, green, magenta, red ]
def initialize(pstypes) def initialize(procfile)
@pstypes = read_pstypes(pstypes) @procfile = read_procfile(procfile)
@directory = File.expand_path(File.dirname(pstypes)) @directory = File.expand_path(File.dirname(procfile))
end end
def processes def processes
@processes ||= begin @processes ||= begin
pstypes.split("\n").inject({}) do |hash, line| @order = []
procfile.split("\n").inject({}) do |hash, line|
next if line.strip == "" next if line.strip == ""
name, command = line.split(" ", 2) name, command = line.split(" ", 2)
process = Foreman::Process.new(name, command) process = Foreman::Process.new(name, command)
process.color = next_color process.color = next_color
@order << process.name
hash.update(process.name => process) hash.update(process.name => process)
end end
end end
end end
def process_order
processes
@order.uniq
end
def processes_in_order
process_order.map do |name|
[name, processes[name]]
end
end
def start(options={}) def start(options={})
proctitle "ruby: foreman master" proctitle "ruby: foreman master"
processes.each do |name, process| processes_in_order.each do |name, process|
fork process, options fork process, options
end end
@@ -56,7 +69,7 @@ class Foreman::Engine
def port_for(process, num, base_port=nil) def port_for(process, num, base_port=nil)
base_port ||= 5000 base_port ||= 5000
offset = processes.keys.sort.index(process.name) * 100 offset = processes_in_order.map { |p| p.first }.index(process.name) * 100
base_port.to_i + offset + num - 1 base_port.to_i + offset + num - 1
end end
@@ -78,7 +91,7 @@ private ######################################################################
run(process) run(process)
end end
info "started with pid #{pid}, PORT=#{port}", process info "started with pid #{pid}", process
running_processes[pid] = process running_processes[pid] = process
end end
@@ -144,8 +157,8 @@ private ######################################################################
$0 = title $0 = title
end end
def read_pstypes(pstypes) def read_procfile(procfile)
File.read(pstypes) File.read(procfile)
end end
def watch_for_termination def watch_for_termination
+10 -10
View File
@@ -1,4 +1,4 @@
foreman(1) -- manage Pstypes-based applications foreman(1) -- manage Psfile-based applications
================================================ ================================================
## SYNOPSIS ## SYNOPSIS
@@ -8,8 +8,8 @@ foreman(1) -- manage Pstypes-based applications
## DESCRIPTION ## DESCRIPTION
**Foreman** is a manager for Pstypes-based applications. Its aim is to **Foreman** is a manager for Psfile-based applications. Its aim is to
abstract away the details of the Pstypes format, and allow you to either run abstract away the details of the Psfile format, and allow you to either run
your application directly or export it to some other process management your application directly or export it to some other process management
format. format.
@@ -18,7 +18,7 @@ format.
`foreman start` is used to run your application directly from the command line. `foreman start` is used to run your application directly from the command line.
If no additional parameters are passed, foreman will run one instance of each If no additional parameters are passed, foreman will run one instance of each
type of process defined in your Pstypes. type of process defined in your Psfile.
If a parameter is passed, foreman will run one instance of the specified If a parameter is passed, foreman will run one instance of the specified
application type. application type.
@@ -66,8 +66,8 @@ The following options control how the application is run:
These options control all modes of foreman's operation. These options control all modes of foreman's operation.
* `-f`, `--pstypes`: * `-f`, `--psfile`:
Specify an alternate location for the application's Pstypes. This file's Specify an alternate location for the application's Psfile. This file's
containing directory will be assumed to be the root directory of the containing directory will be assumed to be the root directory of the
application. application.
@@ -99,9 +99,9 @@ will be structured to make the following commands valid:
`restart appname-processname-3` `restart appname-processname-3`
## PSTYPES ## PSFILE
A Pstyes file should contain both a name for the process and the command used A Psfile should contain both a name for the process and the command used
to run it. to run it.
web bundle exec thin start web bundle exec thin start
@@ -117,9 +117,9 @@ Export the application in upstart format:
$ foreman export upstart /etc/init $ foreman export upstart /etc/init
Run one process type from the application defined in a specific Pstypes: Run one process type from the application defined in a specific Psfile:
$ foreman start alpha -p ~/app/Pstypes $ foreman start alpha -p ~/myapp/Psfile
## COPYRIGHT ## COPYRIGHT
+8 -8
View File
@@ -5,17 +5,17 @@ describe "Foreman::CLI" do
subject { Foreman::CLI.new } subject { Foreman::CLI.new }
describe "start" do describe "start" do
describe "with a non-existent Pstypes" do describe "with a non-existent Procfile" do
it "prints an error" do it "prints an error" do
mock_error(subject, "Pstypes does not exist.") do mock_error(subject, "Procfile does not exist.") do
dont_allow.instance_of(Foreman::Engine).start dont_allow.instance_of(Foreman::Engine).start
subject.start subject.start
end end
end end
end end
describe "with a Pstypes" do describe "with a Procfile" do
before(:each) { write_pstypes } before(:each) { write_procfile }
it "runs successfully" do it "runs successfully" do
dont_allow(subject).error dont_allow(subject).error
@@ -26,17 +26,17 @@ describe "Foreman::CLI" do
end end
describe "export" do describe "export" do
describe "with a non-existent Pstypes" do describe "with a non-existent Procfile" do
it "prints an error" do it "prints an error" do
mock_error(subject, "Pstypes does not exist.") do mock_error(subject, "Procfile does not exist.") do
dont_allow.instance_of(Foreman::Engine).export dont_allow.instance_of(Foreman::Engine).export
subject.export("testapp") subject.export("testapp")
end end
end end
end end
describe "with a Pstypes" do describe "with a Procfile" do
before(:each) { write_pstypes } before(:each) { write_procfile }
describe "with an invalid formatter" do describe "with an invalid formatter" do
it "prints an error" do it "prints an error" do
+10 -10
View File
@@ -2,18 +2,18 @@ require "spec_helper"
require "foreman/engine" require "foreman/engine"
describe "Foreman::Engine" do describe "Foreman::Engine" do
subject { Foreman::Engine.new("Pstypes") } subject { Foreman::Engine.new("Procfile") }
describe "initialize" do describe "initialize" do
describe "without an existing Pstypes" do describe "without an existing Procfile" do
it "raises an error" do it "raises an error" do
lambda { subject }.should raise_error lambda { subject }.should raise_error
end end
end end
describe "with a Pstypes" do describe "with a Procfile" do
it "reads the processes" do it "reads the processes" do
write_pstypes write_procfile
subject.processes["alpha"].command.should == "./alpha" subject.processes["alpha"].command.should == "./alpha"
subject.processes["bravo"].command.should == "./bravo" subject.processes["bravo"].command.should == "./bravo"
end end
@@ -22,7 +22,7 @@ describe "Foreman::Engine" do
describe "start" do describe "start" do
it "forks the processes" do it "forks the processes" do
write_pstypes write_procfile
mock(subject).fork(subject.processes["alpha"], {}) mock(subject).fork(subject.processes["alpha"], {})
mock(subject).fork(subject.processes["bravo"], {}) mock(subject).fork(subject.processes["bravo"], {})
mock(subject).watch_for_termination mock(subject).watch_for_termination
@@ -30,10 +30,10 @@ describe "Foreman::Engine" do
end end
it "handles concurrency" do it "handles concurrency" do
write_pstypes write_procfile
mock(subject).fork_individual(subject.processes["alpha"], 5000) mock(subject).fork_individual(subject.processes["alpha"], 1, 5000)
mock(subject).fork_individual(subject.processes["alpha"], 5001) mock(subject).fork_individual(subject.processes["alpha"], 2, 5001)
mock(subject).fork_individual(subject.processes["bravo"], 5100) mock(subject).fork_individual(subject.processes["bravo"], 1, 5100)
mock(subject).watch_for_termination mock(subject).watch_for_termination
subject.start(:concurrency => "alpha=2") subject.start(:concurrency => "alpha=2")
end end
@@ -41,7 +41,7 @@ describe "Foreman::Engine" do
describe "execute" do describe "execute" do
it "runs the processes" do it "runs the processes" do
write_pstypes write_procfile
mock(subject).fork(subject.processes["alpha"], {}) mock(subject).fork(subject.processes["alpha"], {})
mock(subject).watch_for_termination mock(subject).watch_for_termination
subject.execute("alpha") subject.execute("alpha")
+2 -2
View File
@@ -24,8 +24,8 @@ def write_foreman_config(app)
end end
end end
def write_pstypes(pstypes="Pstypes") def write_procfile(procfile="Procfile")
File.open(pstypes, "w") do |file| File.open(procfile, "w") do |file|
file.puts "alpha ./alpha" file.puts "alpha ./alpha"
file.puts "bravo ./bravo" file.puts "bravo ./bravo"
end end