foreman 0.15.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. data/README.markdown +39 -1
  2. data/data/example/Procfile +2 -2
  3. data/data/example/error +2 -0
  4. data/data/example/ticker +9 -1
  5. data/data/export/bluepill/master.pill.erb +27 -0
  6. data/data/export/runit/log_run.erb +7 -0
  7. data/data/export/runit/run.erb +3 -0
  8. data/data/export/upstart/process.conf.erb +1 -2
  9. data/lib/foreman/cli.rb +12 -9
  10. data/lib/foreman/distribution.rb +9 -0
  11. data/lib/foreman/engine.rb +96 -74
  12. data/lib/foreman/export/base.rb +8 -2
  13. data/lib/foreman/export/bluepill.rb +28 -0
  14. data/lib/foreman/export/inittab.rb +2 -2
  15. data/lib/foreman/export/runit.rb +60 -0
  16. data/lib/foreman/export/upstart.rb +7 -5
  17. data/lib/foreman/export.rb +3 -0
  18. data/lib/foreman/procfile.rb +37 -0
  19. data/lib/foreman/utils.rb +1 -1
  20. data/lib/foreman/version.rb +1 -1
  21. data/lib/foreman.rb +5 -0
  22. data/man/foreman.1 +27 -3
  23. data/spec/foreman/cli_spec.rb +10 -1
  24. data/spec/foreman/engine_spec.rb +59 -24
  25. data/spec/foreman/export/bluepill_spec.rb +20 -0
  26. data/spec/foreman/export/runit_spec.rb +35 -0
  27. data/spec/foreman/export/upstart_spec.rb +43 -9
  28. data/spec/foreman_spec.rb +22 -0
  29. data/spec/resources/export/bluepill/app.pill +65 -0
  30. data/spec/resources/export/runit/app-alpha-1-log-run +7 -0
  31. data/spec/resources/export/runit/app-alpha-1-run +3 -0
  32. data/spec/resources/export/runit/app-alpha-2-log-run +7 -0
  33. data/spec/resources/export/runit/app-alpha-2-run +3 -0
  34. data/spec/resources/export/runit/app-bravo-1-log-run +7 -0
  35. data/spec/resources/export/runit/app-bravo-1-run +3 -0
  36. data/spec/resources/export/upstart/app-alpha-1.conf +5 -0
  37. data/spec/resources/export/upstart/app-alpha-2.conf +5 -0
  38. data/spec/resources/export/upstart/app-alpha.conf +2 -0
  39. data/spec/resources/export/upstart/app-bravo-1.conf +5 -0
  40. data/spec/resources/export/upstart/app-bravo.conf +2 -0
  41. data/spec/resources/export/upstart/app.conf +8 -0
  42. data/spec/spec_helper.rb +16 -5
  43. metadata +60 -124
  44. data/spec/resources/export/upstart/foreman-alpha-1.conf +0 -6
  45. data/spec/resources/export/upstart/foreman-alpha-2.conf +0 -6
  46. data/spec/resources/export/upstart/foreman-alpha.conf +0 -2
  47. data/spec/resources/export/upstart/foreman-bravo-1.conf +0 -6
  48. data/spec/resources/export/upstart/foreman.bravo.conf +0 -2
  49. data/spec/resources/export/upstart/foreman.conf +0 -8
@@ -0,0 +1,37 @@
1
+ require "foreman"
2
+
3
+ # A valid Procfile entry is captured by this regex.
4
+ # All other lines are ignored.
5
+ #
6
+ # /^([A-Za-z0-9_]+):\s*(.+)$/
7
+ #
8
+ # $1 = name
9
+ # $2 = command
10
+ #
11
+ class Foreman::Procfile
12
+
13
+ attr_reader :processes
14
+
15
+ def initialize(filename)
16
+ @processes = parse_procfile(filename)
17
+ end
18
+
19
+ def process_names
20
+ processes.map(&:name)
21
+ end
22
+
23
+ def [](name)
24
+ processes.detect { |process| process.name == name }
25
+ end
26
+
27
+ private
28
+
29
+ def parse_procfile(filename)
30
+ File.read(filename).split("\n").map do |line|
31
+ if line =~ /^([A-Za-z0-9_]+):\s*(.+)$/
32
+ Foreman::Process.new($1, $2)
33
+ end
34
+ end.compact
35
+ end
36
+
37
+ end
data/lib/foreman/utils.rb CHANGED
@@ -3,7 +3,7 @@ require "foreman"
3
3
  class Foreman::Utils
