spin 0.4.6 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/bin/spin +62 -12
  2. metadata +2 -2
data/bin/spin CHANGED
@@ -47,9 +47,9 @@ def disconnect(connection)
47
47
  connection.close
48
48
  end
49
49
 
50
- def rails_root
50
+ def rails_root(preload)
51
51
  path = Pathname.pwd
52
- until path.join('config/application.rb').file?
52
+ until path.join(preload).file?
53
53
  return if path.root?
54
54
  path = path.parent
55
55
  end
@@ -57,9 +57,10 @@ def rails_root
57
57
  end
58
58
 
59
59
  # ## spin serve
60
- def serve(force_rspec, force_testunit, time, push_results)
61
- root_path = rails_root and Dir.chdir(root_path)
60
+ def serve(force_rspec, force_testunit, time, push_results, preload)
61
+ root_path = rails_root(preload) and Dir.chdir(root_path)
62
62
  file = socket_file
63
+ Spin.parse_hook_file(root_path)
63
64
 
64
65
  # We delete the tmp file for the Unix socket if it already exists. The file
65
66
  # is scoped to the `pwd`, so if it already exists then it must be from an
@@ -69,6 +70,12 @@ def serve(force_rspec, force_testunit, time, push_results)
69
70
  # This socket is how we communicate with `spin push`.
70
71
  socket = UNIXServer.open(file)
71
72
 
73
+ # Trap SIGINT (Ctrl-C) so that we exit cleanly.
74
+ trap('SIGINT') {
75
+ socket.close
76
+ exit
77
+ }
78
+
72
79
  ENV['RAILS_ENV'] = 'test' unless ENV['RAILS_ENV']
73
80
 
74
81
  test_framework = nil
@@ -85,7 +92,9 @@ def serve(force_rspec, force_testunit, time, push_results)
85
92
  # But you can't initialize the application because any non-trivial app will
86
93
  # involve it's models/controllers, etc. in its initialization, which you
87
94
  # definitely don't want to preload.
88
- require File.expand_path 'config/application'
95
+ Spin.execute_hook(:before_preload)
96
+ require File.expand_path preload.sub('.rb','')
97
+ Spin.execute_hook(:after_preload)
89
98
 
90
99
  # Determine the test framework to use using the passed-in 'force' options
91
100
  # or else default to checking for defined constants.
@@ -108,7 +117,7 @@ def serve(force_rspec, force_testunit, time, push_results)
108
117
  # This is the amount of time that you'll save on each subsequent test run.
109
118
  puts "Preloaded Rails env in #{sec}s..."
110
119
  else
111
- warn "Could not find config/application.rb. Are you running this from the root of a Rails project?"
120
+ warn "Could not find #{preload}. Are you running this from the root of a Rails project?"
112
121
  end
113
122
 
114
123
  puts "Pushing test results back to push processes" if push_results
@@ -166,6 +175,7 @@ ensure
166
175
  end
167
176
 
168
177
  def fork_and_run(files, push_results, test_framework, conn)
178
+ Spin.execute_hook(:before_fork)
169
179
  # We fork(2) before loading the file so that our pristine preloaded
170
180
  # environment is untouched. The child process will load whatever code it
171
181
  # needs to, then it exits and we're back to the baseline preloaded app.
@@ -173,11 +183,19 @@ def fork_and_run(files, push_results, test_framework, conn)
173
183
  # To push the test results to the push process instead of having them
174
184
  # displayed by the server, we reopen $stdout/$stderr to the open
175
185
  # connection.
186
+ tty = files.delete "tty?"
176
187
  if push_results
177
188
  $stdout.reopen(conn)
189
+ if tty
190
+ def $stdout.tty?
191
+ true
192
+ end
193
+ end
178
194
  $stderr.reopen(conn)
179
195
  end
180
196
 
197
+ Spin.execute_hook(:after_fork)
198
+
181
199
  puts
