Compare commits

..

21 Commits

Author SHA1 Message Date
David Dollar
2804316bbb 0.10.1 2010-12-22 13:56:13 -05:00
David Dollar
26859c2ec2 dont need a log dir 2010-12-22 13:55:51 -05:00
David Dollar
27152b0e76 docs pedantry 2010-12-13 18:13:11 -05:00
David Dollar
160945b499 doc the rake task so it shows in -T 2010-12-13 18:12:28 -05:00
David Dollar
f2be566051 update man page 2010-12-13 18:11:36 -05:00
David Dollar
a504a59f0b add a colon to the mock Procfile 2010-12-13 18:08:40 -05:00
David Dollar
e6b61801b1 0.10.0 2010-12-13 18:05:41 -05:00
David Dollar
dc231f072b allow optional colon after process name 2010-12-13 18:05:06 -05:00
David Dollar
b77b23b306 declare license 2010-11-16 17:47:53 -05:00
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
12 changed files with 82 additions and 64 deletions

View File

@@ -9,8 +9,8 @@ end
group :test do
gem 'fakefs', '~> 0.2.1'
gem 'rcov', '~> 0.9.8'
gem 'rr', '~> 0.10.11'
gem 'rspec', '~> 2.0.0.beta.19'
gem 'rr', '~> 1.0.2'
gem 'rspec', '~> 2.0.0'
end
gem 'term-ansicolor', '~> 1.0.5'

View File

@@ -18,7 +18,7 @@ GEM
hpricot (>= 0.8.2)
mustache (>= 0.7.0)
rdiscount (>= 1.5.8)
rr (0.10.11)
rr (1.0.2)
rspec (2.0.0.beta.19)
rspec-core (= 2.0.0.beta.19)
rspec-expectations (= 2.0.0.beta.19)
@@ -39,7 +39,7 @@ DEPENDENCIES
rake
rcov (~> 0.9.8)
ronn
rr (~> 0.10.11)
rspec (~> 2.0.0.beta.19)
rr (~> 1.0.2)
rspec (~> 2.0.0)
term-ansicolor (~> 1.0.5)
thor (~> 0.13.6)

View File

