guard-spork 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,131 +1,133 @@
1
- # Guard::Spork [![Build Status](https://secure.travis-ci.org/guard/guard-spork.png)](http://travis-ci.org/guard/guard-spokr)
2
-
3
- Guard::Spork allows to automatically & intelligently start/reload your RSpec/Cucumber/Test::Unit [Spork](https://github.com/timcharper/spork) server(s).
4
-
5
- * Compatible with Spork 0.8.4 & 0.9.0.rcX.
6
- * Tested against Ruby 1.8.7, 1.9.2, REE and the latest versions of JRuby & Rubinius.
7
-
8
- ## Install
9
-
10
- Please be sure to have [Guard](https://github.com/guard/guard) installed before continue.
11
-
12
- Install the gem:
13
-
14
- $ gem install guard-spork
15
-
16
- Add it to your Gemfile (inside test group):
17
-
18
- gem 'guard-spork'
19
-
20
- Add guard definition to your Guardfile with:
21
-
22
- $ guard init spork
23
-
24
- ## Usage
25
-
26
- Please read the [Guard usage documentation](https://github.com/guard/guard#readme).
27
-
28
- ## Guardfile
29
-
30
- Please read [Guard doc](https://github.com/guard/guard#readme) for more info about the Guardfile DSL.
31
-
32
- **IMPORTANT: place Spork guard before RSpec/Cucumber/Test::Unit guards!**
33
-
34
- ### Rails app
35
-
36
- ``` ruby
37
- guard 'spork' do
38
- watch('config/application.rb')
39
- watch('config/environment.rb')
40
- watch(%r{^config/environments/.*\.rb$})
41
- watch(%r{^config/initializers/.*\.rb$})
42
- watch('Gemfile')
43
- watch('Gemfile.lock')
44
- watch('spec/spec_helper.rb')
45
- watch('test/test_helper.rb')
46
- end
47
- ```
48
-
49
- ### Running specs over Spork
50
-
51
- Pass the `:cli => "--drb"` option to [Guard::RSpec](https://github.com/guard/guard-rspec) and/or [Guard::Cucumber](https://github.com/guard/guard-cucumber) to run them over the Spork DRb server:
52
-
53
- ``` ruby
54
- guard 'rspec', :cli => "--drb" do
55
- # ...
56
- end
57
-
58
- guard 'cucumber', :cli => "--drb" do
59
- # ...
60
- end
61
- ```
62
-
63
- For MiniTest Guard you should pass the `:drb => true` option:
64
-
65
- ``` ruby
66
- guard 'minitest', :drb => true do
67
- # ...
68
- end
69
- ```
70
-
71
- ## Options
72
-
73
- Guard::Spork automatically detect RSpec/Cucumber/Test::Unit/Bundler presence but you can disable any of them with the corresponding options:
74
-
75
- ``` ruby
76
- guard 'spork', :cucumber => false, :bundler => false do
77
- # ...
78
- end
79
- ```
80
-
81
-
82
- You can provide additional environment variables for RSpec, Cucumber, and Test::Unit with the <tt>:rspec_env</tt>, <tt>:cucumber_env</tt>, and <tt>:test_unit_env</tt> options:
83
-
84
- ``` ruby
85
- guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'cucumber' }, :rspec_env => { 'RAILS_ENV' => 'test' }, :test_unit_env => { 'RAILS_ENV' => 'test' } do
86
- # ...
87
- end
88
- ```
89
-
90
- Available options:
91
-
92
- ``` ruby
93
- :wait => 60 # Seconds to wait for the server to start, default: 30
94
- :cucumber => false
95
- :rspec => false
96
- :test_unit => false
97
- :bundler => false # Don't use "bundle exec"
98
- :test_unit_port => 1233 # Default: 8988
99
- :rspec_port => 1234 # Default: 8989
100
- :cucumber_port => 4321 # Default: 8990
101
- :test_unit_env => { 'RAILS_ENV' => 'baz' } # Default: nil
102
- :rspec_env => { 'RAILS_ENV' => 'foo' } # Default: nil
103
- :cucumber_env => { 'RAILS_ENV' => 'bar' } # Default: nil
104
- :aggressive_kill => false # Default: true, will search Spork pids from `ps aux` and kill them all on start.
105
- ```
106
-
107
- ## Common troubleshooting
108
-
109
- If you can start Spork manually but get the following error message when using Guard::Spork:
110
-
111
- Starting Spork for RSpec ERROR: Could not start Spork for RSpec/Cucumber. Make sure you can use it manually first.
112
-
113
- Try to increase the value of the `:wait => 60` option before any further investigation.
114
-
115
- ## Development
116
-
117
- * Source hosted at [GitHub](https://github.com/guard/guard-spork).
118
- * Report issues and feature requests to [GitHub Issues](https://github.com/guard/guard-spork/issues).
119
-
120
- Pull requests are very welcome! Please try to follow these simple "rules", though:
121
-
122
- * Please create a topic branch for every separate change you make.
123
- * Make sure your patches are well tested.
124
- * Update the README (if applicable).
125
- * Please **do not change** the version number.
126
-
127
- For questions please join us on our [Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net).
128
-
129
- ## Author
130
-
131
- [Thibaud Guillaume-Gentil](https://github.com/thibaudgg)
1
+ # Guard::Spork [![Build Status](https://secure.travis-ci.org/guard/guard-spork.png)](http://travis-ci.org/guard/guard-spork)
2
+
3
+ Guard::Spork allows to automatically & intelligently start/reload your RSpec/Cucumber/Test::Unit [Spork](https://github.com/timcharper/spork) server(s).
4
+
5
+ * Compatible with Spork 0.8.4 & 0.9.0.rcX.
6
+ * Tested against Ruby 1.8.7, 1.9.2, REE and the latest versions of JRuby & Rubinius.
7
+
8
+ ## Install
9
+
10
+ Please be sure to have [Guard](https://github.com/guard/guard) installed before continue.
11
+
12
+ Install the gem:
13
+
14
+ $ gem install guard-spork
15
+
16
+ Add it to your Gemfile (inside test group):
17
+
18
+ gem 'guard-spork'
19
+
20
+ Add guard definition to your Guardfile with:
21
+
22
+ $ guard init spork
23
+
24
+ ## Usage
25
+
26
+ Please read the [Guard usage documentation](https://github.com/guard/guard#readme).
27
+
28
+ ## Guardfile
29
+
30
+ Please read [Guard doc](https://github.com/guard/guard#readme) for more info about the Guardfile DSL.
31
+
32
+ **IMPORTANT: place Spork guard before RSpec/Cucumber/Test::Unit guards!**
33
+
34
+ ### Rails app
35
+
36
+ ``` ruby
37
+ guard 'spork' do
38
+ watch('config/application.rb')
39
+ watch('config/environment.rb')
40
+ watch(%r{^config/environments/.*\.rb$})
41
+ watch(%r{^config/initializers/.*\.rb$})
42
+ watch('Gemfile')
43
+ watch('Gemfile.lock')
44
+ watch('spec/spec_helper.rb') { :rspec }
45
+ watch('test/test_helper.rb') { :test_unit }
46
+ watch(%r{features/support/}) { :cucumber }
47
+ end
48
+ ```
49
+
50
+ ### Running specs over Spork
51
+
52
+ Pass the `:cli => "--drb"` option to [Guard::RSpec](https://github.com/guard/guard-rspec) and/or [Guard::Cucumber](https://github.com/guard/guard-cucumber) to run them over the Spork DRb server:
53
+
54
+ ``` ruby
55
+ guard 'rspec', :cli => "--drb" do
56
+ # ...
57
+ end
58
+
59
+ guard 'cucumber', :cli => "--drb" do
60
+ # ...
61
+ end
62
+ ```
63
+
64
+ For MiniTest Guard you should pass the `:drb => true` option:
65
+
66
+ ``` ruby
67
+ guard 'minitest', :drb => true do
68
+ # ...
69
+ end
70
+ ```
71
+
72
+ ## Options
73
+
74
+ Guard::Spork automatically detect RSpec/Cucumber/Test::Unit/Bundler presence but you can disable any of them with the corresponding options:
75
+
76
+ ``` ruby
77
+ guard 'spork', :cucumber => false, :bundler => false do
78
+ # ...
79
+ end
80
+ ```
81
+
82
+
83
+ You can provide additional environment variables for RSpec, Cucumber, and Test::Unit with the <tt>:rspec_env</tt>, <tt>:cucumber_env</tt>, and <tt>:test_unit_env</tt> options:
84
+
85
+ ``` ruby
86
+ guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'cucumber' }, :rspec_env => { 'RAILS_ENV' => 'test' }, :test_unit_env => { 'RAILS_ENV' => 'test' } do
87
+ # ...
88
+ end
89
+ ```
90
+
91
+ Available options:
92
+
93
+ ``` ruby
94
+ :wait => 60 # Seconds to wait for the server to start, default: 30
95
+ :cucumber => false
96
+ :rspec => false
97
+ :test_unit => false
98
+ :bundler => false # Don't use "bundle exec"
99
+ :test_unit_port => 1233 # Default: 8988
100
+ :rspec_port => 1234 # Default: 8989
101
+ :cucumber_port => 4321 # Default: 8990
102
+ :test_unit_env => { 'RAILS_ENV' => 'baz' } # Default: nil
103
+ :rspec_env => { 'RAILS_ENV' => 'foo' } # Default: nil
104
+ :cucumber_env => { 'RAILS_ENV' => 'bar' } # Default: nil
105
+ :aggressive_kill => false # Default: true, will search Spork pids from `ps aux` and kill them all on start.
106
+ ```
107
+
108
+ ## Common troubleshooting
109
+
110
+ If you can start Spork manually but get the following error message when using Guard::Spork:
111
+
112
+ Starting Spork for RSpec ERROR: Could not start Spork for RSpec/Cucumber. Make sure you can use it manually first.
113
+
114
+ Try to increase the value of the `:wait => 60` option before any further investigation.
115
+ It's possible that this error is the result of an unnecessary /test directory in the root of your application. Removing the /test directory entirely may resolve this error.
116
+
117
+ ## Development
118
+
119
+ * Source hosted at [GitHub](https://github.com/guard/guard-spork).
120
+ * Report issues and feature requests to [GitHub Issues](https://github.com/guard/guard-spork/issues).
121
+
122
+ Pull requests are very welcome! Please try to follow these simple "rules", though:
123
+
124
+ * Please create a topic branch for every separate change you make.
125
+ * Make sure your patches are well tested.
126
+ * Update the README (if applicable).
127
+ * Please **do not change** the version number.
128
+
129
+ For questions please join us on our [Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net).
130
+
131
+ ## Author
132
+
133
+ [Thibaud Guillaume-Gentil](https://github.com/thibaudgg)
@@ -5,15 +5,21 @@ module Guard
5
5
  class Spork < Guard
6
6
 
7
7
  autoload :Runner, 'guard/spork/runner'
8
+ autoload :SporkInstance, 'guard/spork/spork_instance'
8
9
  attr_accessor :runner
9
10
 
10
11
  def initialize(watchers=[], options={})
11
12
  super
12
13
  @runner = Runner.new(options)
14
+
15
+ # This class will be reinitialized by Guard when the Guardfile
16
+ # is reevaluated, so we must always begin by trying to clean
17
+ # up after any hypothetical predecessor
18
+ runner.reevaluate
13
19
  end
14
20
 
15
21
  def start
16
- runner.kill_sporks
22
+ runner.kill_global_sporks
17
23
  runner.launch_sporks("start")
18
24
  end
19
25
 
@@ -22,9 +28,14 @@ module Guard
22
28
  runner.launch_sporks("reload")
23
29
  end
24
30
 
25
- def run_on_change(paths)
26
- runner.kill_sporks
27
- runner.launch_sporks("reload")
31
+ def run_on_change(paths_or_symbol)
32
+ if paths_or_symbol.is_a?(Symbol)
33
+ runner.kill_sporks(paths_or_symbol)
34
+ runner.launch_sporks("reload", paths_or_symbol)
35
+ else
36
+ runner.kill_sporks
37
+ runner.launch_sporks("reload")
38
+ end
28
39
  end
29
40
 
30
41
  def stop
@@ -1,188 +1,138 @@
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
+ require 'socket'
2
+
3
+ module Guard
4
+ class Spork
5
+ class Runner
6
+ attr_accessor :options
7
+ attr_reader :spork_instances
8
+
9
+ def initialize(options={})
10
+ options[:wait] ||= 30 # seconds
11
+ options[:test_unit_port] ||= 8988
12
+ options[:cucumber_port] ||= 8990
13
+ options[:rspec_port] ||= 8989
14
+ options[:rspec_env] ||= {}
15
+ options[:test_unit_env] ||= {}
16
+ options[:cucumber_env] ||= {}
17
+ options[:aggressive_kill] = true unless options[:aggressive_kill] == false
18
+ @options = options
19
+ initialize_spork_instances
20
+ end
21
+
22
+ def launch_sporks(action, type = nil)
23
+ instances = find_instances(type)
24
+ UI.info "#{action.capitalize}ing Spork for #{instances.join(', ')}", :reset => true
25
+ instances.each(&:start)
26
+ verify_launches(action, instances)
27
+ end
28
+
29
+ def kill_sporks(type = nil)
30
+ alive = find_instances(type).select(&:alive?)
31
+ UI.debug "Killing Spork servers with PID: #{alive.map(&:pid).join(', ')}"
32
+ alive.each(&:stop)
33
+ end
34
+
35
+ def kill_global_sporks
36
+ if options[:aggressive_kill]
37
+ kill_global_sporks!
38
+ end
39
+ end
40
+
41
+ def kill_global_sporks!
42
+ kill_pids ps_spork_pids
43
+ end
44
+
45
+ def reevaluate
46
+ if ENV['SPORK_PIDS']
47
+ kill_pids(ENV['SPORK_PIDS'].split(',').map(&:to_i))
48
+ ENV.delete('SPORK_PIDS')
49
+ launch_sporks("reload")
50
+ end
51
+ end
52
+
53
+ private
54
+ def initialize_spork_instances
55
+ @spork_instances = []
56
+ [:rspec, :cucumber, :test_unit].each do |type|
57
+ port, env = options[:"#{type}_port"], options[:"#{type}_env"]
58
+ spork_instances << SporkInstance.new(type, port, env, :bundler => should_use?(:bundler)) if should_use?(type)
59
+ end
60
+ end
61
+
62
+ def kill_pids(pids)
63
+ UI.debug "Killing Spork servers with PID: #{pids.join(', ')}"
64
+ pids.each { |pid| Process.kill("KILL", pid) }
65
+ end
66
+
67
+ def find_instances(type = nil)
68
+ if type.nil?
69
+ spork_instances
70
+ else
71
+ spork_instances.select { |instance| instance.type == type }
72
+ end
73
+ end
74
+
75
+ def verify_launches(action, instances)
76
+ start_time = Time.now
77
+ names = instances.join(', ')
78
+
79
+ if wait_for_launch(instances, options[:wait])
80
+ UI.info "Spork server for #{names} successfully #{action}ed", :reset => true
81
+ Notifier.notify "#{names} successfully #{action}ed", :title => "Spork", :image => :success
82
+ else
83
+ UI.reset_line # workaround before Guard::UI update
84
+ UI.error "Could not #{action} Spork server for #{names} after #{options[:wait]} seconds. I will continue waiting for a further 60 seconds."
85
+ Notifier.notify "#{names} NOT #{action}ed. Continuing to wait for 60 seconds.", :title => "Spork", :image => :failed
86
+ if wait_for_launch(instances, 60)
87
+ total_time = Time.now - start_time
88
+ UI.info "Spork server for #{names} eventually #{action}ed after #{total_time.to_i} seconds. Consider adjusting your :wait option beyond this time.", :reset => true
89
+ Notifier.notify "#{names} eventually #{action}ed after #{total_time.to_i} seconds", :title => "Spork", :image => :success
90
+ else
91
+ UI.reset_line # workaround before Guard::UI update
92
+ UI.error "Could not #{action} Spork server for #{names}. Make sure you can use it manually first."
93
+ Notifier.notify "#{names} NOT #{action}ed", :title => "Spork", :image => :failed
94
+ throw :task_has_failed
95
+ end
96
+ end
97
+ end
98
+
99
+ def wait_for_launch(instances, wait)
100
+ not_running = instances.dup
101
+ wait.times do
102
+ sleep 1
103
+ not_running.delete_if { |instance| instance.running? }
104
+ return true if not_running.empty?
105
+ end
106
+ false
107
+ end
108
+
109
+ def ps_spork_pids
110
+ `ps aux | awk '/spork/&&!/awk/{print $2;}'`.split("\n").map { |pid| pid.to_i }
111
+ end
112
+
113
+ def should_use?(what)
114
+ if options[what].nil?
115
+ send("detect_#{what}")
116
+ else
117
+ options[what]
118
+ end
119
+ end
120
+
121
+ def detect_bundler
122
+ File.exist?("Gemfile")
123
+ end
124
+
125
+ def detect_test_unit
126
+ File.exist?("test/test_helper.rb")
127
+ end
128
+
129
+ def detect_rspec
130
+ File.exist?("spec")
131
+ end
132
+
133
+ def detect_cucumber
134
+ File.exist?("features")
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,87 @@
1
+ module Guard
2
+ class Spork
3
+ class SporkInstance
4
+ attr_reader :type, :env, :port, :options, :pid
5
+
6
+ def initialize(type, port, env, options)
7
+ @type = type
8
+ @port = port
9
+ @env = env
10
+ @options = options
11
+ end
12
+
13
+ def to_s
14
+ case type
15
+ when :rspec
16
+ "RSpec"
17
+ when :cucumber
18
+ "Cucumber"
19
+ when :test_unit
20
+ "Test::Unit"
21
+ else
22
+ type.to_s
23
+ end
24
+ end
25
+
26
+ def start
27
+ @pid = fork do
28
+ exec env, command
29
+ end
30
+ store_pid
31
+ end
32
+
33
+ def stop
34
+ Process.kill('KILL', pid)
35
+ end
36
+
37
+ def alive?
38
+ return false unless pid
39
+ Process.waitpid(pid, Process::WNOHANG).nil?
40
+ end
41
+
42
+ def running?
43
+ return false unless pid
44
+ TCPSocket.new('localhost', port).close
45
+ true
46
+ rescue Errno::ECONNREFUSED
47
+ false
48
+ end
49
+
50
+ def command
51
+ parts = []
52
+ parts << "bundle exec" if use_bundler?
53
+ parts << "spork"
54
+
55
+ if type == :test_unit
56
+ parts << "testunit"
57
+ elsif type == :cucumber
58
+ parts << "cu"
59
+ end
60
+
61
+ parts << "-p #{port}"
62
+ parts.join(" ")
63
+ end
64
+
65
+ def env_exec(environment, command)
66
+ if RUBY_VERSION > "1.9"
67
+ exec environment, command
68
+ else
69
+ environment.each_pair { |key, value| ENV[key] = value }
70
+ exec command
71
+ end
72
+ end
73
+
74
+ private
75
+ def use_bundler?
76
+ options[:bundler]
77
+ end
78
+
79
+ def store_pid
80
+ # We need to store away the PIDs somewhere safe since
81
+ # Guard will destroy our class instances when Guardfile is
82
+ # reevaluated without telling us beforehand
83
+ ENV['SPORK_PIDS'] = [ENV['SPORK_PIDS'], pid.to_s].compact.join(",")
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,10 +1,11 @@
1
- guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
2
- watch('config/application.rb')
3
- watch('config/environment.rb')
4
- watch(%r{^config/environments/.+\.rb$})
5
- watch(%r{^config/initializers/.+\.rb$})
6
- watch('Gemfile')
7
- watch('Gemfile.lock')
8
- watch('spec/spec_helper.rb')
9
- watch('test/test_helper.rb')
10
- end
1
+ guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
2
+ watch('config/application.rb')
3
+ watch('config/environment.rb')
4
+ watch(%r{^config/environments/.+\.rb$})
5
+ watch(%r{^config/initializers/.+\.rb$})
6
+ watch('Gemfile')
7
+ watch('Gemfile.lock')
8
+ watch('spec/spec_helper.rb') { :rspec }
9
+ watch('test/test_helper.rb') { :test_unit }
10
+ watch(%r{features/support/}) { :cucumber }
11
+ end
@@ -1,5 +1,5 @@
1
1
  module Guard
2
2
  module SporkVersion
3
- VERSION = "0.3.2"
3
+ VERSION = "0.4.0"
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.2
4
+ version: 0.4.0
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-11-18 00:00:00.000000000Z
12
+ date: 2011-12-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: guard
16
- requirement: &70366766978340 !ruby/object:Gem::Requirement
16
+ requirement: &70258365044020 !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: *70366766978340
24
+ version_requirements: *70258365044020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: spork
27
- requirement: &70366766977880 !ruby/object:Gem::Requirement
27
+ requirement: &70258365042320 !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: *70366766977880
35
+ version_requirements: *70258365042320
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &70366766977420 !ruby/object:Gem::Requirement
38
+ requirement: &70258365039420 !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: *70366766977420
46
+ version_requirements: *70258365039420
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70366766976960 !ruby/object:Gem::Requirement
49
+ requirement: &70258365037420 !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: *70366766976960
57
+ version_requirements: *70258365037420
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &70366766976500 !ruby/object:Gem::Requirement
60
+ requirement: &70258365026640 !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: *70366766976500
68
+ version_requirements: *70258365026640
69
69
  description: Guard::Spork automatically manage Spork DRb servers.
70
70
  email:
71
71
  - thibaud@thibaud.me
@@ -74,6 +74,7 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - lib/guard/spork/runner.rb
77
+ - lib/guard/spork/spork_instance.rb
77
78
  - lib/guard/spork/templates/Guardfile
78
79
  - lib/guard/spork/version.rb
79
80
  - lib/guard/spork.rb
@@ -99,8 +100,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
100
  version: 1.3.6
100
101
  requirements: []
101
102
  rubyforge_project: guard-spork
102
- rubygems_version: 1.8.9
103
+ rubygems_version: 1.8.10
103
104
  signing_key:
104
105
  specification_version: 3
105
106
  summary: Guard gem for Spork
106
107
  test_files: []
108
+ has_rdoc: