Compare commits

...

19 Commits

Author SHA1 Message Date
David Dollar
35474ad1a5 0.11.1 2011-03-08 12:17:44 -05:00
David Dollar
fc5e86b269 describe .foreman in man page 2011-03-08 12:17:03 -05:00
David Dollar
7f8ca7da39 support .foreman file for default options 2011-03-08 12:14:48 -05:00
David Dollar
31239d98d0 ignore ctags file 2011-01-30 16:18:12 -08:00
David Dollar
472395edf8 0.11.0 2011-01-27 16:15:26 -08:00
David Dollar
6b7d5e5161 deprecate colon-less syntax, add check command 2011-01-27 16:14:43 -08:00
David Dollar
977c80ffdd add json export 2011-01-27 16:13:44 -08:00
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
16 changed files with 156 additions and 40 deletions

2
.gitignore vendored
View File

@@ -5,3 +5,5 @@ man/*.?
man/*.html
man/*.markdown
pkg
tags

View File

@@ -9,9 +9,10 @@ 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 'json', '~> 1.5.1'
gem 'term-ansicolor', '~> 1.0.5'
gem 'thor', '~> 0.13.6'

View File

@@ -4,6 +4,7 @@ GEM
diff-lcs (1.1.2)
fakefs (0.2.1)
hpricot (0.8.2)
json (1.5.1)
mime-types (1.16)
mustache (0.11.2)
parka (0.3.1)
@@ -18,15 +19,17 @@ GEM
hpricot (>= 0.8.2)
mustache (>= 0.7.0)
rdiscount (>= 1.5.8)
rr (0.10.11)
rspec (2.0.0.beta.19)
rspec-core (= 2.0.0.beta.19)
rspec-expectations (= 2.0.0.beta.19)
rspec-mocks (= 2.0.0.beta.19)
rspec-core (2.0.0.beta.19)
rspec-expectations (2.0.0.beta.19)
rr (1.0.2)
rspec (2.0.1)
rspec-core (~> 2.0.1)
rspec-expectations (~> 2.0.1)
rspec-mocks (~> 2.0.1)
rspec-core (2.0.1)
rspec-expectations (2.0.1)
diff-lcs (>= 1.1.2)
rspec-mocks (2.0.0.beta.19)
rspec-mocks (2.0.1)
rspec-core (~> 2.0.1)
rspec-expectations (~> 2.0.1)
term-ansicolor (1.0.5)
thor (0.13.8)
@@ -35,11 +38,12 @@ PLATFORMS
DEPENDENCIES
fakefs (~> 0.2.1)
json (~> 1.5.1)
parka
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

@@ -25,7 +25,7 @@ end
Rspec::Core::RakeTask.new("rcov:build") do |t|
t.pattern = 'spec/**/*_spec.rb'
t.rcov = true
t.rcov_opts = [ "--exclude", Gem.default_dir , "--exclude", "spec" ]
t.rcov_opts = [ "--exclude", ".bundle", "--exclude", "spec" ]
end
desc 'Build the manual'
@@ -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,2 +1,2 @@
ticker ./ticker $PORT
error ./error
ticker: ./ticker $PORT
error : ./error

View File

@@ -0,0 +1,2 @@
ticker ./ticker $PORT
error ./error

View File

@@ -1,6 +1,6 @@
module Foreman
VERSION = "0.9.1"
VERSION = "0.11.1"
class AppDoesNotExist < Exception; end

View File

@@ -36,8 +36,9 @@ class Foreman::CLI < Thor
check_procfile!
formatter = case format
when "upstart" then Foreman::Export::Upstart
when "json" then Foreman::Export::JSON
when "inittab" then Foreman::Export::Inittab
when "upstart" then Foreman::Export::Upstart
else error "Unknown export format: #{format}."
end
@@ -47,6 +48,14 @@ class Foreman::CLI < Thor
error ex.message
end
desc "check", "Validate your application's Procfile"
def check
processes = engine.processes_in_order.map { |p| p.first }
error "no processes defined" unless processes.length > 0
display "valid procfile detected (#{processes.join(', ')})"
end
private ######################################################################
def check_procfile!
@@ -61,7 +70,9 @@ private ######################################################################
options[:procfile] || "Procfile"
end
private ######################################################################
def display(message)
puts message
end
def error(message)
puts "ERROR: #{message}"
@@ -72,4 +83,11 @@ private ######################################################################
File.exist?(procfile)
end
def options
original_options = super
return original_options unless File.exists?(".foreman")
defaults = YAML::load_file(".foreman")
Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
end
end

View File