4
4
 
5
5
  def self.parse_concurrency(concurrency)
6
- @concurrency ||= begin
6
+ begin
7
7
  pairs = concurrency.to_s.gsub(/\s/, "").split(",")
8
8
  pairs.inject(Hash.new(1)) do |hash, pair|
9
9
  process, amount = pair.split("=")
@@ -1,5 +1,5 @@
1
1
  module Foreman
2
2
 
3
- VERSION = "0.15.0"
3
+ VERSION = "0.27.0"
4
4
 
5
5
  end
data/lib/foreman.rb CHANGED
@@ -4,5 +4,10 @@ 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
7
12
  end
8
13
 
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" "May 2011" "Foreman 0.13.0" "Foreman Manual"
4
+ .TH "FOREMAN" "1" "November 2011" "Foreman 0.26.0" "Foreman Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBforeman\fR \- manage Procfile\-based applications
@@ -68,6 +68,10 @@ Specify the user the application should be run as\. Defaults to the app name
68
68
  These options control all modes of foreman\'s operation\.
69
69
  .
70
70
  .TP
71
+ \fB\-e\fR, \fB\-\-env\fR
72
+ Specify an alternate environment file\. You can specify more than one file by using: \fB\-\-env file1,file2\fR\.
73
+ .
74
+ .TP
71
75
  \fB\-f\fR, \fB\-\-procfile\fR
72
76
  Specify an alternate location for the application\'s Procfile\. This file\'s containing directory will be assumed to be the root directory of the application\.
73
77
  .
@@ -75,9 +79,15 @@ Specify an alternate location for the application\'s Procfile\. This file\'s con
75
79
  foreman currently supports the following output formats:
76
80
  .
77
81
  .IP "\(bu" 4
82
+ bluepill
83
+ .
84
+ .IP "\(bu" 4
78
85
  inittab
79
86
  .
80
87
  .IP "\(bu" 4
88
+ runit
89
+ .
90
+ .IP "\(bu" 4
81
91
  upstart
82
92
  .
83
93
  .IP "" 0
@@ -125,7 +135,7 @@ job: bundle exec rake jobs:work
125
135
  .IP "" 0
126
136
  .
127
137
  .P
128
- You can validate your Procfile format using the \fBcheck\fR command
138
+ A process name may contain letters, numbers amd the underscore character\. You can validate your Procfile format using the \fBcheck\fR command:
129
139
  .
130
140
  .IP "" 4
131
141
  .
@@ -137,6 +147,20 @@ $ foreman check
137
147
  .
138
148
  .IP "" 0
139
149
  .
150
+ .SH "ENVIRONMENT"
151
+ If a \fB\.env\fR file exists in the current directory, the default environment will be read from it\. This file should contain key/value pairs, separated by \fB=\fR, with one key/value pair per line\.
152
+ .
153
+ .IP "" 4
154
+ .
155
+ .nf
156
+
157
+ FOO=bar
158
+ BAZ=qux
159
+ .
160
+ .fi
161
+ .
162
+ .IP "" 0
163
+ .
140
164
  .SH "DEFAULT OPTIONS"
141
165
  If a \fB\.foreman\fR file exists in the current directory, default options will be read from it\. This file should be in YAML format with the long option name as keys\. Example:
142
166
  .
@@ -144,7 +168,7 @@ If a \fB\.foreman\fR file exists in the current directory, default options will
144
168
  .
145
169
  .nf
146
170
 
147
- concurrency: alpha=0
171
+ concurrency: alpha=0,bravo=1
148
172
  port: 15000
149
173
  .
150
174
  .fi
@@ -19,13 +19,22 @@ describe "Foreman::CLI" do
19
19
 
20
20
  it "runs successfully" do
21
21
  dont_allow(subject).error
22
- mock.instance_of(Foreman::Engine).start({})
22
+ mock.instance_of(Foreman::Engine).start
23
23
  subject.start
24
24
  end
25
25
  end
26
26
  end
27
27
 
28
28
  describe "export" do
