spring 1.0.0 → 1.1.0.beta2

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.
@@ -0,0 +1,333 @@
1
+ require "spring/env"
2
+
3
+ module Spring
4
+ module Test
5
+ class RailsVersion
6
+ attr_reader :version
7
+
8
+ def initialize(string)
9
+ @version = Gem::Version.new(string)
10
+ end
11
+
12
+ def rails_3?
13
+ version < Gem::Version.new("4.0.0")
14
+ end
15
+ alias needs_testunit? rails_3?
16
+
17
+ def test_command
18
+ needs_testunit? ? 'bin/testunit' : 'bin/rake test'
19
+ end
20
+
21
+ def controller_tests_dir
22
+ rails_3? ? 'functional' : 'controllers'
23
+ end
24
+
25
+ def bundles_spring?
26
+ version >= Gem::Version.new("4.1.0.beta1")
27
+ end
28
+
29
+ def major
30
+ version.segments[0]
31
+ end
32
+
33
+ def minor
34
+ version.segments[1]
35
+ end
36
+ end
37
+
38
+ class Application
39
+ DEFAULT_TIMEOUT = ENV['CI'] ? 30 : 10
40
+
41
+ attr_reader :root, :spring_env
42
+
43
+ def initialize(root)
44
+ @root = Pathname.new(root)
45
+ @spring_env = Spring::Env.new(root)
46
+ end
47
+
48
+ def exists?
49
+ root.exist?
50
+ end
51
+
52
+ def stdout
53
+ @stdout ||= IO.pipe
54
+ end
55
+
56
+ def stderr
57
+ @stderr ||= IO.pipe
58
+ end
59
+
60
+ def log_file_path
61
+ path("tmp/spring.log")
62
+ end
63
+
64
+ def log_file
65
+ @log_file ||= log_file_path.open("w+")
66
+ end
67
+
68
+ def env
69
+ @env ||= {
70
+ "GEM_HOME" => gem_home.to_s,
71
+ "GEM_PATH" => "",
72
+ "HOME" => user_home.to_s,
73
+ "RAILS_ENV" => nil,
74
+ "RACK_ENV" => nil,
75
+ "SPRING_LOG" => log_file_path.to_s
76
+ }
77
+ end
78
+
79
+ def path(addition)
80
+ root.join addition
81
+ end
82
+
83
+ def gemfile
84
+ path "Gemfile"
85
+ end
86
+
87
+ def gem_home
88
+ path "vendor/gems/#{RUBY_VERSION}"
89
+ end
90
+
91
+ def user_home
92
+ path "user_home"
93
+ end
94
+
95
+ def spring
96
+ gem_home.join "bin/spring"
97
+ end
98
+
99
+ def rails_version
100
+ @rails_version ||= RailsVersion.new(gemfile.read.match(/gem 'rails', '(.*)'/)[1])
101
+ end
102
+
103
+ def spring_test_command
104
+ "#{rails_version.test_command} #{test}"
105
+ end
106
+
107
+ def stop_spring
108
+ run "#{spring} stop"
109
+ rescue Errno::ENOENT
110
+ end
111
+
112
+ def test
113
+ path "test/#{rails_version.controller_tests_dir}/posts_controller_test.rb"
114
+ end
115
+
116
+ def controller
117
+ path "app/controllers/posts_controller.rb"
118
+ end
119
+
120
+ def application_config
121
+ path "config/application.rb"
122
+ end
123
+
124
+ def spring_config
125
+ path "config/spring.rb"
126
+ end
127
+
128
+ def run(command, opts = {})
129
+ start_time = Time.now
130
+
131
+ Bundler.with_clean_env do
132
+ Process.spawn(
133
+ env,
134
+ command.to_s,
135
+ out: stdout.last,
136
+ err: stderr.last,
137
+ in: :close,
138
+ chdir: root.to_s,
139
+ )
140
+ end
141
+
142
+ _, status = Timeout.timeout(opts.fetch(:timeout, DEFAULT_TIMEOUT)) { Process.wait2 }
143
+
144
+ if pid = spring_env.pid
145
+ @server_pid = pid
146
+ lines = `ps -A -o ppid= -o pid= | egrep '^\\s*#{@server_pid}'`.lines
147
+ @application_pids = lines.map { |l| l.split.last.to_i }
148
+ end
149
+
150
+ output = read_streams
151
+ puts dump_streams(command, output) if ENV["SPRING_DEBUG"]
152
+
153
+ @times << (Time.now - start_time) if @times
154
+
155
+ output.merge(status: status, command: command)
156
+ rescue Timeout::Error => e
157
+ raise e, "Output:\n\n#{dump_streams(command, read_streams)}"
158
+ end
159
+
160
+ def with_timing
161
+ @times = []
162
+ yield
163
+ ensure
164
+ @times = nil
165
+ end
166
+
167
+ def last_time
168
+ @times.last
169
+ end
170
+
171
+ def first_time
172
+ @times.first
173
+ end
174
+
175
+ def timing_ratio
176
+ last_time / first_time
177
+ end
178
+
179
+ def read_streams
180
+ {
181
+ stdout: read_stream(stdout.first),
182
+ stderr: read_stream(stderr.first),
183
+ log: read_stream(log_file)
184
+ }
185
+ end
186
+
187
+ def read_stream(stream)
188
+ output = ""
189
+ while IO.select([stream], [], [], 0.5) && !stream.eof?
190
+ output << stream.readpartial(10240)
191
+ end
192
+ output
193
+ end
194
+
195
+ def dump_streams(command, streams)
196
+ output = "$ #{command}\n"
197
+
198
+ streams.each do |name, stream|
199
+ unless stream.chomp.empty?
200
+ output << "--- #{name} ---\n"
201
+ output << "#{stream.chomp}\n"
202
+ end
203
+ end
204
+
205
+ output << "\n"
206
+ output
207
+ end
208
+
209
+ def debug(artifacts)
210
+ artifacts = artifacts.dup
211
+ artifacts.delete :status
212
+ dump_streams(artifacts.delete(:command), artifacts)
213
+ end
214
+
215
+ def await_reload
216
+ raise "no pid" if @application_pids.nil? || @application_pids.empty?
217
+
218
+ Timeout.timeout(DEFAULT_TIMEOUT) do
219
+ sleep 0.1 while @application_pids.any? { |p| process_alive?(p) }
220
+ end
221
+ end
222
+
223
+ def run!(*args)
224
+ artifacts = run(*args)
225
+ unless artifacts[:status].success?
226
+ raise "command failed\n\n#{debug(artifacts)}"
227
+ end
228
+ artifacts
229
+ end
230
+
231
+ def bundle
232
+ run! "(gem list bundler | grep bundler) || gem install bundler", timeout: nil
233
+ run! "bundle update", timeout: nil
234
+ end
235
+
236
+ private
237
+
238
+ def process_alive?(pid)
239
+ Process.kill 0, pid
240
+ true
241
+ rescue Errno::ESRCH
242
+ false
243
+ end
244
+ end
245
+
246
+ class ApplicationGenerator
247
+ attr_reader :version_constraint, :version, :application
248
+
249
+ def initialize(version_constraint)
250
+ @version_constraint = version_constraint
251
+ @version = RailsVersion.new(version_constraint.split(' ').last)
252
+ @application = Application.new(root)
253
+ @bundled = false
254
+ end
255
+
256
+ def root
257
+ "#{TEST_ROOT}/apps/rails-#{version.major}-#{version.minor}-spring-#{Spring::VERSION}"
258
+ end
259
+
260
+ def system(command)
261
+ Kernel.system("#{command} > /dev/null") or raise "command failed: #{command}"
262
+ end
263
+
264
+ def bundle
265
+ return if @bundled
266
+ application.bundle
267
+ @bundled = true
268
+ end
269
+
270
+ # Sporadic SSL errors keep causing test failures so there are anti-SSL workarounds here
271
+ def generate
272
+ Bundler.with_clean_env do
273
+ system("(gem list rails --installed --version '#{version_constraint}' || " \
274
+ "gem install rails --clear-sources --source http://rubygems.org --version '#{version_constraint}')")
275
+
276
+ skips = %w(--skip-bundle --skip-javascript --skip-sprockets)
277
+ skips << "--skip-spring" if version.bundles_spring?
278
+
279
+ system("rails '_#{version_constraint}_' new #{application.root} #{skips.join(' ')}")
280
+
281
+ FileUtils.mkdir_p(application.gem_home)
282
+ FileUtils.mkdir_p(application.user_home)
283
+ FileUtils.rm_rf(application.path("test/performance"))
284
+
285
+ File.write(application.gemfile, "#{application.gemfile.read}gem 'spring', '#{Spring::VERSION}'\n")
286
+
287
+ if version.needs_testunit?
288
+ File.write(application.gemfile, "#{application.gemfile.read}gem 'spring-commands-testunit'\n")
289
+ end
290
+
291
+ File.write(application.gemfile, application.gemfile.read.sub("https://rubygems.org", "http://rubygems.org"))
292
+
293
+ if application.path("bin").exist?
294
+ FileUtils.cp_r(application.path("bin"), application.path("bin_original"))
295
+ end
296
+ end
297
+
298
+ bundle
299
+ application.run! "bundle exec rails g scaffold post title:string"
300
+ application.run! "bundle exec rake db:migrate db:test:clone"
301
+ end
302
+
303
+ def generate_if_missing
304
+ generate unless application.exists?
305
+ end
306
+
307
+ def install_spring
308
+ unless @installed
309
+ # Need to do this here too because the app may have been generated with
310
+ # a different ruby
311
+ bundle
312
+
313
+ system("gem build spring.gemspec 2>/dev/null")
314
+ application.run! "gem install ../../../spring-#{Spring::VERSION}.gem", timeout: nil
315
+
316
+ FileUtils.rm_rf application.path("bin")
317
+
318
+ if application.path("bin_original").exist?
319
+ FileUtils.cp_r application.path("bin_original"), application.path("bin")
320
+ end
321
+
322
+ application.run! "#{application.spring} binstub --all"
323
+ @installed = true
324
+ end
325
+ end
326
+
327
+ def copy_to(path)
328
+ FileUtils.rm_rf(path.to_s)
329
+ FileUtils.cp_r(application.root.to_s, path.to_s)
330
+ end
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+ require 'spring/client'
3
+
4
+ class VersionTest < ActiveSupport::TestCase
5
+ test "outputs current version number" do
6
+ version = Spring::Client::Version.new 'version'
7
+
8
+ out, err = capture_io do
9
+ version.call
10
+ end
11
+
12
+ assert_equal "Spring version #{Spring::VERSION}", out.chomp
13
+ end
14
+ end
@@ -1,6 +1,7 @@
1
1
  require "helper"
