Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0033f9caeb | |||
| 74839800a9 | |||
| b75337e21e | |||
| d94f941189 | |||
| 0b34f067cb | |||
| dbe51832b0 | |||
| 3a2a53be95 | |||
| b2bf95479e | |||
| 48f764e347 | |||
| de62d0655e | |||
| 38aecff886 | |||
| e4a3215257 | |||
| c705b5fbef | |||
| 69216b4c5e | |||
| 5d2930745a | |||
| 8fc3d1ef24 | |||
| d33e4fb0ed | |||
| 39b48b566f | |||
| 2f982ff9c7 | |||
| 1217ef1b56 | |||
| c9943d70ec | |||
| 08dca57eb4 | |||
| bb3377407a | |||
| 084b9493d1 | |||
| 279a251c78 | |||
| a49ef286e8 | |||
| 0b3da59947 | |||
| 1f725dd68a | |||
| 2272f76479 | |||
| cf4762071c | |||
| d86b0bed1f | |||
| 12f825204b | |||
| 62c9d1db45 | |||
| 1127551369 | |||
| 8cb58b8517 | |||
| d03e931b67 | |||
| 9ba2b32b36 | |||
| cf5689a77a | |||
| c23dbb79af | |||
| 7e55d8d3e2 | |||
| d4f23d45a4 | |||
| 93fa1645e7 | |||
| 7bdada4a10 | |||
| 2b47d24ab7 | |||
| 24695348fb | |||
| 38b6482af5 | |||
| 501bc138c5 | |||
| df8c05cd6c | |||
| edcc4f3567 | |||
| 3759dbb463 | |||
| b673931c05 | |||
| 137e43b040 | |||
| 79211d9bbf | |||
| 16d4b84a5d | |||
| 5ea4537046 | |||
| d51433ff82 | |||
| 54ab74d305 | |||
| e8b8f34f41 | |||
| 7535f1d3d8 | |||
| 3af0dfb4ae | |||
| 78547b8175 | |||
| 976fbc0bb0 | |||
| 28a9aa774f | |||
| 51f5ff3842 | |||
| e1e18f62bb | |||
| 0a09117328 | |||
| c3df12746f | |||
| 2ec6a23fb3 | |||
| 0d6b784de1 | |||
| 2dcd2c03db | |||
| 9d6d0bbb7d |
@@ -1,4 +1,5 @@
|
|||||||
/.bundle
|
/.bundle
|
||||||
|
/.rbenv-version
|
||||||
/coverage
|
/coverage
|
||||||
/example/log/*
|
/example/log/*
|
||||||
/man/*.html
|
/man/*.html
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
script: bundle exec rake spec
|
script: bundle exec rake spec
|
||||||
|
|
||||||
env: JRUBY_OPTS="--debug -X+O"
|
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
- 1.8.7
|
- 1.8.7
|
||||||
- 1.9.2
|
- 1.9.2
|
||||||
- 1.9.3
|
- 1.9.3
|
||||||
- jruby-head
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|||||||
@@ -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)
|
## 0.37.2 (2012-01-29)
|
||||||
|
|
||||||
* handle directories with spaces in runner [David Dollar]
|
* handle directories with spaces in runner [David Dollar]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ platform :jruby do
|
|||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'parka'
|
gem 'aws-s3'
|
||||||
gem 'rake'
|
gem 'rake'
|
||||||
gem 'ronn'
|
gem 'ronn'
|
||||||
gem 'fakefs', '~> 0.3.2'
|
gem 'fakefs', '~> 0.3.2'
|
||||||
|
|||||||
+10
-13
@@ -1,30 +1,27 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
foreman (0.37.2)
|
foreman (0.42.0)
|
||||||
term-ansicolor (~> 1.0.7)
|
|
||||||
thor (>= 0.13.6)
|
thor (>= 0.13.6)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
crack (0.1.8)
|
aws-s3 (0.6.2)
|
||||||
|
builder
|
||||||
|
mime-types
|
||||||
|
xml-simple
|
||||||
|
builder (3.0.0)
|
||||||
diff-lcs (1.1.3)
|
diff-lcs (1.1.3)
|
||||||
fakefs (0.3.2)
|
fakefs (0.3.2)
|
||||||
hpricot (0.8.2)
|
hpricot (0.8.6)
|
||||||
hpricot (0.8.2-java)
|
hpricot (0.8.6-java)
|
||||||
mime-types (1.16)
|
mime-types (1.16)
|
||||||
multi_json (1.0.4)
|
multi_json (1.0.4)
|
||||||
mustache (0.11.2)
|
mustache (0.11.2)
|
||||||
parka (0.6.2)
|
|
||||||
crack
|
|
||||||
rest-client
|
|
||||||
thor
|
|
||||||
posix-spawn (0.3.6)
|
posix-spawn (0.3.6)
|
||||||
rake (0.9.2.2)
|
rake (0.9.2.2)
|
||||||
rdiscount (1.6.5)
|
rdiscount (1.6.5)
|
||||||
rest-client (1.6.1)
|
|
||||||
mime-types (>= 1.16)
|
|
||||||
ronn (0.7.3)
|
ronn (0.7.3)
|
||||||
hpricot (>= 0.8.2)
|
hpricot (>= 0.8.2)
|
||||||
mustache (>= 0.7.0)
|
mustache (>= 0.7.0)
|
||||||
@@ -42,9 +39,9 @@ GEM
|
|||||||
multi_json (~> 1.0.3)
|
multi_json (~> 1.0.3)
|
||||||
simplecov-html (~> 0.5.3)
|
simplecov-html (~> 0.5.3)
|
||||||
simplecov-html (0.5.3)
|
simplecov-html (0.5.3)
|
||||||
term-ansicolor (1.0.7)
|
|
||||||
thor (0.14.6)
|
thor (0.14.6)
|
||||||
win32console (1.3.0-x86-mingw32)
|
win32console (1.3.0-x86-mingw32)
|
||||||
|
xml-simple (1.0.15)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
java
|
java
|
||||||
@@ -52,9 +49,9 @@ PLATFORMS
|
|||||||
x86-mingw32
|
x86-mingw32
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
aws-s3
|
||||||
fakefs (~> 0.3.2)
|
fakefs (~> 0.3.2)
|
||||||
foreman!
|
foreman!
|
||||||
parka
|
|
||||||
posix-spawn (~> 0.3.6)
|
posix-spawn (~> 0.3.6)
|
||||||
rake
|
rake
|
||||||
ronn
|
ronn
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Manage Procfile-based applications
|
|||||||
David Dollar
|
David Dollar
|
||||||
|
|
||||||
#### Patches contributed by
|
#### 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
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
$:.unshift File.expand_path("../lib", __FILE__)
|
$:.unshift File.expand_path("../lib", __FILE__)
|
||||||
require "foreman"
|
require "foreman"
|
||||||
|
|
||||||
|
require "bundler/setup"
|
||||||
|
|
||||||
Dir[File.expand_path("../tasks/*.rake", __FILE__)].each do |task|
|
Dir[File.expand_path("../tasks/*.rake", __FILE__)].each do |task|
|
||||||
load task
|
load task
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
#/ Usage: runner [-d <dir>] <command>
|
#/ Usage: foreman-runner [-d <dir>] <command>
|
||||||
#/
|
#/
|
||||||
#/ Run a command with exec, optionally changing directory first
|
#/ Run a command with exec, optionally changing directory first
|
||||||
|
|
||||||
@@ -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(',') %>
|
||||||
Vendored
+1
-1
@@ -4,7 +4,7 @@ file pkg("/apt-#{version}/foreman-#{version}.deb") => distribution_files("deb")
|
|||||||
assemble_distribution
|
assemble_distribution
|
||||||
assemble_gems
|
assemble_gems
|
||||||
assemble resource("deb/foreman"), "bin/foreman", 0755
|
assemble resource("deb/foreman"), "bin/foreman", 0755
|
||||||
File.chmod 0755, "bin/runner"
|
File.chmod 0755, "bin/foreman-runner"
|
||||||
end
|
end
|
||||||
|
|
||||||
assemble resource("deb/control"), "control"
|
assemble resource("deb/control"), "control"
|
||||||
|
|||||||
Vendored
+3
-1
@@ -1,5 +1,7 @@
|
|||||||
file pkg("foreman-#{version}-jruby.gem") => distribution_files do |t|
|
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}"
|
sh "mv foreman-#{version}-java.gem #{t.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Vendored
+3
-1
@@ -1,5 +1,7 @@
|
|||||||
file pkg("foreman-#{version}-mingw32.gem") => distribution_files do |t|
|
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}"
|
sh "mv foreman-#{version}-mingw32.gem #{t.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Vendored
+8
-7
@@ -13,7 +13,7 @@ file pkg("foreman-#{version}.pkg") => distribution_files do |t|
|
|||||||
|
|
||||||
mkdir_p "pkg"
|
mkdir_p "pkg"
|
||||||
mkdir_p "pkg/Resources"
|
mkdir_p "pkg/Resources"
|
||||||
mkdir_p "pkg/foreman-#{version}.pkg"
|
mkdir_p "pkg/foreman.pkg"
|
||||||
|
|
||||||
dist = File.read(resource("pkg/Distribution.erb"))
|
dist = File.read(resource("pkg/Distribution.erb"))
|
||||||
dist = ERB.new(dist).result(binding)
|
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 = File.read(resource("pkg/PackageInfo.erb"))
|
||||||
dist = ERB.new(dist).result(binding)
|
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"
|
mkdir_p "pkg/foreman.pkg/Scripts"
|
||||||
cp resource("pkg/postinstall"), "pkg/foreman-#{version}.pkg/Scripts/postinstall"
|
cp resource("pkg/postinstall"), "pkg/foreman.pkg/Scripts/postinstall"
|
||||||
chmod 0755, "pkg/foreman-#{version}.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
|
Dir.chdir("foreman") do
|
||||||
sh %{ pax -wz -x cpio . > ../pkg/foreman-#{version}.pkg/Payload }
|
sh %{ pax -wz -x cpio . > ../pkg/foreman.pkg/Payload }
|
||||||
end
|
end
|
||||||
|
|
||||||
sh %{ pkgutil --flatten pkg foreman-#{version}.pkg }
|
sh %{ pkgutil --flatten pkg foreman-#{version}.pkg }
|
||||||
|
|
||||||
|
FileUtils.mkdir_p(File.dirname(t.name))
|
||||||
cp_r "foreman-#{version}.pkg", t.name
|
cp_r "foreman-#{version}.pkg", t.name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Vendored
+3
-3
@@ -10,14 +10,14 @@
|
|||||||
]]></script>
|
]]></script>
|
||||||
<choices-outline>
|
<choices-outline>
|
||||||
<line choice="git"/>
|
<line choice="git"/>
|
||||||
<line choice="foreman-<%= version %>"/>
|
<line choice="foreman"/>
|
||||||
</choices-outline>
|
</choices-outline>
|
||||||
<choice id="git" title="git" start_selected="false" start_enabled="false" selected="needs_git()" enabled="needs_git()">
|
<choice id="git" title="git" start_selected="false" start_enabled="false" selected="needs_git()" enabled="needs_git()">
|
||||||
<pkg-ref id="git.pkg" />
|
<pkg-ref id="git.pkg" />
|
||||||
</choice>
|
</choice>
|
||||||
<choice id="foreman-<%= version %>" title="foreman">
|
<choice id="foreman" title="foreman">
|
||||||
<pkg-ref id="io.foreman.installer"/>
|
<pkg-ref id="io.foreman.installer"/>
|
||||||
</choice>
|
</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>
|
</installer-script>
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -4,4 +4,3 @@
|
|||||||
<postinstall file="./postinstall"/>
|
<postinstall file="./postinstall"/>
|
||||||
</scripts>
|
</scripts>
|
||||||
</pkg-info>
|
</pkg-info>
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -3,7 +3,7 @@ file pkg("foreman-#{version}.tgz") => distribution_files do |t|
|
|||||||
mkchdir("foreman") do
|
mkchdir("foreman") do
|
||||||
assemble_distribution
|
assemble_distribution
|
||||||
assemble_gems
|
assemble_gems
|
||||||
rm_rf "bin"
|
rm_f "bin/foreman"
|
||||||
assemble resource("tgz/foreman"), "foreman", 0755
|
assemble resource("tgz/foreman"), "foreman", 0755
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -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 = Dir["**/*"].select { |d| d =~ %r{^(README|bin/|data/|ext/|lib/|spec/|test/)} }
|
||||||
gem.files << "man/foreman.1"
|
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"
|
if ENV["PLATFORM"] == "java"
|
||||||
gem.add_dependency "posix-spawn", "~> 0.3.6"
|
gem.add_dependency "posix-spawn", "~> 0.3.6"
|
||||||
|
|||||||
+1
-7
@@ -4,14 +4,8 @@ module Foreman
|
|||||||
|
|
||||||
class AppDoesNotExist < Exception; end
|
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
|
def self.runner
|
||||||
File.expand_path("../../bin/runner", __FILE__)
|
File.expand_path("../../bin/foreman-runner", __FILE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.jruby?
|
def self.jruby?
|
||||||
|
|||||||
+4
-2
@@ -10,7 +10,7 @@ class Foreman::CLI < Thor
|
|||||||
|
|
||||||
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
||||||
|
|
||||||
desc "start", "Start the application"
|
desc "start [PROCESS]", "Start the application (or a specific PROCESS)"
|
||||||
|
|
||||||
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
||||||
class_option :app_root, :type => :string, :aliases => "-d", :desc => "Default: Procfile directory"
|
class_option :app_root, :type => :string, :aliases => "-d", :desc => "Default: Procfile directory"
|
||||||
@@ -27,8 +27,9 @@ class Foreman::CLI < Thor
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def start
|
def start(process=nil)
|
||||||
check_procfile!
|
check_procfile!
|
||||||
|
engine.options[:concurrency] = "#{process}=1" if process
|
||||||
engine.start
|
engine.start
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ class Foreman::CLI < Thor
|
|||||||
desc "check", "Validate your application's Procfile"
|
desc "check", "Validate your application's Procfile"
|
||||||
|
|
||||||
def check
|
def check
|
||||||
|
check_procfile!
|
||||||
error "no processes defined" unless engine.procfile.entries.length > 0
|
error "no processes defined" unless engine.procfile.entries.length > 0
|
||||||
puts "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
|
puts "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
||||||
+42
-60
@@ -1,38 +1,33 @@
|
|||||||
require "foreman"
|
require "foreman"
|
||||||
|
require "foreman/color"
|
||||||
require "foreman/process"
|
require "foreman/process"
|
||||||
require "foreman/procfile"
|
require "foreman/procfile"
|
||||||
require "foreman/utils"
|
require "foreman/utils"
|
||||||
require "tempfile"
|
require "tempfile"
|
||||||
require "timeout"
|
require "timeout"
|
||||||
require "term/ansicolor"
|
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
require "thread"
|
require "thread"
|
||||||
|
|
||||||
class Foreman::Engine
|
class Foreman::Engine
|
||||||
|
|
||||||
|
attr_reader :environment
|
||||||
attr_reader :procfile
|
attr_reader :procfile
|
||||||
attr_reader :directory
|
attr_reader :directory
|
||||||
attr_reader :options
|
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,
|
Foreman::Color.enable($stdout)
|
||||||
intense_cyan, intense_yellow, intense_green, intense_magenta,
|
|
||||||
intense_red, intense_blue ]
|
|
||||||
|
|
||||||
def initialize(procfile, options={})
|
def initialize(procfile, options={})
|
||||||
@procfile = Foreman::Procfile.new(procfile)
|
@procfile = Foreman::Procfile.new(procfile)
|
||||||
@directory = options[:app_root] || File.expand_path(File.dirname(procfile))
|
@directory = options[:app_root] || File.expand_path(File.dirname(procfile))
|
||||||
@options = options
|
@options = options.dup
|
||||||
@environment = read_environment_files(options[:env])
|
@environment = read_environment_files(options[:env])
|
||||||
@output_mutex = Mutex.new
|
@output_mutex = Mutex.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.load_env!(env_file)
|
|
||||||
@environment = read_environment_files(env_file)
|
|
||||||
apply_environment!
|
|
||||||
end
|
|
||||||
|
|
||||||
def start
|
def start
|
||||||
proctitle "ruby: foreman master"
|
proctitle "ruby: foreman master"
|
||||||
termtitle "#{File.basename(@directory)} - foreman"
|
termtitle "#{File.basename(@directory)} - foreman"
|
||||||
@@ -52,6 +47,26 @@ class Foreman::Engine
|
|||||||
base_port.to_i + offset + num - 1
|
base_port.to_i + offset + num - 1
|
||||||
end
|
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 ######################################################################
|
private ######################################################################
|
||||||
|
|
||||||
def spawn_processes
|
def spawn_processes
|
||||||
@@ -99,6 +114,7 @@ private ######################################################################
|
|||||||
(rs || []).each do |r|
|
(rs || []).each do |r|
|
||||||
data = r.gets
|
data = r.gets
|
||||||
next unless data
|
next unless data
|
||||||
|
data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
||||||
ps, message = data.split(",", 2)
|
ps, message = data.split(",", 2)
|
||||||
color = colors[ps.split(".").first]
|
color = colors[ps.split(".").first]
|
||||||
info message, ps, color
|
info message, ps, color
|
||||||
@@ -127,11 +143,11 @@ private ######################################################################
|
|||||||
rescue Errno::ECHILD
|
rescue Errno::ECHILD
|
||||||
end
|
end
|
||||||
|
|
||||||
def info(message, name="system", color=Term::ANSIColor.white)
|
def info(message, name="system", color=:white)
|
||||||
output = ""
|
output = ""
|
||||||
output += color
|
output += $stdout.color(color)
|
||||||
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
||||||
output += Term::ANSIColor.reset
|
output += $stdout.color(:reset)
|
||||||
output += message.chomp
|
output += message.chomp
|
||||||
puts output
|
puts output
|
||||||
end
|
end
|
||||||
@@ -181,8 +197,8 @@ private ######################################################################
|
|||||||
end
|
end
|
||||||
|
|
||||||
def assign_colors
|
def assign_colors
|
||||||
procfile.entries.each do |entry|
|
procfile.entries.each_with_index do |entry, idx|
|
||||||
colors[entry.name] = next_color
|
colors[entry.name] = COLORS[idx % COLORS.length]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -190,49 +206,15 @@ private ######################################################################
|
|||||||
readers.invert[reader]
|
readers.invert[reader]
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_color
|
def read_environment_files(filenames)
|
||||||
@current_color ||= -1
|
environment = {}
|
||||||
@current_color += 1
|
|
||||||
@current_color = 0 if COLORS.length < @current_color
|
(filenames || "").split(",").map(&:strip).each do |filename|
|
||||||
COLORS[@current_color]
|
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
|
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
|
end
|
||||||
|
|||||||
@@ -30,3 +30,5 @@ require "foreman/export/inittab"
|
|||||||
require "foreman/export/upstart"
|
require "foreman/export/upstart"
|
||||||
require "foreman/export/bluepill"
|
require "foreman/export/bluepill"
|
||||||
require "foreman/export/runit"
|
require "foreman/export/runit"
|
||||||
|
require "foreman/export/supervisord"
|
||||||
|
|
||||||
|
|||||||
@@ -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,5 +1,5 @@
|
|||||||
module Foreman
|
module Foreman
|
||||||
|
|
||||||
VERSION = "0.37.2"
|
VERSION = "0.42.0"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+13
-3
@@ -1,7 +1,7 @@
|
|||||||
.\" generated with Ronn/v0.7.3
|
.\" generated with Ronn/v0.7.3
|
||||||
.\" http://github.com/rtomayko/ronn/tree/0.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"
|
.SH "NAME"
|
||||||
\fBforeman\fR \- manage Procfile\-based applications
|
\fBforeman\fR \- manage Procfile\-based applications
|
||||||
@@ -10,10 +10,13 @@
|
|||||||
\fBforeman start [process]\fR
|
\fBforeman start [process]\fR
|
||||||
.
|
.
|
||||||
.br
|
.br
|
||||||
|
\fBforeman run <command>\fR
|
||||||
|
.
|
||||||
|
.br
|
||||||
\fBforeman export <format> [location]\fR
|
\fBforeman export <format> [location]\fR
|
||||||
.
|
.
|
||||||
.SH "DESCRIPTION"
|
.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"
|
.SH "RUNNING"
|
||||||
\fBforeman start\fR is used to run your application directly from the command line\.
|
\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
|
\fB\-p\fR, \fB\-\-port\fR
|
||||||
Specify which port to use as the base for this application\. Should be a multiple of 1000\.
|
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"
|
.SH "EXPORTING"
|
||||||
\fBforeman export\fR is used to export your application to another process management format\.
|
\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\.
|
Specify which port to use as the base for this application\. Should be a multiple of 1000\.
|
||||||
.
|
.
|
||||||
.TP
|
.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
|
\fB\-u\fR, \fB\-\-user\fR
|
||||||
Specify the user the application should be run as\. Defaults to the app name
|
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\.
|
These options control all modes of foreman\'s operation\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
+10
-2
@@ -4,11 +4,12 @@ foreman(1) -- manage Procfile-based applications
|
|||||||
## SYNOPSIS
|
## SYNOPSIS
|
||||||
|
|
||||||
`foreman start [process]`<br>
|
`foreman start [process]`<br>
|
||||||
|
`foreman run <command>`<br>
|
||||||
`foreman export <format> [location]`
|
`foreman export <format> [location]`
|
||||||
|
|
||||||
## DESCRIPTION
|
## 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
|
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
|
your application directly or export it to some other process management
|
||||||
format.
|
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
|
Specify which port to use as the base for this application. Should be
|
||||||
a multiple of 1000.
|
a multiple of 1000.
|
||||||
|
|
||||||
|
`foreman run` is used to run one-off commands using the same environment
|
||||||
|
as your defined processes.
|
||||||
|
|
||||||
## EXPORTING
|
## EXPORTING
|
||||||
|
|
||||||
`foreman export` is used to export your application to another process
|
`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
|
Specify which port to use as the base for this application. Should be
|
||||||
a multiple of 1000.
|
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`:
|
* `-u`, `--user`:
|
||||||
Specify the user the application should be run as. Defaults to the
|
Specify the user the application should be run as. Defaults to the
|
||||||
app name
|
app name
|
||||||
|
|
||||||
## OPTIONS
|
## GLOBAL OPTIONS
|
||||||
|
|
||||||
These options control all modes of foreman's operation.
|
These options control all modes of foreman's operation.
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ require "foreman/cli"
|
|||||||
|
|
||||||
describe "Foreman::CLI", :fakefs do
|
describe "Foreman::CLI", :fakefs do
|
||||||
subject { Foreman::CLI.new }
|
subject { Foreman::CLI.new }
|
||||||
|
let(:engine) { subject.send(:engine) }
|
||||||
|
let(:entries) { engine.procfile.entries.inject({}) { |h,e| h.update(e.name => e) } }
|
||||||
|
|
||||||
describe "start" do
|
describe "start" do
|
||||||
describe "with a non-existent Procfile" do
|
describe "with a non-existent Procfile" do
|
||||||
@@ -22,6 +24,15 @@ describe "Foreman::CLI", :fakefs do
|
|||||||
mock.instance_of(Foreman::Engine).start
|
mock.instance_of(Foreman::Engine).start
|
||||||
subject.start
|
subject.start
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "can run a single process" do
|
||||||
|
dont_allow(subject).error
|
||||||
|
stub(engine).watch_for_output
|
||||||
|
stub(engine).watch_for_termination
|
||||||
|
mock(entries["alpha"]).spawn(1, is_a(IO), engine.directory, {}, 5000) { [] }
|
||||||
|
mock(entries["bravo"]).spawn(0, is_a(IO), engine.directory, {}, 5100) { [] }
|
||||||
|
subject.start("alpha")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -109,6 +120,14 @@ describe "Foreman::CLI", :fakefs do
|
|||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "run" do
|
describe "run" do
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -4,6 +4,13 @@ require "foreman/engine"
|
|||||||
describe "Foreman::Engine", :fakefs do
|
describe "Foreman::Engine", :fakefs do
|
||||||
subject { Foreman::Engine.new("Procfile", {}) }
|
subject { Foreman::Engine.new("Procfile", {}) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
any_instance_of(Foreman::Engine) do |engine|
|
||||||
|
stub(engine).proctitle
|
||||||
|
stub(engine).termtitle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "initialize" do
|
describe "initialize" do
|
||||||
describe "without an existing Procfile" do
|
describe "without an existing Procfile" do
|
||||||
it "raises an error" do
|
it "raises an error" do
|
||||||
@@ -46,14 +53,16 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
before(:each) do
|
before(:each) do
|
||||||
write_procfile
|
write_procfile
|
||||||
stub(Process).fork
|
stub(Process).fork
|
||||||
|
any_instance_of(Foreman::Engine) do |engine|
|
||||||
|
stub(engine).info
|
||||||
|
stub(engine).spawn_processes
|
||||||
|
stub(engine).watch_for_termination
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should read if specified" do
|
it "should read if specified" do
|
||||||
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
|
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
|
||||||
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
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.environment.should == {"FOO"=>"baz"}
|
||||||
engine.start
|
engine.start
|
||||||
end
|
end
|
||||||
@@ -62,13 +71,21 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
||||||
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
|
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
|
||||||
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2")
|
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.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" }
|
||||||
engine.start
|
engine.start
|
||||||
end
|
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
|
it "should fail if specified and doesnt exist" do
|
||||||
mock.instance_of(Foreman::Engine).error("No such file: /tmp/env")
|
mock.instance_of(Foreman::Engine).error("No such file: /tmp/env")
|
||||||
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
||||||
@@ -77,8 +94,6 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
it "should read .env if none specified" do
|
it "should read .env if none specified" do
|
||||||
File.open(".env", "w") { |f| f.puts("FOO=qoo") }
|
File.open(".env", "w") { |f| f.puts("FOO=qoo") }
|
||||||
engine = Foreman::Engine.new("Procfile")
|
engine = Foreman::Engine.new("Procfile")
|
||||||
mock(engine).spawn_processes
|
|
||||||
mock(engine).watch_for_termination
|
|
||||||
engine.environment.should == {"FOO"=>"qoo"}
|
engine.environment.should == {"FOO"=>"qoo"}
|
||||||
engine.start
|
engine.start
|
||||||
end
|
end
|
||||||
@@ -95,7 +110,7 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
stub(subject).watch_for_output
|
stub(subject).watch_for_output
|
||||||
stub(subject).watch_for_termination
|
stub(subject).watch_for_termination
|
||||||
subject.start
|
subject.start
|
||||||
sleep 1
|
Process.waitall
|
||||||
mock(subject).info(/started with pid \d+/, "utf8.1", anything)
|
mock(subject).info(/started with pid \d+/, "utf8.1", anything)
|
||||||
mock(subject).info("\xff\x03\n", "utf8.1", anything)
|
mock(subject).info("\xff\x03\n", "utf8.1", anything)
|
||||||
subject.send(:poll_readers)
|
subject.send(:poll_readers)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -8,24 +8,6 @@ describe Foreman do
|
|||||||
it { should be_a String }
|
it { should be_a String }
|
||||||
end
|
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
|
describe "runner" do
|
||||||
it "should exist" do
|
it "should exist" do
|
||||||
File.exists?(Foreman.runner).should == true
|
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
|
||||||
@@ -27,14 +27,6 @@ task :pages => "man:commit" do
|
|||||||
}
|
}
|
||||||
end
|
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
|
def latest_release
|
||||||
latest = File.read("Changelog.md").split("\n").first.split(" ")[1]
|
latest = File.read("Changelog.md").split("\n").first.split(" ")[1]
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user