29
+ describe "options" do
30
+ it "respects --env" do
31
+ write_procfile
32
+ write_env("envfile")
33
+ mock.instance_of(Foreman::Export::Upstart).export("/upstart", { "env" => "envfile" })
34
+ foreman %{ export upstart /upstart --env envfile }
35
+ end
36
+ end
37
+
29
38
  describe "with a non-existent Procfile" do
30
39
  it "prints an error" do
31
40
  mock_error(subject, "Procfile does not exist.") do
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
  require "foreman/engine"
3
3
 
4
4
  describe "Foreman::Engine" do
5
- subject { Foreman::Engine.new("Procfile") }
5
+ subject { Foreman::Engine.new("Procfile", {}) }
6
6
 
7
7
  describe "initialize" do
8
8
  describe "without an existing Procfile" do
@@ -15,21 +15,8 @@ describe "Foreman::Engine" do
15
15
  before { write_procfile }
16
16
 
17
17
  it "reads the processes" do
18
- subject.processes["alpha"].command.should == "./alpha"
19
- subject.processes["bravo"].command.should == "./bravo"
20
- end
21
- end
22
-
23
- describe "with a deprecated Procfile" do
24
- before do
25
- File.open("Procfile", "w") do |file|
26
- file.puts "name command"
27
- end
28
- end
29
-
30
- it "should print a deprecation warning" do
31
- mock(subject).warn_deprecated_procfile!
32
- subject.processes.length.should == 1
18
+ subject.procfile["alpha"].command.should == "./alpha"
19
+ subject.procfile["bravo"].command.should == "./bravo"
33
20
  end
34
21
  end
35
22
  end
@@ -37,28 +24,76 @@ describe "Foreman::Engine" do
37
24
  describe "start" do
38
25
  it "forks the processes" do
39
26
  write_procfile
40
- mock(subject).fork(subject.processes["alpha"], {})
41
- mock(subject).fork(subject.processes["bravo"], {})
27
+ mock(subject).fork(subject.procfile["alpha"])
28
+ mock(subject).fork(subject.procfile["bravo"])
42
29
  mock(subject).watch_for_termination
43
30
  subject.start
44
31
  end
45
32
 
46
33
  it "handles concurrency" do
47
34
  write_procfile
48
- mock(subject).fork_individual(subject.processes["alpha"], 1, 5000)
49
- mock(subject).fork_individual(subject.processes["alpha"], 2, 5001)
50
- mock(subject).fork_individual(subject.processes["bravo"], 1, 5100)
51
- mock(subject).watch_for_termination
52
- subject.start(:concurrency => "alpha=2")
35
+ engine = Foreman::Engine.new("Procfile",:concurrency => "alpha=2")
36
+ mock(engine).fork_individual(engine.procfile["alpha"], 1, 5000)
37
+ mock(engine).fork_individual(engine.procfile["alpha"], 2, 5001)
38
+ mock(engine).fork_individual(engine.procfile["bravo"], 1, 5100)
39
+ mock(engine).watch_for_termination
40
+ engine.start
53
41
  end
54
42
  end
55
43
 
56
44
  describe "execute" do
57
45
  it "runs the processes" do
58
46
  write_procfile
59
- mock(subject).fork(subject.processes["alpha"], {})
47
+ mock(subject).fork(subject.procfile["alpha"])
60
48
  mock(subject).watch_for_termination
61
49
  subject.execute("alpha")
62
50
  end
51
+
52
+ it "shows an error running a process that doesnt exist" do
53
+ write_procfile
54
+ mock(subject).puts("ERROR: no such process: foo")
55
+ lambda { subject.execute("foo") }.should raise_error(SystemExit)
56
+ end
57
+ end
58
+
59
+ describe "environment" do
60
+ before(:each) do
61
+ write_procfile
62
+ stub(Process).fork
63
+ end
64
+
65
+ it "should read if specified" do
66
+ File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
67
+ engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
68
+ stub(engine).info
69
+ mock(engine).watch_for_termination
70
+ engine.environment.should == {"FOO"=>"baz"}
71
+ engine.execute("alpha")
72
+ end
73
+
74
+ it "should read more than one if specified" do
75
+ File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
76
+ File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
77
+ engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2")
78
+ stub(engine).info
79
+ mock(engine).watch_for_termination
80
+ engine.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" }
81
+ engine.execute("alpha")
82
+ end
83
+
84
+ it "should fail if specified and doesnt exist" do
85
+ mock.instance_of(Foreman::Engine).error("No such file: /tmp/env")
86
+ engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
87
+ end
88
+
89
+ it "should read .env if none specified" do
90
+ File.open(".env", "w") { |f| f.puts("FOO=qoo") }
91
+ engine = Foreman::Engine.new("Procfile")
92
+ stub(engine).info
93
+ mock(engine).watch_for_termination
94
+ mock(engine).fork_individual(anything, anything, anything)
95
+ engine.environment.should == {"FOO"=>"qoo"}
96
+ engine.execute("bravo")
97
+ end
63
98
  end
