invoker 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/Gemfile +2 -0
- data/invoker.gemspec +2 -2
- data/lib/invoker/commander.rb +24 -2
- data/lib/invoker/parsers/config.rb +0 -6
- data/lib/invoker/power/balancer.rb +6 -1
- data/lib/invoker/version.rb +1 -1
- data/readme.md +2 -0
- data/spec/invoker/commander_spec.rb +55 -4
- data/spec/invoker/config_spec.rb +0 -20
- data/spec/invoker/power/balancer_spec.rb +41 -0
- data/spec/spec_helper.rb +3 -0
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36f535d2a652c9164fbe92e7df1e9aff140223d2
|
4
|
+
data.tar.gz: f84168b2628f0f40024de2b46c1de5017a9069d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0fb344263af24e67273104073e872b070bfeb73f2a9e782953f29d355216ab5d2c18c254b5d175619ba0e6bd7bd4461e2956e01b5d022574005f54d38640854
|
7
|
+
data.tar.gz: 1e758cf427cd35b11773c06896d3b3fc2ebd9fab50ac8c60ff06379cab2369fc41eb5353f9a53e6e34c5a5b5e04664bb9570ffa001ed6dc7b9fd867aa305fa6b
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/Gemfile
CHANGED
data/invoker.gemspec
CHANGED
@@ -12,8 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.version = Invoker::VERSION
|
13
13
|
|
14
14
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
15
|
-
s.authors = ["Hemant Kumar"]
|
16
|
-
s.date = %q{2013-05-04}
|
15
|
+
s.authors = ["Hemant Kumar", "Amitava Basak"]
|
17
16
|
s.description = %q{Something small for process management}
|
18
17
|
s.email = %q{hemant@codemancers.com}
|
19
18
|
|
@@ -27,6 +26,7 @@ Gem::Specification.new do |s|
|
|
27
26
|
s.require_paths = ["lib"]
|
28
27
|
s.summary = %q{Something small for Process management}
|
29
28
|
s.add_dependency("slop", "~> 3.4.6")
|
29
|
+
s.add_dependency("rainbow", "~> 1.1.4")
|
30
30
|
s.add_dependency("iniparse", "~> 1.1.6")
|
31
31
|
s.add_dependency("formatador", "~> 0.2.4")
|
32
32
|
s.add_dependency("eventmachine", "~> 1.0.3")
|
data/lib/invoker/commander.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "io/console"
|
2
2
|
require 'pty'
|
3
3
|
require "json"
|
4
|
+
require "dotenv"
|
4
5
|
|
5
6
|
module Invoker
|
6
7
|
class Commander
|
@@ -67,6 +68,11 @@ module Invoker
|
|
67
68
|
#
|
68
69
|
# @param command_label [String] Command label of process specified in config file.
|
69
70
|
def add_command_by_label(command_label)
|
71
|
+
if process_running?(command_label)
|
72
|
+
Invoker::Logger.puts "\nProcess '#{command_label}' is already running".color(:red)
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
|
70
76
|
process_info = Invoker::CONFIG.process(command_label)
|
71
77
|
if process_info
|
72
78
|
add_command(process_info)
|
@@ -142,6 +148,16 @@ module Invoker
|
|
142
148
|
}
|
143
149
|
end
|
144
150
|
|
151
|
+
def load_env(directory = nil)
|
152
|
+
directory ||= ENV['PWD']
|
153
|
+
default_env = File.join(directory, '.env')
|
154
|
+
if File.exist?(default_env)
|
155
|
+
Dotenv::Environment.new(default_env)
|
156
|
+
else
|
157
|
+
{}
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
145
161
|
private
|
146
162
|
def start_event_loop
|
147
163
|
loop do
|
@@ -204,6 +220,8 @@ module Invoker
|
|
204
220
|
|
205
221
|
event_manager.schedule_event(command_label, :exit) { remove_worker(command_label) }
|
206
222
|
|
223
|
+
env_options = load_env(process_info.dir)
|
224
|
+
|
207
225
|
spawn_options = {
|
208
226
|
:chdir => process_info.dir || ENV['PWD'], :out => write_pipe, :err => write_pipe,
|
209
227
|
:pgroup => true, :close_others => true, :in => :close
|
@@ -211,10 +229,10 @@ module Invoker
|
|
211
229
|
|
212
230
|
if defined?(Bundler)
|
213
231
|
Bundler.with_clean_env do
|
214
|
-
spawn(process_info.cmd, spawn_options)
|
232
|
+
spawn(env_options, process_info.cmd, spawn_options)
|
215
233
|
end
|
216
234
|
else
|
217
|
-
spawn(process_info.cmd, spawn_options)
|
235
|
+
spawn(env_options, process_info.cmd, spawn_options)
|
218
236
|
end
|
219
237
|
end
|
220
238
|
|
@@ -267,5 +285,9 @@ module Invoker
|
|
267
285
|
}
|
268
286
|
@workers = {}
|
269
287
|
end
|
288
|
+
|
289
|
+
def process_running?(command_label)
|
290
|
+
!!workers[command_label]
|
291
|
+
end
|
270
292
|
end
|
271
293
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'iniparse'
|
2
|
-
require 'dotenv'
|
3
2
|
|
4
3
|
module Invoker
|
5
4
|
module Parsers
|
@@ -50,7 +49,6 @@ module Invoker
|
|
50
49
|
end
|
51
50
|
|
52
51
|
def process_procfile
|
53
|
-
load_env
|
54
52
|
procfile = Invoker::Parsers::Procfile.new(@filename)
|
55
53
|
procfile.entries.map do |name, command|
|
56
54
|
section = { "label" => name, "command" => command }
|
@@ -67,10 +65,6 @@ module Invoker
|
|
67
65
|
end
|
68
66
|
end
|
69
67
|
|
70
|
-
def load_env
|
71
|
-
Dotenv.load
|
72
|
-
end
|
73
|
-
|
74
68
|
def pick_port(section)
|
75
69
|
if section['command'] =~ PORT_REGEX
|
76
70
|
@port += 1
|
@@ -42,6 +42,7 @@ module Invoker
|
|
42
42
|
|
43
43
|
class Balancer
|
44
44
|
attr_accessor :connection, :http_parser, :session
|
45
|
+
DEV_MATCH_REGEX = /([\w-]+)\.dev(\:\d+)?$/
|
45
46
|
|
46
47
|
def self.run(options = {})
|
47
48
|
EventMachine.start_server('0.0.0.0', Invoker::CONFIG.http_port,
|
@@ -110,9 +111,13 @@ module Invoker
|
|
110
111
|
connection.close_connection_after_writing() if backend == session
|
111
112
|
end
|
112
113
|
|
114
|
+
def extract_host_from_domain(host)
|
115
|
+
host.match(DEV_MATCH_REGEX)
|
116
|
+
end
|
117
|
+
|
113
118
|
private
|
114
119
|
def select_backend_config(host)
|
115
|
-
matching_string = host
|
120
|
+
matching_string = extract_host_from_domain(host)
|
116
121
|
return nil unless matching_string
|
117
122
|
if selected_app = matching_string[1]
|
118
123
|
Invoker::CONFIG.process(selected_app)
|
data/lib/invoker/version.rb
CHANGED
data/readme.md
CHANGED
@@ -2,6 +2,8 @@ Invoker is a gem for managing processes in development environment.
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/code-mancers/invoker.png)](https://travis-ci.org/code-mancers/invoker)
|
4
4
|
[![Code Climate](https://codeclimate.com/repos/51d3bfb9c7f3a3777b060155/badges/7e150ca223f6bc8935f7/gpa.png)](https://codeclimate.com/repos/51d3bfb9c7f3a3777b060155/feed)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/code-mancers/invoker/badge.png)](https://coveralls.io/r/code-mancers/invoker)
|
6
|
+
[![Dependency Status](https://gemnasium.com/code-mancers/invoker.png)](https://gemnasium.com/code-mancers/invoker)
|
5
7
|
|
6
8
|
## Usage ##
|
7
9
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "Invoker::Commander" do
|
4
|
-
|
4
|
+
|
5
5
|
describe "With no processes configured" do
|
6
6
|
before do
|
7
7
|
@commander = Invoker::Commander.new()
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it "should throw error" do
|
11
11
|
invoker_config.stubs(:processes).returns([])
|
12
12
|
|
@@ -25,9 +25,14 @@ describe "Invoker::Commander" do
|
|
25
25
|
invoker_config.stubs(:processes).returns([OpenStruct.new(:label => "resque", :cmd => "foo", :dir => "bar")])
|
26
26
|
invoker_config.expects(:process).returns(OpenStruct.new(:label => "resque", :cmd => "foo", :dir => "bar"))
|
27
27
|
@commander.expects(:add_command).returns(true)
|
28
|
-
|
28
|
+
|
29
29
|
@commander.add_command_by_label("resque")
|
30
30
|
end
|
31
|
+
|
32
|
+
it "should not start already running process" do
|
33
|
+
@commander.workers.expects(:[]).returns(OpenStruct.new(:pid => "bogus"))
|
34
|
+
expect(@commander.add_command_by_label("resque")).to be_false
|
35
|
+
end
|
31
36
|
end
|
32
37
|
|
33
38
|
describe "#remove_command" do
|
@@ -58,7 +63,7 @@ describe "Invoker::Commander" do
|
|
58
63
|
# end
|
59
64
|
|
60
65
|
# it "should return false" do
|
61
|
-
|
66
|
+
|
62
67
|
# end
|
63
68
|
# end
|
64
69
|
end
|
@@ -90,6 +95,7 @@ describe "Invoker::Commander" do
|
|
90
95
|
|
91
96
|
it "should populate workers and open_pipes" do
|
92
97
|
@commander.expects(:start_event_loop)
|
98
|
+
@commander.expects(:load_env).returns({})
|
93
99
|
@commander.start_manager()
|
94
100
|
expect(@commander.open_pipes).not_to be_empty
|
95
101
|
expect(@commander.workers).not_to be_empty
|
@@ -131,4 +137,49 @@ describe "Invoker::Commander" do
|
|
131
137
|
end
|
132
138
|
end
|
133
139
|
|
140
|
+
describe "#load_env" do
|
141
|
+
before do
|
142
|
+
@commander = Invoker::Commander.new()
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should load .env file from the specified directory" do
|
146
|
+
dir = "/tmp"
|
147
|
+
begin
|
148
|
+
env_file = File.new("#{dir}/.env", "w")
|
149
|
+
env_data =<<-EOD
|
150
|
+
FOO=foo
|
151
|
+
BAR=bar
|
152
|
+
EOD
|
153
|
+
env_file.write(env_data)
|
154
|
+
env_file.close
|
155
|
+
env_options = @commander.load_env(dir)
|
156
|
+
expect(env_options).to include("FOO" => "foo", "BAR" => "bar")
|
157
|
+
ensure
|
158
|
+
File.delete(env_file.path)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should default to current directory if no directory is specified" do
|
163
|
+
dir = ENV["HOME"]
|
164
|
+
ENV.stubs(:[]).with("PWD").returns(dir)
|
165
|
+
begin
|
166
|
+
env_file = File.new("#{dir}/.env", "w")
|
167
|
+
env_data =<<-EOD
|
168
|
+
FOO=bar
|
169
|
+
BAR=foo
|
170
|
+
EOD
|
171
|
+
env_file.write(env_data)
|
172
|
+
env_file.close
|
173
|
+
env_options = @commander.load_env
|
174
|
+
expect(env_options).to include("FOO" => "bar", "BAR" => "foo")
|
175
|
+
ensure
|
176
|
+
File.delete(env_file.path)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should return empty hash if there is no .env file" do
|
181
|
+
dir = "/tmp"
|
182
|
+
expect(@commander.load_env(dir)).to eq({})
|
183
|
+
end
|
184
|
+
end
|
134
185
|
end
|
data/spec/invoker/config_spec.rb
CHANGED
@@ -145,25 +145,5 @@ web: bundle exec rails s -p $PORT
|
|
145
145
|
File.delete("/tmp/Procfile")
|
146
146
|
end
|
147
147
|
end
|
148
|
-
|
149
|
-
it "should load environment variables from .env file" do
|
150
|
-
begin
|
151
|
-
env_file = File.new("#{ENV['PWD']}/.env", "w")
|
152
|
-
env_data =<<-EOD
|
153
|
-
TEST="test env"
|
154
|
-
EOD
|
155
|
-
env_file.write(env_data)
|
156
|
-
env_file.close()
|
157
|
-
File.open("/tmp/Procfile", "w") {|fl|
|
158
|
-
fl.write <<-EOD
|
159
|
-
web: bundle exec rails s -p $PORT
|
160
|
-
EOD
|
161
|
-
}
|
162
|
-
config = Invoker::Parsers::Config.new("/tmp/Procfile", 9000)
|
163
|
-
expect(ENV["TEST"]).to eq("test env")
|
164
|
-
ensure
|
165
|
-
File.delete("#{ENV['PWD']}/.env")
|
166
|
-
end
|
167
|
-
end
|
168
148
|
end
|
169
149
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Invoker::Power::Balancer do
|
4
|
+
context "matching domain part of incoming request" do
|
5
|
+
before do
|
6
|
+
@balancer = Invoker::Power::Balancer.new(mock("connection"))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should do foo.dev match" do
|
10
|
+
match = @balancer.extract_host_from_domain("foo.dev")
|
11
|
+
expect(match).to_not be_nil
|
12
|
+
|
13
|
+
matching_string = match[1]
|
14
|
+
expect(matching_string).to eq("foo")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should match foo.dev:1080" do
|
18
|
+
match = @balancer.extract_host_from_domain("foo.dev:1080")
|
19
|
+
expect(match).to_not be_nil
|
20
|
+
|
21
|
+
matching_string = match[1]
|
22
|
+
expect(matching_string).to eq("foo")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should match emacs.bar.dev" do
|
26
|
+
match = @balancer.extract_host_from_domain("emacs.bar.dev")
|
27
|
+
expect(match).to_not be_nil
|
28
|
+
|
29
|
+
matching_string = match[1]
|
30
|
+
expect(matching_string).to eq("bar")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should match hello-world.dev" do
|
34
|
+
match = @balancer.extract_host_from_domain("hello-world.dev")
|
35
|
+
expect(match).to_not be_nil
|
36
|
+
|
37
|
+
matching_string = match[1]
|
38
|
+
expect(matching_string).to eq("hello-world")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: invoker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hemant Kumar
|
8
|
+
- Amitava Basak
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2014-01-30 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: slop
|
@@ -24,6 +25,20 @@ dependencies:
|
|
24
25
|
- - ~>
|
25
26
|
- !ruby/object:Gem::Version
|
26
27
|
version: 3.4.6
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rainbow
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.1.4
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.1.4
|
27
42
|
- !ruby/object:Gem::Dependency
|
28
43
|
name: iniparse
|
29
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,6 +214,7 @@ executables:
|
|
199
214
|
extensions: []
|
200
215
|
extra_rdoc_files: []
|
201
216
|
files:
|
217
|
+
- .coveralls.yml
|
202
218
|
- .gitignore
|
203
219
|
- .rspec
|
204
220
|
- .travis.yml
|
@@ -240,6 +256,7 @@ files:
|
|
240
256
|
- spec/invoker/config_spec.rb
|
241
257
|
- spec/invoker/event/manager_spec.rb
|
242
258
|
- spec/invoker/invoker_spec.rb
|
259
|
+
- spec/invoker/power/balancer_spec.rb
|
243
260
|
- spec/invoker/power/config_spec.rb
|
244
261
|
- spec/invoker/power/http_response_spec.rb
|
245
262
|
- spec/invoker/power/port_finder_spec.rb
|
@@ -276,6 +293,7 @@ test_files:
|
|
276
293
|
- spec/invoker/config_spec.rb
|
277
294
|
- spec/invoker/event/manager_spec.rb
|
278
295
|
- spec/invoker/invoker_spec.rb
|
296
|
+
- spec/invoker/power/balancer_spec.rb
|
279
297
|
- spec/invoker/power/config_spec.rb
|
280
298
|
- spec/invoker/power/http_response_spec.rb
|
281
299
|
- spec/invoker/power/port_finder_spec.rb
|