guard-spork 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -2
- data/lib/guard/spork/runner.rb +188 -171
- data/lib/guard/spork/version.rb +1 -1
- metadata +12 -12
data/README.md
CHANGED
@@ -90,7 +90,7 @@ end
|
|
90
90
|
Available options:
|
91
91
|
|
92
92
|
``` ruby
|
93
|
-
:wait =>
|
93
|
+
:wait => 60 # Seconds to wait for the server to start, default: 30
|
94
94
|
:cucumber => false
|
95
95
|
:rspec => false
|
96
96
|
:test_unit => false
|
@@ -101,7 +101,7 @@ Available options:
|
|
101
101
|
:test_unit_env => { 'RAILS_ENV' => 'baz' } # Default: nil
|
102
102
|
:rspec_env => { 'RAILS_ENV' => 'foo' } # Default: nil
|
103
103
|
:cucumber_env => { 'RAILS_ENV' => 'bar' } # Default: nil
|
104
|
-
:
|
104
|
+
:aggressive_kill => false # Default: true, will search Spork pids from `ps aux` and kill them all on start.
|
105
105
|
```
|
106
106
|
|
107
107
|
## Common troubleshooting
|
data/lib/guard/spork/runner.rb
CHANGED
@@ -1,171 +1,188 @@
|
|
1
|
-
require 'socket'
|
2
|
-
|
3
|
-
module Guard
|
4
|
-
class Spork
|
5
|
-
class Runner
|
6
|
-
attr_accessor :options
|
7
|
-
|
8
|
-
def initialize(options={})
|
9
|
-
options[:wait] ||=
|
10
|
-
options[:test_unit_port] ||= 8988
|
11
|
-
options[:cucumber_port] ||= 8990
|
12
|
-
options[:rspec_port] ||= 8989
|
13
|
-
options[:rspec_env] ||= {}
|
14
|
-
options[:test_unit_env] ||= {}
|
15
|
-
options[:cucumber_env] ||= {}
|
16
|
-
options[:aggressive_kill] = true unless options[:aggressive_kill] == false
|
17
|
-
@options = options
|
18
|
-
ENV['SPORK_PIDS'] ||= ''
|
19
|
-
end
|
20
|
-
|
21
|
-
def launch_sporks(action)
|
22
|
-
UI.info "#{action.capitalize}ing Spork for #{sporked_gems} ", :reset => true
|
23
|
-
spawn_child(options[:test_unit_env], spork_command("test_unit")) if test_unit?
|
24
|
-
spawn_child(options[:rspec_env], spork_command("rspec")) if rspec?
|
25
|
-
spawn_child(options[:cucumber_env], spork_command("cucumber")) if cucumber?
|
26
|
-
verify_launches(action)
|
27
|
-
end
|
28
|
-
|
29
|
-
def kill_sporks
|
30
|
-
UI.debug "Killing Spork servers with PID: #{spork_pids.join(', ')}"
|
31
|
-
spork_pids.each do |pid|
|
32
|
-
::Process.kill("KILL", pid)
|
33
|
-
remove_children(pid)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def spawn_child(env, cmd)
|
40
|
-
pid = fork
|
41
|
-
raise "Fork failed." if pid == -1
|
42
|
-
|
43
|
-
unless pid
|
44
|
-
if RUBY_VERSION > "1.9"
|
45
|
-
exec(env, cmd)
|
46
|
-
else
|
47
|
-
swap_env(env) { exec(cmd) }
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
UI.debug "Spawned Spork server #{pid} ('#{cmd}')"
|
52
|
-
add_children(pid)
|
53
|
-
pid
|
54
|
-
end
|
55
|
-
|
56
|
-
def swap_env(env)
|
57
|
-
old_env = {}
|
58
|
-
env.each do |key, value|
|
59
|
-
old_env[key] = ENV[key]
|
60
|
-
ENV[key] = value
|
61
|
-
end
|
62
|
-
|
63
|
-
yield
|
64
|
-
|
65
|
-
env.each do |key, value|
|
66
|
-
ENV[key] = old_env[key]
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def terminated_children
|
71
|
-
stats = []
|
72
|
-
loop do
|
73
|
-
begin
|
74
|
-
pid, stat = ::Process.wait2(-1, ::Process::WNOHANG)
|
75
|
-
break if pid.nil?
|
76
|
-
stats << stat
|
77
|
-
rescue Errno::ECHILD
|
78
|
-
break
|
79
|
-
end
|
80
|
-
end
|
81
|
-
stats
|
82
|
-
end
|
83
|
-
|
84
|
-
def spork_command(type)
|
85
|
-
cmd_parts = []
|
86
|
-
cmd_parts << "bundle exec" if bundler?
|
87
|
-
cmd_parts << "spork"
|
88
|
-
|
89
|
-
case type
|
90
|
-
when "test_unit"
|
91
|
-
cmd_parts << "testunit -p #{options[:test_unit_port]}"
|
92
|
-
when "rspec"
|
93
|
-
cmd_parts << "-p #{options[:rspec_port]}"
|
94
|
-
when "cucumber"
|
95
|
-
cmd_parts << "cu -p #{options[:cucumber_port]}"
|
96
|
-
end
|
97
|
-
|
98
|
-
cmd_parts.join(" ")
|
99
|
-
end
|
100
|
-
|
101
|
-
def verify_launches(action)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
class Spork
|
5
|
+
class Runner
|
6
|
+
attr_accessor :options
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
options[:wait] ||= 30 # seconds
|
10
|
+
options[:test_unit_port] ||= 8988
|
11
|
+
options[:cucumber_port] ||= 8990
|
12
|
+
options[:rspec_port] ||= 8989
|
13
|
+
options[:rspec_env] ||= {}
|
14
|
+
options[:test_unit_env] ||= {}
|
15
|
+
options[:cucumber_env] ||= {}
|
16
|
+
options[:aggressive_kill] = true unless options[:aggressive_kill] == false
|
17
|
+
@options = options
|
18
|
+
ENV['SPORK_PIDS'] ||= ''
|
19
|
+
end
|
20
|
+
|
21
|
+
def launch_sporks(action)
|
22
|
+
UI.info "#{action.capitalize}ing Spork for #{sporked_gems} ", :reset => true
|
23
|
+
spawn_child(options[:test_unit_env], spork_command("test_unit")) if test_unit?
|
24
|
+
spawn_child(options[:rspec_env], spork_command("rspec")) if rspec?
|
25
|
+
spawn_child(options[:cucumber_env], spork_command("cucumber")) if cucumber?
|
26
|
+
verify_launches(action)
|
27
|
+
end
|
28
|
+
|
29
|
+
def kill_sporks
|
30
|
+
UI.debug "Killing Spork servers with PID: #{spork_pids.join(', ')}"
|
31
|
+
spork_pids.each do |pid|
|
32
|
+
::Process.kill("KILL", pid)
|
33
|
+
remove_children(pid)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def spawn_child(env, cmd)
|
40
|
+
pid = fork
|
41
|
+
raise "Fork failed." if pid == -1
|
42
|
+
|
43
|
+
unless pid
|
44
|
+
if RUBY_VERSION > "1.9"
|
45
|
+
exec(env, cmd)
|
46
|
+
else
|
47
|
+
swap_env(env) { exec(cmd) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
UI.debug "Spawned Spork server #{pid} ('#{cmd}')"
|
52
|
+
add_children(pid)
|
53
|
+
pid
|
54
|
+
end
|
55
|
+
|
56
|
+
def swap_env(env)
|
57
|
+
old_env = {}
|
58
|
+
env.each do |key, value|
|
59
|
+
old_env[key] = ENV[key]
|
60
|
+
ENV[key] = value
|
61
|
+
end
|
62
|
+
|
63
|
+
yield
|
64
|
+
|
65
|
+
env.each do |key, value|
|
66
|
+
ENV[key] = old_env[key]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def terminated_children
|
71
|
+
stats = []
|
72
|
+
loop do
|
73
|
+
begin
|
74
|
+
pid, stat = ::Process.wait2(-1, ::Process::WNOHANG)
|
75
|
+
break if pid.nil?
|
76
|
+
stats << stat
|
77
|
+
rescue Errno::ECHILD
|
78
|
+
break
|
79
|
+
end
|
80
|
+
end
|
81
|
+
stats
|
82
|
+
end
|
83
|
+
|
84
|
+
def spork_command(type)
|
85
|
+
cmd_parts = []
|
86
|
+
cmd_parts << "bundle exec" if bundler?
|
87
|
+
cmd_parts << "spork"
|
88
|
+
|
89
|
+
case type
|
90
|
+
when "test_unit"
|
91
|
+
cmd_parts << "testunit -p #{options[:test_unit_port]}"
|
92
|
+
when "rspec"
|
93
|
+
cmd_parts << "-p #{options[:rspec_port]}"
|
94
|
+
when "cucumber"
|
95
|
+
cmd_parts << "cu -p #{options[:cucumber_port]}"
|
96
|
+
end
|
97
|
+
|
98
|
+
cmd_parts.join(" ")
|
99
|
+
end
|
100
|
+
|
101
|
+
def verify_launches(action)
|
102
|
+
start_time = Time.now
|
103
|
+
if wait_for_launch(options[:wait])
|
104
|
+
UI.info "Spork server for #{sporked_gems} successfully #{action}ed", :reset => true
|
105
|
+
Notifier.notify "#{sporked_gems} successfully #{action}ed", :title => "Spork", :image => :success
|
106
|
+
else
|
107
|
+
UI.reset_line # workaround before Guard::UI update
|
108
|
+
UI.error "Could not #{action} Spork server for #{sporked_gems} after #{options[:wait]} seconds. I will continue waiting for a further 60 seconds."
|
109
|
+
Notifier.notify "#{sporked_gems} NOT #{action}ed. Continuing to wait for 60 seconds.", :title => "Spork", :image => :failed
|
110
|
+
if wait_for_launch(60)
|
111
|
+
total_time = Time.now - start_time
|
112
|
+
UI.info "Spork server for #{sporked_gems} eventually #{action}ed after #{total_time.to_i} seconds. Consider adjusting your :wait option beyond this time.", :reset => true
|
113
|
+
Notifier.notify "#{sporked_gems} eventually #{action}ed after #{total_time.to_i} seconds", :title => "Spork", :image => :success
|
114
|
+
else
|
115
|
+
UI.reset_line # workaround before Guard::UI update
|
116
|
+
UI.error "Could not #{action} Spork server for #{sporked_gems}. Make sure you can use it manually first."
|
117
|
+
Notifier.notify "#{sporked_gems} NOT #{action}ed", :title => "Spork", :image => :failed
|
118
|
+
throw :task_has_failed
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def wait_for_launch(wait)
|
124
|
+
wait.times do
|
125
|
+
sleep 1
|
126
|
+
begin
|
127
|
+
TCPSocket.new('localhost', options[:test_unit_port]).close if test_unit?
|
128
|
+
TCPSocket.new('localhost', options[:rspec_port]).close if rspec?
|
129
|
+
TCPSocket.new('localhost', options[:cucumber_port]).close if cucumber?
|
130
|
+
rescue Errno::ECONNREFUSED
|
131
|
+
next
|
132
|
+
end
|
133
|
+
return true # Success
|
134
|
+
end
|
135
|
+
return false # Failure
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_children(pid)
|
139
|
+
pids = spork_pids << pid
|
140
|
+
ENV['SPORK_PIDS'] = pids.join(',')
|
141
|
+
end
|
142
|
+
|
143
|
+
def remove_children(pid)
|
144
|
+
pids = spork_pids
|
145
|
+
deleted_pid = pids.delete(pid)
|
146
|
+
ENV['SPORK_PIDS'] = pids.join(',')
|
147
|
+
deleted_pid
|
148
|
+
end
|
149
|
+
|
150
|
+
def spork_pids
|
151
|
+
if ENV['SPORK_PIDS'] == '' && options[:aggressive_kill]
|
152
|
+
ps_spork_pids
|
153
|
+
else
|
154
|
+
ENV['SPORK_PIDS'].split(',').map { |pid| pid.to_i }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def ps_spork_pids
|
159
|
+
`ps aux | awk '/spork/&&!/awk/{print $2;}'`.split("\n").map { |pid| pid.to_i }
|
160
|
+
end
|
161
|
+
|
162
|
+
def sporked_gems
|
163
|
+
gems = []
|
164
|
+
gems << "Test::Unit" if test_unit?
|
165
|
+
gems << "RSpec" if rspec?
|
166
|
+
gems << "Cucumber" if cucumber?
|
167
|
+
gems.join(' & ')
|
168
|
+
end
|
169
|
+
|
170
|
+
def bundler?
|
171
|
+
@bundler ||= File.exist?("#{Dir.pwd}/Gemfile") && options[:bundler] != false
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_unit?
|
175
|
+
@test_unit ||= File.exist?("#{Dir.pwd}/test/test_helper.rb") && options[:test_unit] != false
|
176
|
+
end
|
177
|
+
|
178
|
+
def rspec?
|
179
|
+
@rspec ||= File.exist?("#{Dir.pwd}/spec") && options[:rspec] != false
|
180
|
+
end
|
181
|
+
|
182
|
+
def cucumber?
|
183
|
+
@cucumber ||= File.exist?("#{Dir.pwd}/features") && options[:cucumber] != false
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
data/lib/guard/spork/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guard-spork
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
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: 2011-
|
12
|
+
date: 2011-11-18 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: guard
|
16
|
-
requirement: &
|
16
|
+
requirement: &70366766978340 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.8.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70366766978340
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: spork
|
27
|
-
requirement: &
|
27
|
+
requirement: &70366766977880 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.8.4
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70366766977880
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bundler
|
38
|
-
requirement: &
|
38
|
+
requirement: &70366766977420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '1.0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70366766977420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &70366766976960 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '2.6'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70366766976960
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: guard-rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &70366766976500 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0.4'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70366766976500
|
69
69
|
description: Guard::Spork automatically manage Spork DRb servers.
|
70
70
|
email:
|
71
71
|
- thibaud@thibaud.me
|