64
99
  end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/bluepill"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Bluepill do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:engine) { Foreman::Engine.new(procfile) }
9
+ let(:bluepill) { Foreman::Export::Bluepill.new(engine) }
10
+
11
+ before(:each) { load_export_templates_into_fakefs("bluepill") }
12
+ before(:each) { stub(bluepill).say }
13
+
14
+ it "exports to the filesystem" do
15
+ bluepill.export("/tmp/init", :concurrency => "alpha=2")
16
+
17
+ File.read("/tmp/init/app.pill").should == example_export_file("bluepill/app.pill")
18
+ end
19
+
20
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/runit"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Runit do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
8
+ let(:engine) { Foreman::Engine.new(procfile) }
9
+ let(:runit) { Foreman::Export::Runit.new(engine) }
10
+
11
+ before(:each) { load_export_templates_into_fakefs("runit") }
12
+ before(:each) { stub(runit).say }
13
+
14
+ it "exports to the filesystem" do
15
+ FileUtils.mkdir_p('/tmp/init')
16
+ runit.export('/tmp/init', :concurrency => 'alpha=2')
17
+
18
+ File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1-run')
19
+ File.read("/tmp/init/app-alpha-1/log/run").should ==
20
+ example_export_file('runit/app-alpha-1-log-run')
21
+ File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n"
22
+ File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n"
23
+
24
+ File.read("/tmp/init/app-alpha-2/run").should == example_export_file('runit/app-alpha-2-run')
25
+ File.read("/tmp/init/app-alpha-2/log/run").should ==
26
+ example_export_file('runit/app-alpha-2-log-run')
27
+ File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n"
28
+ File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n"
29
+
30
+ File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1-run')
31
+ File.read("/tmp/init/app-bravo-1/log/run").should ==
32
+ example_export_file('runit/app-bravo-1-log-run')
33
+ File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n"
34
+ end
35
+ end
@@ -1,21 +1,55 @@
1
1
  require "spec_helper"
2
+ require "foreman/engine"
2
3
  require "foreman/export/upstart"
4
+ require "tmpdir"
3
5
 
4
6
  describe Foreman::Export::Upstart do
5
- let(:engine) { Foreman::Engine.new(write_procfile) }
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:engine) { Foreman::Engine.new(procfile) }
6
9
  let(:upstart) { Foreman::Export::Upstart.new(engine) }
7
10
 
8
11
  before(:each) { load_export_templates_into_fakefs("upstart") }
9
12
  before(:each) { stub(upstart).say }
10
13
 
11
14
  it "exports to the filesystem" do
12
- upstart.export("/tmp/init")
13
-
14
- File.read("/tmp/init/foreman.conf").should == example_export_file("upstart/foreman.conf")
15
- File.read("/tmp/init/foreman-alpha.conf").should == example_export_file("upstart/foreman-alpha.conf")
16
- File.read("/tmp/init/foreman-alpha-1.conf").should == example_export_file("upstart/foreman-alpha-1.conf")
17
- File.read("/tmp/init/foreman-alpha-2.conf").should == example_export_file("upstart/foreman-alpha-2.conf")
18
- File.read("/tmp/init/foreman-bravo.conf").should == example_export_file("upstart/foreman.bravo.conf")
19
- File.read("/tmp/init/foreman-bravo-1.conf").should == example_export_file("upstart/foreman-bravo-1.conf")
15
+ upstart.export("/tmp/init", :concurrency => "alpha=2")
16
+
17
+ File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
18
+ File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
19
+ File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
20
+ File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
21
+ File.read("/tmp/init/app-bravo.conf").should == example_export_file("upstart/app-bravo.conf")
22
+ File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
23
+ end
24
+
25
+ context "with alternate templates" do
26
+ let(:template_root) { "/tmp/alternate" }
27
+
28
+ before do
29
+ FileUtils.mkdir_p template_root
30
+ File.open("#{template_root}/master.conf.erb", "w") { |f| f.puts "alternate_template" }
31
+ end
32
+
33
+ it "can export with alternate template files" do
34
+ upstart.export("/tmp/init", :template => template_root)
35
+
36
+ File.read("/tmp/init/app.conf").should == "alternate_template\n"
37
+ end
20
38
  end