@@ -25,7 +25,11 @@ class Foreman::Engine
@order = []
procfile.split("\n").inject({}) do |hash, line|
next if line.strip == ""
name, command = line.split(" ", 2)
name, command = line.split(/ *: +/, 2)
unless command
warn_deprecated_procfile!
name, command = line.split(/ +/, 2)
end
process = Foreman::Process.new(name, command)
process.color = next_color
@order << process.name
@@ -69,7 +73,7 @@ class Foreman::Engine
def port_for(process, num, base_port=nil)
base_port ||= 5000
offset = processes_in_order.map(&:first).index(process.name) * 100
offset = processes_in_order.map { |p| p.first }.index(process.name) * 100
base_port.to_i + offset + num - 1
end
@@ -95,12 +99,11 @@ private ######################################################################
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|
@@ -179,4 +182,12 @@ private ######################################################################
@current_color >= COLORS.length ? "" : COLORS[@current_color]
end
def warn_deprecated_procfile!
return if @already_warned_deprecated
@already_warned_deprecated = true
puts "!!! This format of Procfile is deprecated, and will not work starting in v0.12"
puts "!!! Use a colon to separate the process name from the command"
puts "!!! e.g. web: thin start"
end
end

View File

@@ -4,5 +4,6 @@ module Foreman::Export
class Exception < ::Exception; end
end
require "foreman/export/upstart"
require "foreman/export/json"
require "foreman/export/inittab"
require "foreman/export/upstart"

View File

@@ -0,0 +1,13 @@
require "foreman/export/base"
require "json"
class Foreman::Export::JSON < Foreman::Export::Base
def export(fname=nil, options={})
processes = engine.processes.values.inject({}) do |hash, process|
hash.update(process.name => { "command" => process.command })
end
puts processes.to_json
end
end

View File

@@ -1,4 +1,4 @@
foreman(1) -- manage Psfile-based applications
foreman(1) -- manage Procfile-based applications
================================================
## SYNOPSIS
@@ -8,8 +8,8 @@ foreman(1) -- manage Psfile-based applications
## DESCRIPTION
**Foreman** is a manager for Psfile-based applications. Its aim is to
abstract away the details of the Psfile 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 Psfile.
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`, `--psfile`:
Specify an alternate location for the application's Psfile. 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.
@@ -75,10 +75,18 @@ These options control all modes of foreman's operation.
foreman currently supports the following output formats:
* json
* inittab
* upstart
## JSON EXPORT
Will export your processes as JSON:
{ "web": { "command": "bundle exec thin start" } }
## INITTAB EXPORT
Will export a chunk of inittab-compatible configuration:
@@ -99,13 +107,26 @@ will be structured to make the following commands valid:
`restart appname-processname-3`
## PSFILE
## PROCFILE
A Psfile 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
You can validate your Procfile format using the `check` command
$ foreman check
## DEFAULT OPTIONS
If a `.foreman` file exists in the current directory, default options will
be read from it. This file should be in YAML format with the long option
name as keys. Example:
concurrency: alpha=0
port: 15000
## EXAMPLES
@@ -117,9 +138,9 @@ Export the application in upstart format:
$ foreman export upstart /etc/init
Run one process type from the application defined in a specific Psfile:
Run one process type from the application defined in a specific Procfile:
$ foreman start alpha -p ~/myapp/Psfile
$ foreman start alpha -p ~/myapp/Procfile
## COPYRIGHT

View File

@@ -58,4 +58,27 @@ describe "Foreman::CLI" do
end
end
describe "check" do
describe "with a valid Procfile" do
before { write_procfile }
it "displays the jobs" do
mock(subject).display("valid procfile detected (alpha, bravo)")
subject.check
end
end
describe "with a blank Procfile" do
before do
FileUtils.touch("Procfile")
end
it "displays an error" do
mock_error(subject, "no processes defined") do
subject.check
end
end
end
end
end

View File

@@ -12,12 +12,26 @@ describe "Foreman::Engine" do
end
describe "with a Procfile" do
before { write_procfile }
it "reads the processes" do
write_procfile
subject.processes["alpha"].command.should == "./alpha"
subject.processes["bravo"].command.should == "./bravo"
end
end
describe "with a deprecated Procfile" do
before do
File.open("Procfile", "w") do |file|
file.puts "name command"
end
end
it "should print a deprecation warning" do
mock(subject).warn_deprecated_procfile!
subject.processes.length.should == 1
end
end
end
describe "start" do

View File

@@ -26,8 +26,8 @@ end
def write_procfile(procfile="Procfile")
File.open(procfile, "w") do |file|
file.puts "alpha ./alpha"
file.puts "bravo ./bravo"
file.puts "alpha: ./alpha"
file.puts "bravo: ./bravo"
end
end