2
2
  require "tmpdir"
3
3
  require "fileutils"
4
+ require "timeout"
4
5
  require "active_support/core_ext/numeric/time"
5
6
  require "spring/watcher"
6
7
  require "spring/watcher/polling"
@@ -120,22 +121,25 @@ module WatcherTests
120
121
  assert_stale
121
122
  end
122
123
 
123
- def test_can_io_select
124
+ def test_on_stale
124
125
  file = "#{@dir}/omg"
125
126
  touch file, Time.now - 2.seconds
126
127
 
127
128
  watcher.add file
128
129
  watcher.start
129
130
 
130
- io = watcher.to_io
131
+ stale = false
132
+ watcher.on_stale { stale = true }
131
133
 
132
- Thread.new {
133
- sleep LATENCY * 3
134
- touch file, Time.now
135
- }
134
+ touch file, Time.now
136
135
 
137
- assert IO.select([io], [], [], 1), "IO.select timed out before watcher was readable"
138
- assert watcher.stale?
136
+ Timeout.timeout(1) { sleep 0.01 until stale }
137
+ assert stale
138
+
139
+ # Check that we only get notified once
140
+ stale = false
141
+ sleep LATENCY * 3
142
+ assert !stale
139
143
  end
140
144
 
141
145
  def test_add_relative_path
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Leighton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-19 00:00:00.000000000 Z
11
+ date: 2014-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -55,7 +55,10 @@ files:
55
55
  - Rakefile