39
+
40
+ context "with alternate templates from home dir" do
41
+ let(:default_template_root) {File.expand_path("~/.foreman/templates")}
42
+
43
+ before do
44
+ FileUtils.mkdir_p default_template_root
45
+ File.open("#{default_template_root}/master.conf.erb", "w") { |f| f.puts "default_alternate_template" }
46
+ end
47
+
48
+ it "can export with alternate template files" do
49
+ upstart.export("/tmp/init")
50
+
51
+ File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
52
+ end
53
+ end
54
+
21
55
  end
data/spec/foreman_spec.rb CHANGED
@@ -8,4 +8,26 @@ describe Foreman do
8
8
  it { should be_a String }
9
9
  end
10
10
 
11
+ describe "::load_env!(env_file)" do
12
+ before do
13
+ FakeFS.activate!
14
+ end
15
+
16
+ after do
17
+ FakeFS.deactivate!
18
+ ENV['FOO'] = nil
19
+ end
20
+
21
+ it "should load env_file into ENV" do
22
+ File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
23
+ Foreman.load_env!("/tmp/env1")
24
+ ENV['FOO'].should == 'bar'
25
+ end
26
+
27
+ it "should assume env_file in ./.env" do
28
+ File.open("./.env", "w") { |f| f.puts("FOO=bar") }
29
+ Foreman.load_env!
30
+ ENV['FOO'].should == 'bar'
31
+ end
32
+ end
11
33
  end
@@ -0,0 +1,65 @@
1
+ Bluepill.application("app", :foreground => false, :log_file => "/var/log/bluepill.log") do |app|
2
+
3
+ app.uid = "app"
4
+ app.gid = "app"
5
+
6
+
7
+
8
+
9
+ app.process("alpha-1") do |process|
10
+ process.start_command = "./alpha"
11
+
12
+ process.working_dir = "/tmp/app"
13
+ process.daemonize = true
14
+ process.environment = {"PORT" => "5000"}
15
+ process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
16
+
17
+ process.stdout = process.stderr = "/var/log/app/app-alpha-1.log"
18
+
19
+ process.monitor_children do |children|
20
+ children.stop_command "kill -QUIT {{PID}}"
21
+ end
22
+
23
+ process.group = "app-alpha"
24
+ end
25
+
26
+
27
+ app.process("alpha-2") do |process|
28
+ process.start_command = "./alpha"
29
+
30
+ process.working_dir = "/tmp/app"
31
+ process.daemonize = true
32
+ process.environment = {"PORT" => "5001"}
33
+ process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
34
+
35
+ process.stdout = process.stderr = "/var/log/app/app-alpha-2.log"
36
+
37
+ process.monitor_children do |children|
38
+ children.stop_command "kill -QUIT {{PID}}"
39
+ end
40
+
41
+ process.group = "app-alpha"
42
+ end
43
+
44
+
45
+
46
+
47
+ app.process("bravo-1") do |process|
48
+ process.start_command = "./bravo"
49
+
50
+ process.working_dir = "/tmp/app"
51
+ process.daemonize = true
52
+ process.environment = {"PORT" => "5100"}
53
+ process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
54
+
55
+ process.stdout = process.stderr = "/var/log/app/app-bravo-1.log"
56
+
57
+ process.monitor_children do |children|
58
+ children.stop_command "kill -QUIT {{PID}}"
59
+ end
60
+
61
+ process.group = "app-bravo"
62
+ end
63
+
64
+
65
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ LOG=/var/log/app/alpha-1
5
+
6
+ test -d "$LOG" || mkdir -p m2750 "$LOG" && chown app "$LOG"
7
+ exec chpst -u app svlogd "$LOG"
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ cd /tmp/app
3
+ exec chpst -u app -e /tmp/init/app-alpha-1/env ./alpha bar=baz
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ LOG=/var/log/app/alpha-2
5
+
6
+ test -d "$LOG" || mkdir -p m2750 "$LOG" && chown app "$LOG"
7
+ exec chpst -u app svlogd "$LOG"
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ cd /tmp/app
3
+ exec chpst -u app -e /tmp/init/app-alpha-2/env ./alpha bar=baz
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ LOG=/var/log/app/bravo-1
5
+
6
+ test -d "$LOG" || mkdir -p m2750 "$LOG" && chown app "$LOG"
7
+ exec chpst -u app svlogd "$LOG"
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ cd /tmp/app
3
+ exec chpst -u app -e /tmp/init/app-bravo-1/env ./bravo
@@ -0,0 +1,5 @@
1
+ start on starting app-alpha
2
+ stop on stopping app-alpha
3
+ respawn
4
+
5
+ exec su - app -c 'cd /tmp/app; export PORT=5000; ./alpha >> /var/log/app/alpha-1.log 2>&1'
@@ -0,0 +1,5 @@
1
+ start on starting app-alpha
2
+ stop on stopping app-alpha
3
+ respawn
4
+
5
+ exec su - app -c 'cd /tmp/app; export PORT=5001; ./alpha >> /var/log/app/alpha-2.log 2>&1'
@@ -0,0 +1,2 @@
1
+ start on starting app
2
+ stop on stopping app
@@ -0,0 +1,5 @@
1
+ start on starting app-bravo
2
+ stop on stopping app-bravo
3
+ respawn
4
+
5
+ exec su - app -c 'cd /tmp/app; export PORT=5100; ./bravo >> /var/log/app/bravo-1.log 2>&1'
@@ -0,0 +1,2 @@
1
+ start on starting app
2
+ stop on stopping app
@@ -0,0 +1,8 @@
1
+ pre-start script
2
+
3
+ bash << "EOF"
4
+ mkdir -p /var/log/app
5
+ chown -R app /var/log/app
6
+ EOF
7
+
8
+ end script
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,7 @@ require "rspec"
3
3
  require "fakefs/safe"
4
4
  require "fakefs/spec_helpers"
5
5
 
6
- $:.unshift "lib"
6
+ $:.unshift File.expand_path("../../lib", __FILE__)
7
7
 
8
8
  def mock_error(subject, message)
9
9
  mock_exit do
@@ -12,6 +12,10 @@ def mock_error(subject, message)
12
12
  end
13
13
  end
14
14
 
15
+ def foreman(args)
16
+ Foreman::CLI.start(args.split(" "))
17
+ end
18
+
15
19
  def mock_exit(&block)
16
20
  block.should raise_error(SystemExit)
17
21
  end
@@ -24,14 +28,21 @@ def write_foreman_config(app)
24
28
  end
25
29
  end
26
30
 
27
- def write_procfile(procfile="Procfile")
31
+ def write_procfile(procfile="Procfile", alpha_env="")
28
32
  File.open(procfile, "w") do |file|
29
- file.puts "alpha: ./alpha"
30
- file.puts "bravo: ./bravo"
33
+ file.puts "alpha: ./alpha" + " #{alpha_env}".rstrip
34
+ file.puts "\n"
35
+ file.puts "bravo:\t./bravo"
31
36
  end
32
37
  File.expand_path(procfile)
33
38
  end
34
39
 
40
+ def write_env(env=".env")
41
+ File.open(env, "w") do |file|
42
+ file.puts "FOO=bar"
43
+ end
44
+ end
45
+
35
46
  def load_export_templates_into_fakefs(type)
36
47
  FakeFS.deactivate!
37
48
  files = Dir[File.expand_path("../../data/export/#{type}/**", __FILE__)].inject({}) do |hash, file|
@@ -52,7 +63,7 @@ def example_export_file(filename)
52
63
  data
53
64
  end
54
65
 
55
- Rspec.configure do |config|
66
+ RSpec.configure do |config|
56
67
  config.color_enabled = true
57
68
  config.include FakeFS::SpecHelpers
58
69
  config.mock_with :rr