foreman 0.50.0-x86-mingw32

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 (81) hide show
  1. data/README.md +46 -0
  2. data/bin/foreman +7 -0
  3. data/bin/foreman-runner +32 -0
  4. data/bin/taskman +8 -0
  5. data/data/example/Procfile +4 -0
  6. data/data/example/Procfile.without_colon +2 -0
  7. data/data/example/error +7 -0
  8. data/data/example/log/neverdie.log +4 -0
  9. data/data/example/spawnee +14 -0
  10. data/data/example/spawner +7 -0
  11. data/data/example/ticker +14 -0
  12. data/data/example/utf8 +11 -0
  13. data/data/export/bluepill/master.pill.erb +28 -0
  14. data/data/export/launchd/launchd.plist.erb +22 -0
  15. data/data/export/runit/log/run.erb +7 -0
  16. data/data/export/runit/run.erb +3 -0
  17. data/data/export/supervisord/app.conf.erb +27 -0
  18. data/data/export/upstart/master.conf.erb +8 -0
  19. data/data/export/upstart/process.conf.erb +5 -0
  20. data/data/export/upstart/process_master.conf.erb +2 -0
  21. data/lib/foreman.rb +23 -0
  22. data/lib/foreman/cli.rb +140 -0
  23. data/lib/foreman/distribution.rb +9 -0
  24. data/lib/foreman/engine.rb +313 -0
  25. data/lib/foreman/engine/cli.rb +105 -0
  26. data/lib/foreman/env.rb +27 -0
  27. data/lib/foreman/export.rb +34 -0
  28. data/lib/foreman/export/base.rb +146 -0
  29. data/lib/foreman/export/bluepill.rb +12 -0
  30. data/lib/foreman/export/inittab.rb +33 -0
  31. data/lib/foreman/export/launchd.rb +15 -0
  32. data/lib/foreman/export/runit.rb +34 -0
  33. data/lib/foreman/export/supervisord.rb +16 -0
  34. data/lib/foreman/export/upstart.rb +25 -0
  35. data/lib/foreman/helpers.rb +45 -0
  36. data/lib/foreman/process.rb +102 -0
  37. data/lib/foreman/procfile.rb +92 -0
  38. data/lib/foreman/version.rb +5 -0
  39. data/man/foreman.1 +244 -0
  40. data/spec/foreman/cli_spec.rb +87 -0
  41. data/spec/foreman/engine_spec.rb +104 -0
  42. data/spec/foreman/export/base_spec.rb +19 -0
  43. data/spec/foreman/export/bluepill_spec.rb +37 -0
  44. data/spec/foreman/export/inittab_spec.rb +40 -0
  45. data/spec/foreman/export/launchd_spec.rb +21 -0
  46. data/spec/foreman/export/runit_spec.rb +36 -0
  47. data/spec/foreman/export/supervisord_spec.rb +36 -0
  48. data/spec/foreman/export/upstart_spec.rb +88 -0
  49. data/spec/foreman/export_spec.rb +24 -0
  50. data/spec/foreman/helpers_spec.rb +26 -0
  51. data/spec/foreman/process_spec.rb +48 -0
  52. data/spec/foreman/procfile_spec.rb +41 -0
  53. data/spec/foreman_spec.rb +16 -0
  54. data/spec/helper_spec.rb +18 -0
  55. data/spec/resources/Procfile +4 -0
  56. data/spec/resources/bin/echo +2 -0
  57. data/spec/resources/bin/env +2 -0
  58. data/spec/resources/bin/test +2 -0
  59. data/spec/resources/bin/utf8 +2 -0
  60. data/spec/resources/export/bluepill/app-concurrency.pill +49 -0
  61. data/spec/resources/export/bluepill/app.pill +46 -0
  62. data/spec/resources/export/inittab/inittab.concurrency +4 -0
  63. data/spec/resources/export/inittab/inittab.default +4 -0
  64. data/spec/resources/export/launchd/launchd-a.default +22 -0
  65. data/spec/resources/export/launchd/launchd-b.default +22 -0
  66. data/spec/resources/export/runit/app-alpha-1/log/run +7 -0
  67. data/spec/resources/export/runit/app-alpha-1/run +3 -0
  68. data/spec/resources/export/runit/app-alpha-2/log/run +7 -0
  69. data/spec/resources/export/runit/app-alpha-2/run +3 -0
  70. data/spec/resources/export/runit/app-bravo-1/log/run +7 -0
  71. data/spec/resources/export/runit/app-bravo-1/run +3 -0
  72. data/spec/resources/export/supervisord/app-alpha-1.conf +24 -0
  73. data/spec/resources/export/supervisord/app-alpha-2.conf +24 -0
  74. data/spec/resources/export/upstart/app-alpha-1.conf +5 -0
  75. data/spec/resources/export/upstart/app-alpha-2.conf +5 -0
  76. data/spec/resources/export/upstart/app-alpha.conf +2 -0
  77. data/spec/resources/export/upstart/app-bravo-1.conf +5 -0
  78. data/spec/resources/export/upstart/app-bravo.conf +2 -0
  79. data/spec/resources/export/upstart/app.conf +8 -0
  80. data/spec/spec_helper.rb +153 -0
  81. metadata +148 -0
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export"
4
+
5
+ describe "Foreman::Export::Base", :fakefs do
6
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
7
+ let(:location) { "/tmp/init" }
8
+ let(:engine) { Foreman::Engine.new().load_procfile(procfile) }
9
+ let(:subject) { Foreman::Export::Base.new(location, engine) }
10
+
11
+ it "has a say method for displaying info" do
12
+ mock(subject).puts("[foreman export] foo")
13
+ subject.send(:say, "foo")
14
+ end
15
+
16
+ it "raises errors as a Foreman::Export::Exception" do
17
+ lambda { subject.send(:error, "foo") }.should raise_error(Foreman::Export::Exception, "foo")
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/bluepill"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Bluepill, :fakefs do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:formation) { nil }
9
+ let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
10
+ let(:options) { Hash.new }
11
+ let(:bluepill) { Foreman::Export::Bluepill.new("/tmp/init", engine, options) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("bluepill") }
14
+ before(:each) { stub(bluepill).say }
15
+
16
+ it "exports to the filesystem" do
17
+ bluepill.export
18
+ normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app.pill"))
19
+ end
20
+
21
+ it "cleans up if exporting into an existing dir" do
22
+ mock(FileUtils).rm("/tmp/init/app.pill")
23
+
24
+ bluepill.export
25
+ bluepill.export
26
+ end
27
+
28
+ context "with a process formation" do
29
+ let(:formation) { "alpha=2" }
30
+
31
+ it "exports to the filesystem with concurrency" do
32
+ bluepill.export
33
+ normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app-concurrency.pill"))
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/inittab"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Inittab, :fakefs do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:location) { "/tmp/inittab" }
9
+ let(:formation) { nil }
10
+ let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
11
+ let(:options) { Hash.new }
12
+ let(:inittab) { Foreman::Export::Inittab.new(location, engine, options) }
13
+
14
+ before(:each) { load_export_templates_into_fakefs("inittab") }
15
+ before(:each) { stub(inittab).say }
16
+
17
+ it "exports to the filesystem" do
18
+ inittab.export
19
+ File.read("/tmp/inittab").should == example_export_file("inittab/inittab.default")
20
+ end
21
+
22
+ context "to stdout" do
23
+ let(:location) { "-" }
24
+
25
+ it "exports to stdout" do
26
+ mock(inittab).puts example_export_file("inittab/inittab.default")
27
+ inittab.export
28
+ end
29
+ end
30
+
31
+ context "with concurrency" do
32
+ let(:formation) { "alpha=2" }
33
+
34
+ it "exports to the filesystem with concurrency" do
35
+ inittab.export
36
+ File.read("/tmp/inittab").should == example_export_file("inittab/inittab.concurrency")
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/launchd"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Launchd, :fakefs do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:options) { Hash.new }
9
+ let(:engine) { Foreman::Engine.new().load_procfile(procfile) }
10
+ let(:launchd) { Foreman::Export::Launchd.new("/tmp/init", engine, options) }
11
+
12
+ before(:each) { load_export_templates_into_fakefs("launchd") }
13
+ before(:each) { stub(launchd).say }
14
+
15
+ it "exports to the filesystem" do
16
+ launchd.export
17
+ File.read("/tmp/init/app-alpha-1.plist").should == example_export_file("launchd/launchd-a.default")
18
+ File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
19
+ end
20
+
21
+ end
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/runit"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Runit, :fakefs do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
8
+ let(:engine) { Foreman::Engine.new(:formation => "alpha=2,bravo=1").load_procfile(procfile) }
9
+ let(:options) { Hash.new }
10
+ let(:runit) { Foreman::Export::Runit.new('/tmp/init', engine, options) }
11
+
12
+ before(:each) { load_export_templates_into_fakefs("runit") }
13
+ before(:each) { stub(runit).say }
14
+ before(:each) { stub(FakeFS::FileUtils).chmod }
15
+
16
+ it "exports to the filesystem" do
17
+ engine.env["BAR"] = "baz"
18
+ runit.export
19
+
20
+ File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1/run')
21
+ File.read("/tmp/init/app-alpha-1/log/run").should == example_export_file('runit/app-alpha-1/log/run')
22
+ File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n"
23
+ File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n"
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 == example_export_file('runit/app-alpha-2/log/run')
26
+ File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n"
27
+ File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n"
28
+ File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1/run')
29
+ File.read("/tmp/init/app-bravo-1/log/run").should == example_export_file('runit/app-bravo-1/log/run')
30
+ File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n"
31
+ end
32
+
33
+ it "creates a full path to the export directory" do
34
+ expect { runit.export }.to_not raise_error(Errno::ENOENT)
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/supervisord"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Supervisord, :fakefs do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:formation) { nil }
9
+ let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
10
+ let(:options) { Hash.new }
11
+ let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, options) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("supervisord") }
14
+ before(:each) { stub(supervisord).say }
15
+
16
+ it "exports to the filesystem" do
17
+ supervisord.export
18
+ File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-1.conf")
19
+ end
20
+
21
+ it "cleans up if exporting into an existing dir" do
22
+ mock(FileUtils).rm("/tmp/init/app.conf")
23
+ supervisord.export
24
+ supervisord.export
25
+ end
26
+
27
+ context "with concurrency" do
28
+ let(:formation) { "alpha=2" }
29
+
30
+ it "exports to the filesystem with concurrency" do
31
+ supervisord.export
32
+ File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,88 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/upstart"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Upstart, :fakefs do
7
+ let(:procfile) { write_procfile("/tmp/app/Procfile") }
8
+ let(:formation) { nil }
9
+ let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
10
+ let(:options) { Hash.new }
11
+ let(:upstart) { Foreman::Export::Upstart.new("/tmp/init", engine, options) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("upstart") }
14
+ before(:each) { stub(upstart).say }
15
+
16
+ it "exports to the filesystem" do
17
+ upstart.export
18
+
19
+ File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
20
+ File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
21
+ File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
22
+ File.read("/tmp/init/app-bravo.conf").should == example_export_file("upstart/app-bravo.conf")
23
+ File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
24
+ end
25
+
26
+ it "cleans up if exporting into an existing dir" do
27
+ mock(FileUtils).rm("/tmp/init/app.conf")
28
+ mock(FileUtils).rm("/tmp/init/app-alpha.conf")
29
+ mock(FileUtils).rm("/tmp/init/app-alpha-1.conf")
30
+ mock(FileUtils).rm("/tmp/init/app-bravo.conf")
31
+ mock(FileUtils).rm("/tmp/init/app-bravo-1.conf")
32
+
33
+ upstart.export
34
+ upstart.export
35
+ end
36
+
37
+ it "quotes and escapes environment variables" do
38
+ engine.env['KEY'] = 'd"\|d'
39
+ upstart.export
40
+ "foobarfoo".should include "bar"
41
+ File.read("/tmp/init/app-alpha-1.conf").should =~ /KEY="d\\"\\\\\\\|d/
42
+ end
43
+
44
+ context "with a formation" do
45
+ let(:formation) { "alpha=2" }
46
+
47
+ it "exports to the filesystem with concurrency" do
48
+ upstart.export
49
+
50
+ File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
51
+ File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
52
+ File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
53
+ File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
54
+ File.exists?("/tmp/init/app-bravo-1.conf").should == false
55
+ end
56
+ end
57
+
58
+ context "with alternate templates" do
59
+ let(:template) { "/tmp/alternate" }
60
+ let(:options) { { :app => "app", :template => template } }
61
+
62
+ before do
63
+ FileUtils.mkdir_p template
64
+ File.open("#{template}/master.conf.erb", "w") { |f| f.puts "alternate_template" }
65
+ end
66
+
67
+ it "can export with alternate template files" do
68
+ upstart.export
69
+ File.read("/tmp/init/app.conf").should == "alternate_template\n"
70
+ end
71
+ end
72
+
73
+ context "with alternate templates from home dir" do
74
+
75
+ before do
76
+ FileUtils.mkdir_p File.expand_path("~/.foreman/templates/upstart")
77
+ File.open(File.expand_path("~/.foreman/templates/upstart/master.conf.erb"), "w") do |file|
78
+ file.puts "default_alternate_template"
79
+ end
80
+ end
81
+
82
+ it "can export with alternate template files" do
83
+ upstart.export
84
+ File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+ require "foreman/export"
3
+
4
+ describe "Foreman::Export" do
5
+ subject { Foreman::Export }
6
+
7
+ describe "with a formatter that doesn't declare the appropriate class" do
8
+ it "prints an error" do
9
+ mock(subject).require("foreman/export/invalidformatter")
10
+ mock_export_error("Unknown export format: invalidformatter (no class Foreman::Export::Invalidformatter).") do
11
+ subject.formatter("invalidformatter")
12
+ end
13
+ end
14
+ end
15
+
16
+ describe "with an invalid formatter" do
17
+
18
+ it "prints an error" do
19
+ mock_export_error("Unknown export format: invalidformatter (unable to load file 'foreman/export/invalidformatter').") do
20
+ subject.formatter("invalidformatter")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+ require "foreman/helpers"
3
+
4
+ describe "Foreman::Helpers" do
5
+ before do
6
+ module Foo
7
+ class Bar; end
8
+ end
9
+ end
10
+
11
+ after do
12
+ Object.send(:remove_const, :Foo)
13
+ end
14
+
15
+ subject { o = Object.new; o.extend(Foreman::Helpers); o }
16
+
17
+ it "should classify words" do
18
+ subject.classify("foo").should == "Foo"
19
+ subject.classify("foo-bar").should == "FooBar"
20
+ end
21
+
22
+ it "should constantize words" do
23
+ subject.constantize("Object").should == Object
24
+ subject.constantize("Foo::Bar").should == Foo::Bar
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'foreman/process'
3
+ require 'ostruct'
4
+ require 'timeout'
5
+ require 'tmpdir'
6
+
7
+ describe Foreman::Process do
8
+
9
+ def run(process, options={})
10
+ rd, wr = IO.method(:pipe).arity.zero? ? IO.pipe : IO.pipe("BINARY")
11
+ process.run(options.merge(:output => wr))
12
+ rd.gets
13
+ end
14
+
15
+ describe "#run" do
16
+
17
+ it "runs the process" do
18
+ process = Foreman::Process.new(resource_path("bin/test"))
19
+ run(process).should == "testing\n"
20
+ end
21
+
22
+ it "can set environment" do
23
+ process = Foreman::Process.new(resource_path("bin/env FOO"), :env => { "FOO" => "bar" })
24
+ run(process).should == "bar\n"
25
+ end
26
+
27
+ it "can set per-run environment" do
28
+ process = Foreman::Process.new(resource_path("bin/env FOO"))
29
+ run(process, :env => { "FOO" => "bar "}).should == "bar\n"
30
+ end
31
+
32
+ it "can handle env vars in the command" do
33
+ process = Foreman::Process.new(resource_path("bin/echo $FOO"), :env => { "FOO" => "bar" })
34
+ run(process).should == "bar\n"
35
+ end
36
+
37
+ it "can handle per-run env vars in the command" do
38
+ process = Foreman::Process.new(resource_path("bin/echo $FOO"))
39
+ run(process, :env => { "FOO" => "bar" }).should == "bar\n"
40
+ end
41
+
42
+ it "should output utf8 properly" do
43
+ process = Foreman::Process.new(resource_path("bin/utf8"))
44
+ run(process).should == "\xFF\x03\n"
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'foreman/procfile'
3
+ require 'pathname'
4
+ require 'tmpdir'
5
+
6
+ describe Foreman::Procfile, :fakefs do
7
+ subject { Foreman::Procfile.new }
8
+
9
+ it "can load from a file" do
10
+ write_procfile
11
+ subject.load "Procfile"
12
+ subject["alpha"].should == "./alpha"
13
+ subject["bravo"].should == "./bravo"
14
+ end
15
+
16
+ it "loads a passed-in Procfile" do
17
+ write_procfile
18
+ procfile = Foreman::Procfile.new("Procfile")
19
+ procfile["alpha"].should == "./alpha"
20
+ procfile["bravo"].should == "./bravo"
21
+ end
22
+
23
+ it "can have a process appended to it" do
24
+ subject["charlie"] = "./charlie"
25
+ subject["charlie"].should == "./charlie"
26
+ end
27
+
28
+ it "can write to a string" do
29
+ subject["foo"] = "./foo"
30
+ subject["bar"] = "./bar"
31
+ subject.to_s.should == "foo: ./foo\nbar: ./bar"
32
+ end
33
+
34
+ it "can write to a file" do
35
+ subject["foo"] = "./foo"
36
+ subject["bar"] = "./bar"
37
+ subject.save "/tmp/proc"
38
+ File.read("/tmp/proc").should == "foo: ./foo\nbar: ./bar\n"
39
+ end
40
+
41
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+ require "foreman"
3
+
4
+ describe Foreman do
5
+
6
+ describe "VERSION" do
7
+ subject { Foreman::VERSION }
8
+ it { should be_a String }
9
+ end
10
+
11
+ describe "runner" do
12
+ it "should exist" do
13
+ File.exists?(Foreman.runner).should == true
14
+ end
15
+ end
16
+ end