foreman 0.31.0 → 0.32.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +2 -1
- data/bin/runner +2 -2
- data/lib/foreman/cli.rb +24 -4
- data/lib/foreman/engine.rb +7 -1
- data/lib/foreman/process.rb +2 -0
- data/lib/foreman/version.rb +1 -1
- data/spec/foreman/cli_spec.rb +49 -0
- data/spec/helper_spec.rb +18 -0
- data/spec/spec_helper.rb +10 -0
- metadata +39 -60
data/README.markdown
CHANGED
@@ -20,7 +20,8 @@ http://blog.daviddollar.org/2011/05/06/introducing-foreman.html
|
|
20
20
|
|
21
21
|
## Manual
|
22
22
|
|
23
|
-
|
23
|
+
* [man page](http://ddollar.github.com/foreman)
|
24
|
+
* [wiki](http://github.com/ddollar/foreman/wiki)
|
24
25
|
|
25
26
|
## Authorship
|
26
27
|
|
data/bin/runner
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
#!/bin/
|
2
|
-
exec
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
exec "#{ARGV.join(' ')} 2>&1"
|
data/lib/foreman/cli.rb
CHANGED
@@ -5,15 +5,23 @@ require "thor"
|
|
5
5
|
require "yaml"
|
6
6
|
|
7
7
|
class Foreman::CLI < Thor
|
8
|
-
|
8
|
+
|
9
9
|
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
10
|
-
|
10
|
+
|
11
11
|
desc "start", "Start the application"
|
12
12
|
|
13
13
|
method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
|
14
14
|
method_option :port, :type => :numeric, :aliases => "-p"
|
15
15
|
method_option :concurrency, :type => :string, :aliases => "-c", :banner => '"alpha=5,bar=3"'
|
16
16
|
|
17
|
+
class << self
|
18
|
+
# Hackery. Take the run method away from Thor so that we can redefine it.
|
19
|
+
def is_thor_reserved_word?(word, type)
|
20
|
+
return false if word == 'run'
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
17
25
|
def start
|
18
26
|
check_procfile!
|
19
27
|
engine.start
|
@@ -53,7 +61,20 @@ class Foreman::CLI < Thor
|
|
53
61
|
error "no processes defined" unless engine.procfile.entries.length > 0
|
54
62
|
display "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
|
55
63
|
end
|
56
|
-
|
64
|
+
|
65
|
+
desc "run COMMAND", "Run a command using your application's environment"
|
66
|
+
|
67
|
+
def run(*args)
|
68
|
+
engine.apply_environment!
|
69
|
+
begin
|
70
|
+
exec args.join(" ")
|
71
|
+
rescue Errno::EACCES
|
72
|
+
error "not executable: #{args.first}"
|
73
|
+
rescue Errno::ENOENT
|
74
|
+
error "command not found: #{args.first}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
57
78
|
private ######################################################################
|
58
79
|
|
59
80
|
def check_procfile!
|
@@ -87,5 +108,4 @@ private ######################################################################
|
|
87
108
|
defaults = YAML::load_file(".foreman") || {}
|
88
109
|
Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
|
89
110
|
end
|
90
|
-
|
91
111
|
end
|
data/lib/foreman/engine.rb
CHANGED
@@ -72,10 +72,16 @@ private ######################################################################
|
|
72
72
|
def kill_all(signal="SIGTERM")
|
73
73
|
running_processes.each do |pid, process|
|
74
74
|
info "sending #{signal} to pid #{pid}"
|
75
|
-
|
75
|
+
kill(signal, -pid) or kill(signal, pid)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
def kill(signal, pid)
|
80
|
+
Process.kill signal, pid
|
81
|
+
rescue Errno::ESRCH
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
79
85
|
def terminate_gracefully
|
80
86
|
info "sending SIGTERM to all processes"
|
81
87
|
kill_all "SIGTERM"
|
data/lib/foreman/process.rb
CHANGED
@@ -30,11 +30,13 @@ private
|
|
30
30
|
def fork_with_io(command)
|
31
31
|
reader, writer = IO.pipe
|
32
32
|
pid = fork do
|
33
|
+
Process.setpgrp
|
33
34
|
trap("INT", "IGNORE")
|
34
35
|
$stdout.reopen writer
|
35
36
|
reader.close
|
36
37
|
exec Foreman.runner, replace_command_env(command)
|
37
38
|
end
|
39
|
+
Process.detach pid
|
38
40
|
[ reader, pid ]
|
39
41
|
end
|
40
42
|
|
data/lib/foreman/version.rb
CHANGED
data/spec/foreman/cli_spec.rb
CHANGED
@@ -89,5 +89,54 @@ describe "Foreman::CLI" do
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
describe "run" do
|
94
|
+
describe "with a valid Procfile" do
|
95
|
+
before { write_procfile }
|
96
|
+
|
97
|
+
describe "and a command" do
|
98
|
+
let(:command) { ["ls", "-l"] }
|
99
|
+
|
100
|
+
before(:each) do
|
101
|
+
stub(subject).exec
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should load the environment file" do
|
105
|
+
write_env
|
106
|
+
preserving_env do
|
107
|
+
subject.run *command
|
108
|
+
ENV["FOO"].should == "bar"
|
109
|
+
end
|
110
|
+
|
111
|
+
ENV["FOO"].should be_nil
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should runute the command as a string" do
|
115
|
+
mock(subject).exec(command.join(" "))
|
116
|
+
subject.run *command
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "and a non-existent command" do
|
121
|
+
let(:command) { "iuhtngrglhulhdfg" }
|
122
|
+
|
123
|
+
it "should print an error" do
|
124
|
+
mock_error(subject, "command not found: #{command}") do
|
125
|
+
subject.run command
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "and a non-executable command" do
|
131
|
+
let(:command) { __FILE__ }
|
132
|
+
|
133
|
+
it "should print an error" do
|
134
|
+
mock_error(subject, "not executable: #{command}") do
|
135
|
+
subject.run command
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
92
141
|
|
93
142
|
end
|
data/spec/helper_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "spec helpers" do
|
4
|
+
describe "#preserving_env" do
|
5
|
+
after { ENV.delete "FOO" }
|
6
|
+
|
7
|
+
it "should remove added environment vars" do
|
8
|
+
preserving_env { ENV["FOO"] = "baz" }
|
9
|
+
ENV["FOO"].should == nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should reset modified environment vars" do
|
13
|
+
ENV["FOO"] = "bar"
|
14
|
+
preserving_env { ENV["FOO"] = "baz"}
|
15
|
+
ENV["FOO"].should == "bar"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -63,6 +63,16 @@ def example_export_file(filename)
|
|
63
63
|
data
|
64
64
|
end
|
65
65
|
|
66
|
+
def preserving_env
|
67
|
+
old_env = ENV.to_hash
|
68
|
+
begin
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
ENV.clear
|
72
|
+
ENV.update(old_env)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
66
76
|
RSpec.configure do |config|
|
67
77
|
config.color_enabled = true
|
68
78
|
config.include FakeFS::SpecHelpers
|
metadata
CHANGED
@@ -1,63 +1,45 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.32.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 31
|
9
|
-
- 0
|
10
|
-
version: 0.31.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- David Dollar
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
12
|
+
date: 2012-01-12 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: term-ansicolor
|
16
|
+
requirement: &70189245337240 !ruby/object:Gem::Requirement
|
23
17
|
none: false
|
24
|
-
requirements:
|
18
|
+
requirements:
|
25
19
|
- - ~>
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
hash: 29
|
28
|
-
segments:
|
29
|
-
- 1
|
30
|
-
- 0
|
31
|
-
- 5
|
20
|
+
- !ruby/object:Gem::Version
|
32
21
|
version: 1.0.5
|
33
|
-
version_requirements: *id001
|
34
|
-
prerelease: false
|
35
|
-
name: term-ansicolor
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
22
|
type: :runtime
|
38
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70189245337240
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: thor
|
27
|
+
requirement: &70189245321980 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
hash: 39
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
- 13
|
47
|
-
- 6
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
48
32
|
version: 0.13.6
|
49
|
-
|
33
|
+
type: :runtime
|
50
34
|
prerelease: false
|
51
|
-
|
35
|
+
version_requirements: *70189245321980
|
52
36
|
description: Process manager for applications with multiple components
|
53
37
|
email: ddollar@gmail.com
|
54
|
-
executables:
|
38
|
+
executables:
|
55
39
|
- foreman
|
56
40
|
extensions: []
|
57
|
-
|
58
41
|
extra_rdoc_files: []
|
59
|
-
|
60
|
-
files:
|
42
|
+
files:
|
61
43
|
- bin/foreman
|
62
44
|
- bin/runner
|
63
45
|
- data/example/error
|
@@ -95,6 +77,7 @@ files:
|
|
95
77
|
- spec/foreman/export_spec.rb
|
96
78
|
- spec/foreman/process_spec.rb
|
97
79
|
- spec/foreman_spec.rb
|
80
|
+
- spec/helper_spec.rb
|
98
81
|
- spec/resources/export/bluepill/app.pill
|
99
82
|
- spec/resources/export/runit/app-alpha-1-log-run
|
100
83
|
- spec/resources/export/runit/app-alpha-1-run
|
@@ -112,36 +95,32 @@ files:
|
|
112
95
|
- man/foreman.1
|
113
96
|
homepage: http://github.com/ddollar/foreman
|
114
97
|
licenses: []
|
115
|
-
|
116
98
|
post_install_message:
|
117
99
|
rdoc_options: []
|
118
|
-
|
119
|
-
require_paths:
|
100
|
+
require_paths:
|
120
101
|
- lib
|
121
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
103
|
none: false
|
123
|
-
requirements:
|
124
|
-
- -
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
|
127
|
-
segments:
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
segments:
|
128
109
|
- 0
|
129
|
-
|
130
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
hash: -1641968407225152398
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
112
|
none: false
|
132
|
-
requirements:
|
133
|
-
- -
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
|
136
|
-
segments:
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
segments:
|
137
118
|
- 0
|
138
|
-
|
119
|
+
hash: -1641968407225152398
|
139
120
|
requirements: []
|
140
|
-
|
141
121
|
rubyforge_project:
|
142
122
|
rubygems_version: 1.8.10
|
143
123
|
signing_key:
|
144
124
|
specification_version: 3
|
145
125
|
summary: Process manager for applications with multiple components
|
146
126
|
test_files: []
|
147
|
-
|