56
56
  - bin/spring
57
57
  - lib/spring/application.rb
58
+ - lib/spring/application/boot.rb
58
59
  - lib/spring/application_manager.rb
60
+ - lib/spring/binstub.rb
61
+ - lib/spring/boot.rb
59
62
  - lib/spring/client.rb
60
63
  - lib/spring/client/binstub.rb
61
64
  - lib/spring/client/command.rb
@@ -64,6 +67,8 @@ files:
64
67
  - lib/spring/client/run.rb
65
68
  - lib/spring/client/status.rb
66
69
  - lib/spring/client/stop.rb
70
+ - lib/spring/client/version.rb
71
+ - lib/spring/command_wrapper.rb
67
72
  - lib/spring/commands.rb
68
73
  - lib/spring/commands/rails.rb
69
74
  - lib/spring/commands/rake.rb
@@ -81,13 +86,15 @@ files:
81
86
  - lib/spring/watcher/polling.rb
82
87
  - spring.gemspec
83
88
  - test/acceptance/app_test.rb
89
+ - test/acceptance/helper.rb
84
90
  - test/apps/.gitignore
85
91
  - test/helper.rb
86
92
  - test/unit/client/help_test.rb
93
+ - test/unit/client/version_test.rb
87
94
  - test/unit/commands_test.rb
88
95
  - test/unit/process_title_updater_test.rb
89
96
  - test/unit/watcher_test.rb
90
- homepage: http://github.com/jonleighton/spring
97
+ homepage: http://github.com/rails/spring
91
98
  licenses:
92
99
  - MIT
93
100
  metadata: {}
@@ -102,9 +109,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
109
  version: '0'
103
110
  required_rubygems_version: !ruby/object:Gem::Requirement
104
111
  requirements:
105
- - - '>='
112
+ - - '>'
106
113
  - !ruby/object:Gem::Version
107
- version: '0'
114
+ version: 1.3.1
108
115
  requirements: []
109
116
  rubyforge_project:
110
117
  rubygems_version: 2.1.9
@@ -113,9 +120,12 @@ specification_version: 4
113
120
  summary: Rails application preloader
114
121
  test_files:
115
122
  - test/acceptance/app_test.rb
123
+ - test/acceptance/helper.rb
116
124
  - test/apps/.gitignore
117
125
  - test/helper.rb
118
126
  - test/unit/client/help_test.rb
127
+ - test/unit/client/version_test.rb
119
128
  - test/unit/commands_test.rb
120
129
  - test/unit/process_title_updater_test.rb
121
130
  - test/unit/watcher_test.rb
131
+ has_rdoc: