Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d86b0bed1f | ||
|
|
12f825204b | ||
|
|
62c9d1db45 | ||
|
|
cf5689a77a | ||
|
|
c23dbb79af | ||
|
|
7e55d8d3e2 | ||
|
|
d4f23d45a4 | ||
|
|
93fa1645e7 | ||
|
|
7bdada4a10 | ||
|
|
2b47d24ab7 | ||
|
|
24695348fb | ||
|
|
38b6482af5 |
@@ -1,3 +1,10 @@
|
|||||||
|
## 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)
|
## 0.38.0 (2012-02-02)
|
||||||
|
|
||||||
* bring back single process starting [David Dollar]
|
* bring back single process starting [David Dollar]
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
foreman (0.39.0)
|
foreman (0.40.0)
|
||||||
term-ansicolor (~> 1.0.7)
|
term-ansicolor (~> 1.0.7)
|
||||||
thor (>= 0.13.6)
|
thor (>= 0.13.6)
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,6 @@ 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/foreman-runner", __FILE__)
|
File.expand_path("../../bin/foreman-runner", __FILE__)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -54,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
|
||||||
|
|||||||
+27
-38
@@ -10,6 +10,7 @@ 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
|
||||||
@@ -28,11 +29,6 @@ class Foreman::Engine
|
|||||||
@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 +48,10 @@ 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
|
||||||
|
|
||||||
private ######################################################################
|
private ######################################################################
|
||||||
|
|
||||||
def spawn_processes
|
def spawn_processes
|
||||||
@@ -198,42 +198,31 @@ private ######################################################################
|
|||||||
COLORS[@current_color]
|
COLORS[@current_color]
|
||||||
end
|
end
|
||||||
|
|
||||||
module Env
|
def read_environment_files(filenames)
|
||||||
attr_reader :environment
|
environment = {}
|
||||||
|
|
||||||
def read_environment_files(filenames)
|
(filenames || "").split(",").map(&:strip).each do |filename|
|
||||||
environment = {}
|
error "No such file: #{filename}" unless File.exists?(filename)
|
||||||
|
environment.merge!(read_environment(filename))
|
||||||
(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
|
end
|
||||||
|
|
||||||
def read_environment(filename)
|
environment.merge!(read_environment(".env")) unless filenames
|
||||||
return {} unless File.exists?(filename)
|
environment
|
||||||
|
|
||||||
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
|
end
|
||||||
|
|
||||||
include Env
|
def read_environment(filename)
|
||||||
extend Env
|
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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module Foreman
|
module Foreman
|
||||||
|
|
||||||
VERSION = "0.39.0"
|
VERSION = "0.40.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.
|
||||||
|
|
||||||
|
|||||||
@@ -120,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
|
||||||
|
|||||||
@@ -53,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
|
||||||
@@ -69,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")
|
||||||
@@ -84,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user