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 CHANGED
@@ -90,7 +90,7 @@ end
90
90
  Available options:
91
91
 
92
92
  ``` ruby
93
- :wait => 30 # Seconds to wait for the server to starts, default: 20
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
- :aggressive_kills => false # Default: true, will search Spork pids from `ps aux` and kill them all on start.
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
@@ -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] ||= 20 # 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
- options[:wait].times do
103
- sleep 1
104
- begin
105
- TCPSocket.new('localhost', options[:test_unit_port]).close if test_unit?
106
- TCPSocket.new('localhost', options[:rspec_port]).close if rspec?
107
- TCPSocket.new('localhost', options[:cucumber_port]).close if cucumber?
108
- rescue Errno::ECONNREFUSED
109
- next
110
- end
111
- UI.info "Spork server for #{sporked_gems} successfully #{action}ed", :reset => true
112
- Notifier.notify "#{sporked_gems} successfully #{action}ed", :title => "Spork", :image => :success
113
- return true
114
- end
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
-
121
- def add_children(pid)
122
- pids = spork_pids << pid
123
- ENV['SPORK_PIDS'] = pids.join(',')
124
- end
125
-
126
- def remove_children(pid)
127
- pids = spork_pids
128
- deleted_pid = pids.delete(pid)
129
- ENV['SPORK_PIDS'] = pids.join(',')
130
- deleted_pid
131
- end
132
-
133
- def spork_pids
134
- if ENV['SPORK_PIDS'] == '' && options[:aggressive_kill]
135
- ps_spork_pids
136
- else
137
- ENV['SPORK_PIDS'].split(',').map { |pid| pid.to_i }
138
- end
139
- end
140
-
141
- def ps_spork_pids
142
- `ps aux | awk '/spork/&&!/awk/{print $2;}'`.split("\n").map { |pid| pid.to_i }
143
- end
144
-
145
- def sporked_gems
146
- gems = []
147
- gems << "Test::Unit" if test_unit?
148
- gems << "RSpec" if rspec?
149
- gems << "Cucumber" if cucumber?
150
- gems.join(' & ')
151
- end
152
-
153
- def bundler?
154
- @bundler ||= File.exist?("#{Dir.pwd}/Gemfile") && options[:bundler] != false
155
- end
156
-
157
- def test_unit?
158
- @test_unit ||= File.exist?("#{Dir.pwd}/test/test_helper.rb") && options[:test_unit] != false
159
- end
160
-
161
- def rspec?
162
- @rspec ||= File.exist?("#{Dir.pwd}/spec") && options[:rspec] != false
163
- end
164
-
165
- def cucumber?
166
- @cucumber ||= File.exist?("#{Dir.pwd}/features") && options[:cucumber] != false
167
- end
168
-
169
- end
170
- end
171
- end
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
@@ -1,5 +1,5 @@
1
1
  module Guard
2
2
  module SporkVersion
3
- VERSION = "0.3.1"
3
+ VERSION = "0.3.2"
4
4
  end
5
5
  end
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.1
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-10-08 00:00:00.000000000Z
12
+ date: 2011-11-18 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: guard
16
- requirement: &70103270744260 !ruby/object:Gem::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: *70103270744260
24
+ version_requirements: *70366766978340
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: spork
27
- requirement: &70103270743040 !ruby/object:Gem::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: *70103270743040
35
+ version_requirements: *70366766977880
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &70103270742200 !ruby/object:Gem::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: *70103270742200
46
+ version_requirements: *70366766977420
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70103270741260 !ruby/object:Gem::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: *70103270741260
57
+ version_requirements: *70366766976960
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &70103270732320 !ruby/object:Gem::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: *70103270732320
68
+ version_requirements: *70366766976500
69
69
  description: Guard::Spork automatically manage Spork DRb servers.
70
70
  email:
71
71
  - thibaud@thibaud.me