foreman 0.39.0 → 0.40.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/lib/foreman.rb +0 -6
- data/lib/foreman/cli.rb +1 -0
- data/lib/foreman/engine.rb +24 -35
- data/lib/foreman/version.rb +1 -1
- data/man/foreman.1 +13 -3
- data/spec/foreman/cli_spec.rb +8 -0
- data/spec/foreman/engine_spec.rb +16 -8
- data/spec/foreman_spec.rb +0 -18
- metadata +8 -8
data/README.md
CHANGED
@@ -33,7 +33,7 @@ Manage Procfile-based applications
|
|
33
33
|
David Dollar
|
34
34
|
|
35
35
|
#### Patches contributed by
|
36
|
-
|
36
|
+
[Contributor List](https://github.com/ddollar/foreman/contributors)
|
37
37
|
|
38
38
|
## License
|
39
39
|
|
data/lib/foreman.rb
CHANGED
@@ -4,12 +4,6 @@ module Foreman
|
|
4
4
|
|
5
5
|
class AppDoesNotExist < Exception; end
|
6
6
|
|
7
|
-
# load contents of env_file into ENV
|
8
|
-
def self.load_env!(env_file = './.env')
|
9
|
-
require 'foreman/engine'
|
10
|
-
Foreman::Engine.load_env!(env_file)
|
11
|
-
end
|
12
|
-
|
13
7
|
def self.runner
|
14
8
|
File.expand_path("../../bin/foreman-runner", __FILE__)
|
15
9
|
end
|
data/lib/foreman/cli.rb
CHANGED
@@ -54,6 +54,7 @@ class Foreman::CLI < Thor
|
|
54
54
|
desc "check", "Validate your application's Procfile"
|
55
55
|
|
56
56
|
def check
|
57
|
+
check_procfile!
|
57
58
|
error "no processes defined" unless engine.procfile.entries.length > 0
|
58
59
|
puts "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
|
59
60
|
end
|
data/lib/foreman/engine.rb
CHANGED
@@ -10,6 +10,7 @@ require "thread"
|
|
10
10
|
|
11
11
|
class Foreman::Engine
|
12
12
|
|
13
|
+
attr_reader :environment
|
13
14
|
attr_reader :procfile
|
14
15
|
attr_reader :directory
|
15
16
|
attr_reader :options
|
@@ -28,11 +29,6 @@ class Foreman::Engine
|
|
28
29
|
@output_mutex = Mutex.new
|
29
30
|
end
|
30
31
|
|
31
|
-
def self.load_env!(env_file)
|
32
|
-
@environment = read_environment_files(env_file)
|
33
|
-
apply_environment!
|
34
|
-
end
|
35
|
-
|
36
32
|
def start
|
37
33
|
proctitle "ruby: foreman master"
|
38
34
|
termtitle "#{File.basename(@directory)} - foreman"
|
@@ -52,6 +48,10 @@ class Foreman::Engine
|
|
52
48
|
base_port.to_i + offset + num - 1
|
53
49
|
end
|
54
50
|
|
51
|
+
def apply_environment!
|
52
|
+
environment.each { |k,v| ENV[k] = v }
|
53
|
+
end
|
54
|
+
|
55
55
|
private ######################################################################
|
56
56
|
|
57
57
|
def spawn_processes
|
@@ -198,42 +198,31 @@ private ######################################################################
|
|
198
198
|
COLORS[@current_color]
|
199
199
|
end
|
200
200
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
def read_environment_files(filenames)
|
205
|
-
environment = {}
|
206
|
-
|
207
|
-
(filenames || "").split(",").map(&:strip).each do |filename|
|
208
|
-
error "No such file: #{filename}" unless File.exists?(filename)
|
209
|
-
environment.merge!(read_environment(filename))
|
210
|
-
end
|
201
|
+
def read_environment_files(filenames)
|
202
|
+
environment = {}
|
211
203
|
|
212
|
-
|
213
|
-
|
204
|
+
(filenames || "").split(",").map(&:strip).each do |filename|
|
205
|
+
error "No such file: #{filename}" unless File.exists?(filename)
|
206
|
+
environment.merge!(read_environment(filename))
|
214
207
|
end
|
215
208
|
|
216
|
-
|
217
|
-
|
209
|
+
environment.merge!(read_environment(".env")) unless filenames
|
210
|
+
environment
|
211
|
+
end
|
212
|
+
|
213
|
+
def read_environment(filename)
|
214
|
+
return {} unless File.exists?(filename)
|
218
215
|
|
219
|
-
|
220
|
-
|
221
|
-
|
216
|
+
File.read(filename).split("\n").inject({}) do |hash, line|
|
217
|
+
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
218
|
+
key, val = [$1, $2]
|
219
|
+
case val
|
220
|
+
when /\A'(.*)'\z/ then hash[key] = $1
|
221
|
+
when /\A"(.*)"\z/ then hash[key] = $1.gsub(/\\(.)/, '\1')
|
222
|
+
else hash[key] = val
|
222
223
|
end
|
223
|
-
hash
|
224
224
|
end
|
225
|
-
|
226
|
-
|
227
|
-
def apply_environment!
|
228
|
-
@environment.each { |k,v| ENV[k] = v }
|
229
|
-
end
|
230
|
-
|
231
|
-
def error(message)
|
232
|
-
puts "ERROR: #{message}"
|
233
|
-
exit 1
|
225
|
+
hash
|
234
226
|
end
|
235
227
|
end
|
236
|
-
|
237
|
-
include Env
|
238
|
-
extend Env
|
239
228
|
end
|
data/lib/foreman/version.rb
CHANGED
data/man/foreman.1
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
.\" generated with Ronn/v0.7.3
|
2
2
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
3
|
.
|
4
|
-
.TH "FOREMAN" "1" "
|
4
|
+
.TH "FOREMAN" "1" "February 2012" "Foreman 0.39.0" "Foreman Manual"
|
5
5
|
.
|
6
6
|
.SH "NAME"
|
7
7
|
\fBforeman\fR \- manage Procfile\-based applications
|
@@ -10,10 +10,13 @@
|
|
10
10
|
\fBforeman start [process]\fR
|
11
11
|
.
|
12
12
|
.br
|
13
|
+
\fBforeman run <command>\fR
|
14
|
+
.
|
15
|
+
.br
|
13
16
|
\fBforeman export <format> [location]\fR
|
14
17
|
.
|
15
18
|
.SH "DESCRIPTION"
|
16
|
-
|
19
|
+
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\.
|
17
20
|
.
|
18
21
|
.SH "RUNNING"
|
19
22
|
\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
|
|
35
38
|
\fB\-p\fR, \fB\-\-port\fR
|
36
39
|
Specify which port to use as the base for this application\. Should be a multiple of 1000\.
|
37
40
|
.
|
41
|
+
.P
|
42
|
+
\fBforeman run\fR is used to run one\-off commands using the same environment as your defined processes\.
|
43
|
+
.
|
38
44
|
.SH "EXPORTING"
|
39
45
|
\fBforeman export\fR is used to export your application to another process management format\.
|
40
46
|
.
|
@@ -61,10 +67,14 @@ Specify the directory to place process logs in\.
|
|
61
67
|
Specify which port to use as the base for this application\. Should be a multiple of 1000\.
|
62
68
|
.
|
63
69
|
.TP
|
70
|
+
\fB\-t\fR, \fB\-\-template\fR
|
71
|
+
Specify an alternate template to use for creating export files\. See \fIhttps://github\.com/ddollar/foreman/tree/master/data/export\fR for examples\.
|
72
|
+
.
|
73
|
+
.TP
|
64
74
|
\fB\-u\fR, \fB\-\-user\fR
|
65
75
|
Specify the user the application should be run as\. Defaults to the app name
|
66
76
|
.
|
67
|
-
.SH "OPTIONS"
|
77
|
+
.SH "GLOBAL OPTIONS"
|
68
78
|
These options control all modes of foreman\'s operation\.
|
69
79
|
.
|
70
80
|
.TP
|
data/spec/foreman/cli_spec.rb
CHANGED
@@ -120,6 +120,14 @@ describe "Foreman::CLI", :fakefs do
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
123
|
+
|
124
|
+
describe "without a Procfile" do
|
125
|
+
it "displays an error" do
|
126
|
+
mock_error(subject, "Procfile does not exist.") do
|
127
|
+
subject.check
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
123
131
|
end
|
124
132
|
|
125
133
|
describe "run" do
|
data/spec/foreman/engine_spec.rb
CHANGED
@@ -53,14 +53,16 @@ describe "Foreman::Engine", :fakefs do
|
|
53
53
|
before(:each) do
|
54
54
|
write_procfile
|
55
55
|
stub(Process).fork
|
56
|
+
any_instance_of(Foreman::Engine) do |engine|
|
57
|
+
stub(engine).info
|
58
|
+
stub(engine).spawn_processes
|
59
|
+
stub(engine).watch_for_termination
|
60
|
+
end
|
56
61
|
end
|
57
62
|
|
58
63
|
it "should read if specified" do
|
59
64
|
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
|
60
65
|
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
61
|
-
stub(engine).info
|
62
|
-
mock(engine).spawn_processes
|
63
|
-
mock(engine).watch_for_termination
|
64
66
|
engine.environment.should == {"FOO"=>"baz"}
|
65
67
|
engine.start
|
66
68
|
end
|
@@ -69,13 +71,21 @@ describe "Foreman::Engine", :fakefs do
|
|
69
71
|
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
70
72
|
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
|
71
73
|
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2")
|
72
|
-
stub(engine).info
|
73
|
-
mock(engine).spawn_processes
|
74
|
-
mock(engine).watch_for_termination
|
75
74
|
engine.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" }
|
76
75
|
engine.start
|
77
76
|
end
|
78
77
|
|
78
|
+
it "should handle quoted values" do
|
79
|
+
File.open("/tmp/env", "w") do |f|
|
80
|
+
f.puts 'FOO=bar'
|
81
|
+
f.puts 'BAZ="qux"'
|
82
|
+
f.puts "FRED='barney'"
|
83
|
+
f.puts 'OTHER="escaped\"quote"'
|
84
|
+
end
|
85
|
+
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
86
|
+
engine.environment.should == { "FOO" => "bar", "BAZ" => "qux", "FRED" => "barney", "OTHER" => 'escaped"quote' }
|
87
|
+
end
|
88
|
+
|
79
89
|
it "should fail if specified and doesnt exist" do
|
80
90
|
mock.instance_of(Foreman::Engine).error("No such file: /tmp/env")
|
81
91
|
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
@@ -84,8 +94,6 @@ describe "Foreman::Engine", :fakefs do
|
|
84
94
|
it "should read .env if none specified" do
|
85
95
|
File.open(".env", "w") { |f| f.puts("FOO=qoo") }
|
86
96
|
engine = Foreman::Engine.new("Procfile")
|
87
|
-
mock(engine).spawn_processes
|
88
|
-
mock(engine).watch_for_termination
|
89
97
|
engine.environment.should == {"FOO"=>"qoo"}
|
90
98
|
engine.start
|
91
99
|
end
|
data/spec/foreman_spec.rb
CHANGED
@@ -8,24 +8,6 @@ describe Foreman do
|
|
8
8
|
it { should be_a String }
|
9
9
|
end
|
10
10
|
|
11
|
-
describe "::load_env!(env_file)", :fakefs do
|
12
|
-
after do
|
13
|
-
ENV['FOO'] = nil
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should load env_file into ENV" do
|
17
|
-
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
18
|
-
Foreman.load_env!("/tmp/env1")
|
19
|
-
ENV['FOO'].should == 'bar'
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should assume env_file in ./.env" do
|
23
|
-
File.open("./.env", "w") { |f| f.puts("FOO=bar") }
|
24
|
-
Foreman.load_env!
|
25
|
-
ENV['FOO'].should == 'bar'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
11
|
describe "runner" do
|
30
12
|
it "should exist" do
|
31
13
|
File.exists?(Foreman.runner).should == true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.40.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: term-ansicolor
|
16
|
-
requirement: &
|
16
|
+
requirement: &70330442658940 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.0.7
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70330442658940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: thor
|
27
|
-
requirement: &
|
27
|
+
requirement: &70330442658420 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 0.13.6
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70330442658420
|
36
36
|
description: Process manager for applications with multiple components
|
37
37
|
email: ddollar@gmail.com
|
38
38
|
executables:
|
@@ -116,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
116
|
version: '0'
|
117
117
|
segments:
|
118
118
|
- 0
|
119
|
-
hash:
|
119
|
+
hash: 4516446218853691019
|
120
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
121
|
none: false
|
122
122
|
requirements:
|
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
125
|
version: '0'
|
126
126
|
segments:
|
127
127
|
- 0
|
128
|
-
hash:
|
128
|
+
hash: 4516446218853691019
|
129
129
|
requirements: []
|
130
130
|
rubyforge_project:
|
131
131
|
rubygems_version: 1.8.11
|