Compare commits

..

58 Commits

Author SHA1 Message Date
David Dollar 0033f9caeb 0.42.0 2012-04-18 13:02:51 -04:00
David Dollar 74839800a9 Merge pull request #181 from technomancy/master
Public read_environment
2012-04-18 10:01:38 -07:00
Phil Hagelberg b75337e21e Move read_environment to a public class method. 2012-04-18 09:56:17 -07:00
David Dollar d94f941189 update gemfile.lock 2012-04-18 12:49:33 -04:00
David Dollar 0b34f067cb Revert "Merge pull request #176 from rtyler/feature/156-foreman-stop-command"
Rewriting using a better Process API

This reverts commit dbe51832b0, reversing
changes made to 69216b4c5e.
2012-04-18 12:48:51 -04:00
David Dollar dbe51832b0 Merge pull request #176 from rtyler/feature/156-foreman-stop-command
Adding #stop method to Foreman::Engine
2012-04-11 10:29:54 -07:00
R. Tyler Croy 3a2a53be95 Remove ALL_PROCESSES and default the name arguments to #start/#stop to nil 2012-04-11 10:25:58 -07:00
R. Tyler Croy b2bf95479e Refactor #stop to reference ALL_PROCESSES for a bit clearer readability 2012-04-10 20:35:59 -07:00
R. Tyler Croy 48f764e347 Refactor #spawn_processes into #start(name)
When passed nil (aka ALL_PROCESSES) #start will start all processes in the
Procfile as per existing behavior
2012-04-10 20:35:59 -07:00
R. Tyler Croy de62d0655e Re-name the main Foreman::Engine method to #run to avoid a name collision with #start(name) 2012-04-10 20:35:59 -07:00
R. Tyler Croy 38aecff886 When executing #stop(nil), all processes should be sent the signal 2012-04-10 20:35:58 -07:00
R. Tyler Croy e4a3215257 Re-implement #terminate_gracefully with #stop(name) 2012-04-10 20:19:23 -07:00
R. Tyler Croy c705b5fbef Add #stop method on Foreman::Engine for stopping certain named processes
This will make embedding foreman "nicer" since the embedder can then stop
a specific process (e.g. turning off a service for an integration fail-over test)
2012-04-10 20:10:51 -07:00
David Dollar 69216b4c5e Merge pull request #171 from technomancy/0.41.0-deparkaed
Drop parka dependency to make things easier on the build slaves.
2012-03-26 15:05:35 -07:00
Phil Hagelberg 5d2930745a Drop parka dependency to make things easier on the build slaves. 2012-03-26 15:01:04 -07:00
David Dollar 8fc3d1ef24 Merge pull request #161 from leahpar/master
Supervisord Support (Update & Bugfix)
2012-03-16 18:47:15 -07:00
David Dollar d33e4fb0ed update changelog 2012-03-16 16:36:16 -04:00
David Dollar 39b48b566f 0.41.0 2012-03-16 16:34:32 -04:00
David Dollar 2f982ff9c7 replace term-ansicolor with built-in colorization 2012-03-16 16:34:14 -04:00
Raphael Randschau 1217ef1b56 fix typo 2012-03-05 15:51:10 +01:00
Raphael Randschau c9943d70ec add group support for supervisord 2012-03-05 15:48:40 +01:00
Raphael Randschau 08dca57eb4 fix enviroment export 2012-02-25 17:24:27 +01:00
David Dollar bb3377407a Merge pull request #160 from leahpar/master
supervisord support
2012-02-24 11:49:55 -08:00
Raphael Randschau 084b9493d1 revert bundle update 2012-02-24 20:31:07 +01:00
Raphael Randschau 279a251c78 fix whitespaces 2012-02-24 20:29:16 +01:00
Raphael Randschau a49ef286e8 all specs are passing 2012-02-24 20:18:38 +01:00
Raphael Randschau 0b3da59947 passing first export 2012-02-24 19:52:18 +01:00
David Dollar 1f725dd68a let github show authors 2012-02-24 11:34:34 -05:00
David Dollar 2272f76479 authors 2012-02-24 11:33:33 -05:00
David Dollar cf4762071c changelog 2012-02-24 11:33:18 -05:00
David Dollar d86b0bed1f 0.40.0 2012-02-24 11:32:00 -05:00
David Dollar 12f825204b support various quoting styles in .env 2012-02-24 11:31:21 -05:00
David Dollar 62c9d1db45 remove load_env! as it's made unnecessary by foreman run 2012-02-24 11:31:21 -05:00
Raphael Randschau 1127551369 rename supervisord base template to app
add supervisord stub
2012-02-23 17:24:08 +01:00
Raphael Randschau 8cb58b8517 require supervisord export 2012-02-23 17:11:19 +01:00
Raphael Randschau d03e931b67 add supervisord export engine 2012-02-23 17:10:57 +01:00
Raphael Randschau 9ba2b32b36 add supervisord base template 2012-02-23 17:02:59 +01:00
David Dollar cf5689a77a Merge pull request #155 from rtyler/bug/152-check-exception-no-procfile
Provide a useful error if `foreman check` fails to find a Procfile
2012-02-21 17:40:20 -08:00
R. Tyler Croy c23dbb79af Provide a useful error if foreman check fails to find a Procfile
Fixes #152
2012-02-21 17:27:15 -08:00
David Dollar 7e55d8d3e2 update docs 2012-02-21 11:58:57 -05:00
David Dollar d4f23d45a4 add run to docs 2012-02-21 11:58:52 -05:00
David Dollar 93fa1645e7 update docs 2012-02-21 11:50:11 -05:00
David Dollar 7bdada4a10 update docs 2012-02-21 11:49:57 -05:00
David Dollar 2b47d24ab7 Travis doesn't support cext. Revert "try java again"
This reverts commit 24695348fb.
2012-02-09 19:16:14 -05:00
David Dollar 24695348fb try java again 2012-02-09 19:12:11 -05:00
David Dollar 38b6482af5 changelog 2012-02-07 11:19:12 -05:00
David Dollar 501bc138c5 authors 2012-02-07 11:18:06 -05:00
David Dollar df8c05cd6c 0.39.0 2012-02-07 11:17:59 -05:00
David Dollar edcc4f3567 move to foreman-runner 2012-02-07 11:17:44 -05:00
David Dollar 3759dbb463 fix tgz release 2012-02-07 11:16:07 -05:00
David Dollar b673931c05 Double Revert "Revert "bundle update hpricot""
This reverts commit 137e43b040.
2012-02-04 19:47:48 -05:00
David Dollar 137e43b040 Revert "bundle update hpricot"
This reverts commit 16d4b84a5d.
2012-02-04 19:25:01 -05:00
David Dollar 79211d9bbf Merge pull request #147 from jfirebaugh/rubinius
bundle update hpricot
2012-02-04 14:05:06 -08:00
John Firebaugh 16d4b84a5d bundle update hpricot
0.8.2 doesn't compile on Rubinius; 0.8.6 does.
2012-02-04 13:46:48 -08:00
David Dollar 5ea4537046 remove version from inner pkg 2012-02-02 21:31:58 -05:00
David Dollar d51433ff82 fix foreman pkg builder 2012-02-02 21:08:01 -05:00
David Dollar 54ab74d305 fix release tasks 2012-02-02 17:32:52 -05:00
David Dollar e8b8f34f41 changelog 2012-02-02 17:27:56 -05:00
31 changed files with 398 additions and 139 deletions
+26
View File
@@ -1,3 +1,29 @@
## 0.41.0 (2012-03-16)
* replace term-ansicolor with built-in colorization [David Dollar]
* supervisord export template [Raphael Randschau]
## 0.40.0 (2012-02-24)
* support various quoting styles in .env [David Dollar]
* remove load_env! as it's made unnecessary by foreman run [David Dollar]
* Provide a useful error if `foreman check` fails to find a Procfile [R. Tyler Croy]
* update docs [David Dollar]
## 0.39.0 (2012-02-07)
* rename bin/runner to bin/foreman-runner [David Dollar]
* fix tgz release [David Dollar]
* bundle update hpricot [John Firebaugh]
* touch up .pkg release tasks [David Dollar]
## 0.38.0 (2012-02-02)
* bring back single process starting [David Dollar]
* more attempts at getting ci working with jruby [David Dollar]
* ignore .rbenv-version [David Dollar]
* force to binary encoding if supported [David Dollar]
## 0.37.2 (2012-01-29)
* handle directories with spaces in runner [David Dollar]
+1 -1
View File
@@ -11,7 +11,7 @@ platform :jruby do
end
group :development do
gem 'parka'
gem 'aws-s3'
gem 'rake'
gem 'ronn'
gem 'fakefs', '~> 0.3.2'
+10 -13
View File
@@ -1,30 +1,27 @@
PATH
remote: .
specs:
foreman (0.38.0)
term-ansicolor (~> 1.0.7)
foreman (0.42.0)
thor (>= 0.13.6)
GEM
remote: http://rubygems.org/
specs:
crack (0.1.8)
aws-s3 (0.6.2)
builder
mime-types
xml-simple
builder (3.0.0)
diff-lcs (1.1.3)
fakefs (0.3.2)
hpricot (0.8.2)
hpricot (0.8.2-java)
hpricot (0.8.6)
hpricot (0.8.6-java)
mime-types (1.16)
multi_json (1.0.4)
mustache (0.11.2)
parka (0.6.2)
crack
rest-client
thor
posix-spawn (0.3.6)
rake (0.9.2.2)
rdiscount (1.6.5)
rest-client (1.6.1)
mime-types (>= 1.16)
ronn (0.7.3)
hpricot (>= 0.8.2)
mustache (>= 0.7.0)
@@ -42,9 +39,9 @@ GEM
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
term-ansicolor (1.0.7)
thor (0.14.6)
win32console (1.3.0-x86-mingw32)
xml-simple (1.0.15)
PLATFORMS
java
@@ -52,9 +49,9 @@ PLATFORMS
x86-mingw32
DEPENDENCIES
aws-s3
fakefs (~> 0.3.2)
foreman!
parka
posix-spawn (~> 0.3.6)
rake
ronn
+1 -1
View File
@@ -33,7 +33,7 @@ Manage Procfile-based applications
David Dollar
#### Patches contributed by
Adam Wiggins, Chris Continanza, Chris Lowder, Craig R Webster, Dan Farina, Dan Peterson, David Dollar, Fletcher Nichol, Florian Apolloner, Gabriel Burt, Gamaliel Toro, Greg Reinacker, Hugues Le Gendre, Hunter Nield, Iain Hecker, Jay Zeschin, Keith Rarick, Khaja Minhajuddin, Lincoln Stoll, Marcos Muino Garcia, Mark McGranaghan, Matt Griffin, Matt Haynes, Matthijs Langenberg, Michael Dwan, Michael van Rooijen, Mike Javorski, Nathan Broadbent, Nathan L Smith, Nick Zadrozny, Phil Hagelberg, Ricardo Chimal, Jr, Thom May, Tom Ward, brainopia, clifff, jc00ke
[Contributor List](https://github.com/ddollar/foreman/contributors)
## License
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
#
#/ Usage: runner [-d <dir>] <command>
#/ Usage: foreman-runner [-d <dir>] <command>
#/
#/ Run a command with exec, optionally changing directory first
+27
View File
@@ -0,0 +1,27 @@
<%
app_names = []
engine.procfile.entries.each do |process|
next if (conc = self.concurrency[process.name]) < 1
1.upto(self.concurrency[process.name]) do |num|
port = engine.port_for(process, num, self.port)
name = if (conc > 1); "#{process.name}-#{num}" else process.name; end
environment = (engine.environment.map{ |var,env| "#{var.upcase}=#{env}" } + ["PORT=#{port}"])
app_name = "#{app}-#{name}"
app_names << app_name
%>
[program:<%= app_name %>]
command=<%= process.command %>
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=<%= log_root %>/<%=process.name%>-<%=num%>-out.log
stderr_logfile=<%= log_root %>/<%=process.name%>-<%=num%>-err.log
user=<%= user %>
directory=<%= engine.directory %>
environment=<%= environment.join(',') %><%
end
end
%>
[group:<%= app %>]
programs=<%= app_names.join(',') %>
+1 -1
View File
@@ -4,7 +4,7 @@ file pkg("/apt-#{version}/foreman-#{version}.deb") => distribution_files("deb")
assemble_distribution
assemble_gems
assemble resource("deb/foreman"), "bin/foreman", 0755
File.chmod 0755, "bin/runner"
File.chmod 0755, "bin/foreman-runner"
end
assemble resource("deb/control"), "control"
+3 -1
View File
@@ -1,5 +1,7 @@
file pkg("foreman-#{version}-jruby.gem") => distribution_files do |t|
sh "env PLATFORM=java gem build foreman.gemspec"
Bundler.with_clean_env do
sh "env PLATFORM=java gem build foreman.gemspec"
end
sh "mv foreman-#{version}-java.gem #{t.name}"
end
+3 -1
View File
@@ -1,5 +1,7 @@
file pkg("foreman-#{version}-mingw32.gem") => distribution_files do |t|
sh "env PLATFORM=mingw32 gem build foreman.gemspec"
Bundler.with_clean_env do
sh "env PLATFORM=mingw32 gem build foreman.gemspec"
end
sh "mv foreman-#{version}-mingw32.gem #{t.name}"
end
+8 -7
View File
@@ -13,7 +13,7 @@ file pkg("foreman-#{version}.pkg") => distribution_files do |t|
mkdir_p "pkg"
mkdir_p "pkg/Resources"
mkdir_p "pkg/foreman-#{version}.pkg"
mkdir_p "pkg/foreman.pkg"
dist = File.read(resource("pkg/Distribution.erb"))
dist = ERB.new(dist).result(binding)
@@ -21,20 +21,21 @@ file pkg("foreman-#{version}.pkg") => distribution_files do |t|
dist = File.read(resource("pkg/PackageInfo.erb"))
dist = ERB.new(dist).result(binding)
File.open("pkg/foreman-#{version}.pkg/PackageInfo", "w") { |f| f.puts dist }
File.open("pkg/foreman.pkg/PackageInfo", "w") { |f| f.puts dist }
mkdir_p "pkg/foreman-#{version}.pkg/Scripts"
cp resource("pkg/postinstall"), "pkg/foreman-#{version}.pkg/Scripts/postinstall"
chmod 0755, "pkg/foreman-#{version}.pkg/Scripts/postinstall"
mkdir_p "pkg/foreman.pkg/Scripts"
cp resource("pkg/postinstall"), "pkg/foreman.pkg/Scripts/postinstall"
chmod 0755, "pkg/foreman.pkg/Scripts/postinstall"
sh %{ mkbom -s foreman pkg/foreman-#{version}.pkg/Bom }
sh %{ mkbom -s foreman pkg/foreman.pkg/Bom }
Dir.chdir("foreman") do
sh %{ pax -wz -x cpio . > ../pkg/foreman-#{version}.pkg/Payload }
sh %{ pax -wz -x cpio . > ../pkg/foreman.pkg/Payload }
end
sh %{ pkgutil --flatten pkg foreman-#{version}.pkg }
FileUtils.mkdir_p(File.dirname(t.name))
cp_r "foreman-#{version}.pkg", t.name
end
end
+3 -3
View File
@@ -10,14 +10,14 @@
]]></script>
<choices-outline>
<line choice="git"/>
<line choice="foreman-<%= version %>"/>
<line choice="foreman"/>
</choices-outline>
<choice id="git" title="git" start_selected="false" start_enabled="false" selected="needs_git()" enabled="needs_git()">
<pkg-ref id="git.pkg" />
</choice>
<choice id="foreman-<%= version %>" title="foreman">
<choice id="foreman" title="foreman">
<pkg-ref id="io.foreman.installer"/>
</choice>
<pkg-ref id="io.foreman.installer" installKBytes="<%= kbytes %>" version="<%= version %>" auth="Root">#foreman-<%= version %>.pkg</pkg-ref>
<pkg-ref id="io.foreman.installer" installKBytes="<%= kbytes %>" version="<%= version %>" auth="Root">#foreman.pkg</pkg-ref>
</installer-script>
-1
View File
@@ -4,4 +4,3 @@
<postinstall file="./postinstall"/>
</scripts>
</pkg-info>
+1 -1
View File
@@ -3,7 +3,7 @@ file pkg("foreman-#{version}.tgz") => distribution_files do |t|
mkchdir("foreman") do
assemble_distribution
assemble_gems
rm_rf "bin"
rm_f "bin/foreman"
assemble resource("tgz/foreman"), "foreman", 0755
end
+1 -2
View File
@@ -16,8 +16,7 @@ Gem::Specification.new do |gem|
gem.files = Dir["**/*"].select { |d| d =~ %r{^(README|bin/|data/|ext/|lib/|spec/|test/)} }
gem.files << "man/foreman.1"
gem.add_dependency 'term-ansicolor', '~> 1.0.7'
gem.add_dependency 'thor', '>= 0.13.6'
gem.add_dependency 'thor', '>= 0.13.6'
if ENV["PLATFORM"] == "java"
gem.add_dependency "posix-spawn", "~> 0.3.6"
+1 -7
View File
@@ -4,14 +4,8 @@ module Foreman
class AppDoesNotExist < Exception; end
# load contents of env_file into ENV
def self.load_env!(env_file = './.env')
require 'foreman/engine'
Foreman::Engine.load_env!(env_file)
end
def self.runner
File.expand_path("../../bin/runner", __FILE__)
File.expand_path("../../bin/foreman-runner", __FILE__)
end
def self.jruby?
+1
View File
@@ -54,6 +54,7 @@ class Foreman::CLI < Thor
desc "check", "Validate your application's Procfile"
def check
check_procfile!
error "no processes defined" unless engine.procfile.entries.length > 0
puts "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
end
+40
View File
@@ -0,0 +1,40 @@
require "foreman"
module Foreman::Color
ANSI = {
:reset => 0,
:black => 30,
:red => 31,
:green => 32,
:yellow => 33,
:blue => 34,
:magenta => 35,
:cyan => 36,
:white => 37,
:bright_black => 30,
:bright_red => 31,
:bright_green => 32,
:bright_yellow => 33,
:bright_blue => 34,
:bright_magenta => 35,
:bright_cyan => 36,
:bright_white => 37,
}
def self.enable(io)
io.extend(self)
end
def color?
return false unless self.respond_to?(:isatty)
self.isatty && ENV["TERM"]
end
def color(name)
return "" unless color?
return "" unless ansi = ANSI[name.to_sym]
"\e[#{ansi}m"
end
end
+40 -59
View File
@@ -1,24 +1,24 @@
require "foreman"
require "foreman/color"
require "foreman/process"
require "foreman/procfile"
require "foreman/utils"
require "tempfile"
require "timeout"
require "term/ansicolor"
require "fileutils"
require "thread"
class Foreman::Engine
attr_reader :environment
attr_reader :procfile
attr_reader :directory
attr_reader :options
extend Term::ANSIColor
COLORS = %w( cyan yellow green magenta red blue intense_cyan intense_yellow
intense_green intense_magenta intense_red, intense_blue )
COLORS = [ cyan, yellow, green, magenta, red, blue,
intense_cyan, intense_yellow, intense_green, intense_magenta,
intense_red, intense_blue ]
Foreman::Color.enable($stdout)
def initialize(procfile, options={})
@procfile = Foreman::Procfile.new(procfile)
@@ -28,11 +28,6 @@ class Foreman::Engine
@output_mutex = Mutex.new
end
def self.load_env!(env_file)
@environment = read_environment_files(env_file)
apply_environment!
end
def start
proctitle "ruby: foreman master"
termtitle "#{File.basename(@directory)} - foreman"
@@ -52,6 +47,26 @@ class Foreman::Engine
base_port.to_i + offset + num - 1
end
def apply_environment!
environment.each { |k,v| ENV[k] = v }
end
def self.read_environment(filename)
return {} unless File.exists?(filename)
File.read(filename).split("\n").inject({}) do |hash, line|
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
key, val = [$1, $2]
case val
when /\A'(.*)'\z/ then hash[key] = $1
when /\A"(.*)"\z/ then hash[key] = $1.gsub(/\\(.)/, '\1')
else hash[key] = val
end
end
hash
end
end
private ######################################################################
def spawn_processes
@@ -128,11 +143,11 @@ private ######################################################################
rescue Errno::ECHILD
end
def info(message, name="system", color=Term::ANSIColor.white)
def info(message, name="system", color=:white)
output = ""
output += color
output += $stdout.color(color)
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
output += Term::ANSIColor.reset
output += $stdout.color(:reset)
output += message.chomp
puts output
end
@@ -182,8 +197,8 @@ private ######################################################################
end
def assign_colors
procfile.entries.each do |entry|
colors[entry.name] = next_color
procfile.entries.each_with_index do |entry, idx|
colors[entry.name] = COLORS[idx % COLORS.length]
end
end
@@ -191,49 +206,15 @@ private ######################################################################
readers.invert[reader]
end
def next_color
@current_color ||= -1
@current_color += 1
@current_color = 0 if COLORS.length < @current_color
COLORS[@current_color]
def read_environment_files(filenames)
environment = {}
(filenames || "").split(",").map(&:strip).each do |filename|
error "No such file: #{filename}" unless File.exists?(filename)
environment.merge!(Foreman::Engine.read_environment(filename))
end
environment.merge!(Foreman::Engine.read_environment(".env")) unless filenames
environment
end
module Env
attr_reader :environment
def read_environment_files(filenames)
environment = {}
(filenames || "").split(",").map(&:strip).each do |filename|
error "No such file: #{filename}" unless File.exists?(filename)
environment.merge!(read_environment(filename))
end
environment.merge!(read_environment(".env")) unless filenames
environment
end
def read_environment(filename)
return {} unless File.exists?(filename)
File.read(filename).split("\n").inject({}) do |hash, line|
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
hash[$1] = $2
end
hash
end
end
def apply_environment!
@environment.each { |k,v| ENV[k] = v }
end
def error(message)
puts "ERROR: #{message}"
exit 1
end
end
include Env
extend Env
end
+2
View File
@@ -30,3 +30,5 @@ require "foreman/export/inittab"
require "foreman/export/upstart"
require "foreman/export/bluepill"
require "foreman/export/runit"
require "foreman/export/supervisord"
+26
View File
@@ -0,0 +1,26 @@
require "erb"
require "foreman/export"
class Foreman::Export::Supervisord < Foreman::Export::Base
def export
error("Must specify a location") unless location
FileUtils.mkdir_p location
app = self.app || File.basename(engine.directory)
user = self.user || app
log_root = self.log || "/var/log/#{app}"
template_root = self.template
Dir["#{location}/#{app}*.conf"].each do |file|
say "cleaning up: #{file}"
FileUtils.rm(file)
end
app_template = export_template("supervisord", "app.conf.erb", template_root)
app_config = ERB.new(app_template, 0, '<').result(binding)
write_file "#{location}/#{app}.conf", app_config
end
end
+1 -1
View File
@@ -1,5 +1,5 @@
module Foreman
VERSION = "0.38.0"
VERSION = "0.42.0"
end
+13 -3
View File
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FOREMAN" "1" "January 2012" "Foreman 0.37.2" "Foreman Manual"
.TH "FOREMAN" "1" "February 2012" "Foreman 0.39.0" "Foreman Manual"
.
.SH "NAME"
\fBforeman\fR \- manage Procfile\-based applications
@@ -10,10 +10,13 @@
\fBforeman start [process]\fR
.
.br
\fBforeman run <command>\fR
.
.br
\fBforeman export <format> [location]\fR
.
.SH "DESCRIPTION"
\fBForeman\fR 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\.
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\.
.
.SH "RUNNING"
\fBforeman start\fR is used to run your application directly from the command line\.
@@ -35,6 +38,9 @@ Specify the number of each process type to run\. The value passed in should be i
\fB\-p\fR, \fB\-\-port\fR
Specify which port to use as the base for this application\. Should be a multiple of 1000\.
.
.P
\fBforeman run\fR is used to run one\-off commands using the same environment as your defined processes\.
.
.SH "EXPORTING"
\fBforeman export\fR is used to export your application to another process management format\.
.
@@ -61,10 +67,14 @@ Specify the directory to place process logs in\.
Specify which port to use as the base for this application\. Should be a multiple of 1000\.
.
.TP
\fB\-t\fR, \fB\-\-template\fR
Specify an alternate template to use for creating export files\. See \fIhttps://github\.com/ddollar/foreman/tree/master/data/export\fR for examples\.
.
.TP
\fB\-u\fR, \fB\-\-user\fR
Specify the user the application should be run as\. Defaults to the app name
.
.SH "OPTIONS"
.SH "GLOBAL OPTIONS"
These options control all modes of foreman\'s operation\.
.
.TP
+10 -2
View File
@@ -4,11 +4,12 @@ foreman(1) -- manage Procfile-based applications
## SYNOPSIS
`foreman start [process]`<br>
`foreman run <command>`<br>
`foreman export <format> [location]`
## DESCRIPTION
**Foreman** is a manager for Procfile-based applications. Its aim is to
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.
@@ -33,6 +34,9 @@ The following options control how the application is run:
Specify which port to use as the base for this application. Should be
a multiple of 1000.
`foreman run` is used to run one-off commands using the same environment
as your defined processes.
## EXPORTING
`foreman export` is used to export your application to another process
@@ -58,11 +62,15 @@ The following options control how the application is run:
Specify which port to use as the base for this application. Should be
a multiple of 1000.
* `-t`, `--template`:
Specify an alternate template to use for creating export files.
See <https://github.com/ddollar/foreman/tree/master/data/export> for examples.
* `-u`, `--user`:
Specify the user the application should be run as. Defaults to the
app name
## OPTIONS
## GLOBAL OPTIONS
These options control all modes of foreman's operation.
+8
View File
@@ -120,6 +120,14 @@ describe "Foreman::CLI", :fakefs do
end
end
end
describe "without a Procfile" do
it "displays an error" do
mock_error(subject, "Procfile does not exist.") do
subject.check
end
end
end
end
describe "run" do
+31
View File
@@ -0,0 +1,31 @@
require "spec_helper"
require "foreman/color"
describe Foreman::Color do
let(:io) { Object.new }
it "should extend an object with colorization" do
Foreman::Color.enable(io)
io.should respond_to(:color)
end
it "should not colorize if the object does not respond to isatty" do
mock(io).respond_to?(:isatty) { false }
Foreman::Color.enable(io)
io.color(:white).should == ""
end
it "should not colorize if the object is not a tty" do
mock(io).isatty { false }
Foreman::Color.enable(io)
io.color(:white).should == ""
end
it "should colorize if the object is a tty" do
mock(io).isatty { true }
Foreman::Color.enable(io)
io.color(:white).should == "\e[37m"
end
end
+16 -8
View File
@@ -53,14 +53,16 @@ describe "Foreman::Engine", :fakefs do
before(:each) do
write_procfile
stub(Process).fork
any_instance_of(Foreman::Engine) do |engine|
stub(engine).info
stub(engine).spawn_processes
stub(engine).watch_for_termination
end
end
it "should read if specified" do
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
stub(engine).info
mock(engine).spawn_processes
mock(engine).watch_for_termination
engine.environment.should == {"FOO"=>"baz"}
engine.start
end
@@ -69,13 +71,21 @@ describe "Foreman::Engine", :fakefs do
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2")
stub(engine).info
mock(engine).spawn_processes
mock(engine).watch_for_termination
engine.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" }
engine.start
end
it "should handle quoted values" do
File.open("/tmp/env", "w") do |f|
f.puts 'FOO=bar'
f.puts 'BAZ="qux"'
f.puts "FRED='barney'"
f.puts 'OTHER="escaped\"quote"'
end
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
engine.environment.should == { "FOO" => "bar", "BAZ" => "qux", "FRED" => "barney", "OTHER" => 'escaped"quote' }
end
it "should fail if specified and doesnt exist" do
mock.instance_of(Foreman::Engine).error("No such file: /tmp/env")
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
@@ -84,8 +94,6 @@ describe "Foreman::Engine", :fakefs do
it "should read .env if none specified" do
File.open(".env", "w") { |f| f.puts("FOO=qoo") }
engine = Foreman::Engine.new("Procfile")
mock(engine).spawn_processes
mock(engine).watch_for_termination
engine.environment.should == {"FOO"=>"qoo"}
engine.start
end
+75
View File
@@ -0,0 +1,75 @@
require "spec_helper"
require "foreman/engine"
require "foreman/export/supervisord"
require "tmpdir"
describe Foreman::Export::Supervisord, :fakefs do
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
let(:engine) { Foreman::Engine.new(procfile) }
let(:options) { Hash.new }
let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, options) }
before(:each) { load_export_templates_into_fakefs("supervisord") }
before(:each) { stub(supervisord).say }
it "exports to the filesystem" do
supervisord.export
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app.conf")
end
it "cleans up if exporting into an existing dir" do
mock(FileUtils).rm("/tmp/init/app.conf")
supervisord.export
supervisord.export
end
context "with concurrency" do
let(:options) { Hash[:concurrency => "alpha=2"] }
it "exports to the filesystem with concurrency" do
supervisord.export
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
end
end
context "with alternate templates" do
let(:template_root) { "/tmp/alternate" }
let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, :template => template_root) }
before do
FileUtils.mkdir_p template_root
File.open("#{template_root}/app.conf.erb", "w") { |f| f.puts "alternate_template" }
end
it "can export with alternate template files" do
supervisord.export
File.read("/tmp/init/app.conf").should == "alternate_template\n"
end
end
context "with alternate templates from home dir" do
let(:default_template_root) {File.expand_path("#{ENV['HOME']}/.foreman/templates")}
before do
ENV['_FOREMAN_SPEC_HOME'] = ENV['HOME']
ENV['HOME'] = "/home/appuser"
FileUtils.mkdir_p default_template_root
File.open("#{default_template_root}/app.conf.erb", "w") { |f| f.puts "default_alternate_template" }
end
after do
ENV['HOME'] = ENV.delete('_FOREMAN_SPEC_HOME')
end
it "can export with alternate template files" do
supervisord.export
File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
end
end
end
-18
View File
@@ -8,24 +8,6 @@ describe Foreman do
it { should be_a String }
end
describe "::load_env!(env_file)", :fakefs do
after do
ENV['FOO'] = nil
end
it "should load env_file into ENV" do
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
Foreman.load_env!("/tmp/env1")
ENV['FOO'].should == 'bar'
end
it "should assume env_file in ./.env" do
File.open("./.env", "w") { |f| f.puts("FOO=bar") }
Foreman.load_env!
ENV['FOO'].should == 'bar'
end
end
describe "runner" do
it "should exist" do
File.exists?(Foreman.runner).should == true
@@ -0,0 +1,24 @@
[program:app-alpha-1]
command=./alpha
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/alpha-1-out.log
stderr_logfile=/var/log/app/alpha-1-err.log
user=app
directory=/tmp/app
environment=PORT=5000
[program:app-alpha-2]
command=./alpha
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/alpha-2-out.log
stderr_logfile=/var/log/app/alpha-2-err.log
user=app
directory=/tmp/app
environment=PORT=5001
[group:app]
programs=app-alpha-1,app-alpha-2
@@ -0,0 +1,24 @@
[program:app-alpha]
command=./alpha
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/alpha-1-out.log
stderr_logfile=/var/log/app/alpha-1-err.log
user=app
directory=/tmp/app
environment=PORT=5000
[program:app-bravo]
command=./bravo
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/bravo-1-out.log
stderr_logfile=/var/log/app/bravo-1-err.log
user=app
directory=/tmp/app
environment=PORT=5100
[group:app]
programs=app-alpha,app-bravo
-8
View File
@@ -27,14 +27,6 @@ task :pages => "man:commit" do
}
end
desc "Generate an authors list"
task :authors do
authors = %x{ git log --pretty=format:"%an" | sort -u }.split("\n")
readme = File.read("README.md")
readme.gsub!(/#### Patches contributed by\n([^\n]*)\n/m, "#### Patches contributed by\n#{authors.join(", ")}\n")
File.open("README.md", "w") { |f| f.print readme }
end
def latest_release
latest = File.read("Changelog.md").split("\n").first.split(" ")[1]
end