@@ -1,4 +1,9 @@
Foreman
=======
# Foreman
## Manual
See the [man page](http://ddollar.github.com/foreman) for usage.
## License
MIT

View File

@@ -37,6 +37,7 @@ task :man do
sh "git commit -m 'update readme' || echo 'nothing to commit'"
end
desc "Generate the Github docs"
task :pages => :man do
sh %{
cp man/foreman.1.html /tmp/foreman.1.html

View File

@@ -1,6 +1,6 @@
module Foreman
VERSION = "0.9.0.beta.1"
VERSION = "0.10.1"
class AppDoesNotExist < Exception; end

View File

@@ -5,7 +5,7 @@ require "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"
@@ -14,7 +14,7 @@ class Foreman::CLI < Thor
:banner => '"alpha=5,bar=3"'
def start(process=nil)
check_pstypes!
check_procfile!
if process
engine.execute(process, options)
@@ -33,7 +33,7 @@ class Foreman::CLI < Thor
:banner => '"alpha=5,bar=3"'
def export(format, location=nil)
check_pstypes!
check_procfile!
formatter = case format
when "upstart" then Foreman::Export::Upstart
@@ -49,16 +49,16 @@ class Foreman::CLI < Thor
private ######################################################################
def check_pstypes!
error("#{pstypes} does not exist.") unless File.exist?(pstypes)
def check_procfile!
error("#{procfile} does not exist.") unless File.exist?(procfile)
end
def engine
@engine ||= Foreman::Engine.new(pstypes)
@engine ||= Foreman::Engine.new(procfile)
end
def pstypes
options[:pstypes] || "Pstypes"
def procfile
options[:procfile] || "Procfile"
end
private ######################################################################
@@ -68,8 +68,8 @@ private ######################################################################
exit 1
end
def pstypes_exists?(pstypes)
File.exist?(pstypes)
def procfile_exists?(procfile)
File.exist?(procfile)
end
end

View File

@@ -8,34 +8,47 @@ require "fileutils"
class Foreman::Engine
attr_reader :pstypes
attr_reader :procfile
attr_reader :directory
extend Term::ANSIColor
COLORS = [ cyan, yellow, green, magenta, red ]
def initialize(pstypes)
@pstypes = read_pstypes(pstypes)
@directory = File.expand_path(File.dirname(pstypes))
def initialize(procfile)
@procfile = read_procfile(procfile)
@directory = File.expand_path(File.dirname(procfile))
end
def processes
@processes ||= begin
pstypes.split("\n").inject({}) do |hash, line|
@order = []
procfile.split("\n").inject({}) do |hash, line|
next if line.strip == ""
name, command = line.split(" ", 2)
name, command = line.split(/:? +/, 2)
process = Foreman::Process.new(name, command)
process.color = next_color
@order << process.name
hash.update(process.name => process)
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={})
proctitle "ruby: foreman master"
processes.each do |name, process|
processes_in_order.each do |name, process|
fork process, options
end
@@ -56,7 +69,7 @@ class Foreman::Engine
def port_for(process, num, base_port=nil)
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
end
@@ -78,16 +91,15 @@ private ######################################################################
run(process)
end
info "started with pid #{pid}, PORT=#{port}", process
info "started with pid #{pid}", process
running_processes[pid] = process
end
def run(process, log_to_file=true)
def run(process)
proctitle "ruby: foreman #{process.name}"
begin
Dir.chdir directory do
FileUtils.mkdir_p "log"
command = process.command
PTY.spawn("#{process.command} 2>&1") do |stdin, stdout, pid|
@@ -144,8 +156,8 @@ private ######################################################################
$0 = title
end
def read_pstypes(pstypes)
File.read(pstypes)
def read_procfile(procfile)
File.read(procfile)
end
def watch_for_termination

View File

@@ -1,4 +1,4 @@
foreman(1) -- manage Pstypes-based applications
foreman(1) -- manage Procfile-based applications
================================================
## SYNOPSIS
@@ -8,8 +8,8 @@ foreman(1) -- manage Pstypes-based applications
## DESCRIPTION
**Foreman** is a manager for Pstypes-based applications. Its aim is to
abstract away the details of the Pstypes format, and allow you to either run
**Foreman** is a manager for Procfile-based applications. Its aim is to
abstract away the details of the Procfile format, and allow you to either run
your application directly or export it to some other process management
format.
@@ -18,7 +18,7 @@ format.
`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
type of process defined in your Pstypes.
type of process defined in your Procfile.
If a parameter is passed, foreman will run one instance of the specified
application type.
@@ -66,8 +66,8 @@ The following options control how the application is run:
These options control all modes of foreman's operation.
* `-f`, `--pstypes`:
Specify an alternate location for the application's Pstypes. This file's
* `-f`, `--procfile`:
Specify an alternate location for the application's Procfile. This file's
containing directory will be assumed to be the root directory of the
application.
@@ -99,13 +99,13 @@ will be structured to make the following commands valid:
`restart appname-processname-3`
## PSTYPES
## PROCFILE
A Pstyes file should contain both a name for the process and the command used
A Procfile should contain both a name for the process and the command used
to run it.
web bundle exec thin start
job bundle exec rake jobs:work
web: bundle exec thin start
job: bundle exec rake jobs:work
## EXAMPLES
@@ -117,9 +117,9 @@ Export the application in upstart format:
$ 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 Procfile:
$ foreman start alpha -p ~/app/Pstypes
$ foreman start alpha -p ~/myapp/Procfile
## COPYRIGHT

View File

@@ -5,17 +5,17 @@ describe "Foreman::CLI" do
subject { Foreman::CLI.new }
describe "start" do
describe "with a non-existent Pstypes" do
describe "with a non-existent Procfile" 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
subject.start
end
end
end
describe "with a Pstypes" do
before(:each) { write_pstypes }
describe "with a Procfile" do
before(:each) { write_procfile }
it "runs successfully" do
dont_allow(subject).error
@@ -26,17 +26,17 @@ describe "Foreman::CLI" do
end
describe "export" do
describe "with a non-existent Pstypes" do
describe "with a non-existent Procfile" 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
subject.export("testapp")
end
end
end
describe "with a Pstypes" do
before(:each) { write_pstypes }
describe "with a Procfile" do
before(:each) { write_procfile }
describe "with an invalid formatter" do
it "prints an error" do

View File

@@ -2,18 +2,18 @@ require "spec_helper"
require "foreman/engine"
describe "Foreman::Engine" do
subject { Foreman::Engine.new("Pstypes") }
subject { Foreman::Engine.new("Procfile") }
describe "initialize" do
describe "without an existing Pstypes" do
describe "without an existing Procfile" do
it "raises an error" do
lambda { subject }.should raise_error
end
end
describe "with a Pstypes" do
describe "with a Procfile" do
it "reads the processes" do
write_pstypes
write_procfile
subject.processes["alpha"].command.should == "./alpha"
subject.processes["bravo"].command.should == "./bravo"
end
@@ -22,7 +22,7 @@ describe "Foreman::Engine" do
describe "start" do
it "forks the processes" do
write_pstypes
write_procfile
mock(subject).fork(subject.processes["alpha"], {})
mock(subject).fork(subject.processes["bravo"], {})
mock(subject).watch_for_termination
@@ -30,10 +30,10 @@ describe "Foreman::Engine" do
end
it "handles concurrency" do
write_pstypes
mock(subject).fork_individual(subject.processes["alpha"], 5000)
mock(subject).fork_individual(subject.processes["alpha"], 5001)
mock(subject).fork_individual(subject.processes["bravo"], 5100)
write_procfile
mock(subject).fork_individual(subject.processes["alpha"], 1, 5000)
mock(subject).fork_individual(subject.processes["alpha"], 2, 5001)
mock(subject).fork_individual(subject.processes["bravo"], 1, 5100)
mock(subject).watch_for_termination
subject.start(:concurrency => "alpha=2")
end
@@ -41,7 +41,7 @@ describe "Foreman::Engine" do
describe "execute" do
it "runs the processes" do
write_pstypes
write_procfile
mock(subject).fork(subject.processes["alpha"], {})
mock(subject).watch_for_termination
subject.execute("alpha")

View File

@@ -24,10 +24,10 @@ def write_foreman_config(app)
end
end
def write_pstypes(pstypes="Pstypes")
File.open(pstypes, "w") do |file|
def write_procfile(procfile="Procfile")
File.open(procfile, "w") do |file|
file.puts "alpha ./alpha"
file.puts "bravo ./bravo"
file.puts "bravo: ./bravo"
end
end