182
200
  puts "Loading #{files.inspect}"
183
201
 
@@ -198,7 +216,7 @@ def fork_and_run(files, push_results, test_framework, conn)
198
216
  end
199
217
 
200
218
  # ## spin push
201
- def push
219
+ def push(preload)
202
220
  # The filenames that we will spin up to `spin serve` are passed in as
203
221
  # arguments.
204
222
  files_to_load = ARGV
@@ -208,7 +226,7 @@ def push
208
226
  # bit will just be ignored.
209
227
  #
210
228
  # We build a string like `file1.rb|file2.rb` and pass it up to the server.
211
- files_to_load.map! do |file|
229
+ files_to_load = files_to_load.map do |file|
212
230
  args = file.split(':')
213
231
 
214
232
  file_name = args.first.to_s
@@ -232,13 +250,14 @@ def push
232
250
  end
233
251
  end.compact.uniq
234
252
 
235
- if root_path = rails_root
253
+ if root_path = rails_root(preload)
236
254
  files_to_load.map! do |file|
237
255
  Pathname.new(file).expand_path.relative_path_from(root_path).to_s
238
256
  end
239
257
  Dir.chdir root_path
240
258
  end
241
259
 
260
+ files_to_load << "tty?" if $stdout.tty?
242
261
  f = files_to_load.join(SEPARATOR)
243
262
 
244
263
  abort if f.empty?
@@ -254,14 +273,41 @@ def push
254
273
  break if line[-1,1] == "\0"
255
274
  print line
256
275
  end
257
- rescue Errno::ECONNREFUSED
276
+ rescue Errno::ECONNREFUSED, Errno::ENOENT
258
277
  abort "Connection was refused. Have you started up `spin serve` yet?"
259
278
  end
260
279
 
280
+ module Spin
281
+ HOOKS = [:before_fork, :after_fork, :before_preload, :after_preload]
282
+
283
+ def self.hook(name, &block)
284
+ raise unless HOOKS.include?(name)
285
+ _hooks(name) << block
286
+ end
287
+
288
+ def self.execute_hook(name)
289
+ raise unless HOOKS.include?(name)
290
+ _hooks(name).each(&:call)
291
+ end
292
+
293
+ def self.parse_hook_file(root)
294
+ load(root.join(".spin.rb"))
295
+ end
296
+
297
+ private
298
+
299
+ def self._hooks(name)
300
+ @hooks ||= {}
301
+ @hooks[name] ||= []
302
+ @hooks[name]
303
+ end
304
+ end
305
+
261
306
  force_rspec = false
262
307
  force_testunit = false
263
308
  time = false
264
309
  push_results = false
310
+ preload = "config/application.rb"
265
311
  options = OptionParser.new do |opts|
266
312
  opts.banner = usage
267
313
  opts.separator ""
@@ -287,6 +333,10 @@ options = OptionParser.new do |opts|
287
333
  push_results = v
288
334
  end
289
335
 
336
+ opts.on('--preload FILE', "Preload this file instead of #{preload}") do |v|
337
+ preload = v
338
+ end
339
+
290
340
  opts.separator "General Options:"
291
341
  opts.on('-e', 'Stub to keep kicker happy')
292
342
  opts.on('-h', '--help') do
@@ -298,8 +348,8 @@ options.parse!
298
348
 
299
349
  subcommand = ARGV.shift
300
350
  case subcommand
301
- when 'serve' then serve(force_rspec, force_testunit, time, push_results)
302
- when 'push' then push
351
+ when 'serve' then serve(force_rspec, force_testunit, time, push_results, preload)
352
+ when 'push' then push(preload)
303
353
  else
304
354
  $stderr.puts options
305
355
  exit 1
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-21 00:00:00.000000000 Z
12
+ date: 2012-07-25 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'Spin preloads your Rails environment to speed up your autotest(ish)
15
15
  workflow.