spring 1.0.0 → 1.1.0.beta3

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,337 @@
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 ||= begin
66
+ tmp = path("tmp")
67
+ tmp.mkdir unless tmp.exist?
68
+ tmp.join("spring.log").open("w+")
69
+ end
70
+ end
71
+
72
+ def env
73
+ @env ||= {
74
+ "GEM_HOME" => gem_home.to_s,
75
+ "GEM_PATH" => "",
76
+ "HOME" => user_home.to_s,
77
+ "RAILS_ENV" => nil,
78
+ "RACK_ENV" => nil,
79
+ "SPRING_LOG" => log_file.path
80
+ }
81
+ end
82
+
83
+ def path(addition)
84
+ root.join addition
85
+ end
86
+
87
+ def gemfile
88
+ path "Gemfile"
89
+ end
90
+
91
+ def gem_home
92
+ path "vendor/gems/#{RUBY_VERSION}"
93
+ end
94
+
95
+ def user_home
96
+ path "user_home"
97
+ end
98
+
99
+ def spring
100
+ gem_home.join "bin/spring"
101
+ end
102
+
103
+ def rails_version
104
+ @rails_version ||= RailsVersion.new(gemfile.read.match(/gem 'rails', '(.*)'/)[1])
105
+ end
106
+
107
+ def spring_test_command
108
+ "#{rails_version.test_command} #{test}"
109
+ end
110
+
111
+ def stop_spring
112
+ run "#{spring} stop"
113
+ rescue Errno::ENOENT
114
+ end
115
+
116
+ def test
117
+ path "test/#{rails_version.controller_tests_dir}/posts_controller_test.rb"
118
+ end
119
+
120
+ def controller
121
+ path "app/controllers/posts_controller.rb"
122
+ end
123
+
124
+ def application_config
125
+ path "config/application.rb"
126
+ end
127
+
128
+ def spring_config
129
+ path "config/spring.rb"
130
+ end
131
+
132
+ def run(command, opts = {})
133
+ start_time = Time.now
134
+
135
+ Bundler.with_clean_env do
136
+ Process.spawn(
137
+ env,
138
+ command.to_s,
139
+ out: stdout.last,
140
+ err: stderr.last,
141
+ in: :close,
142
+ chdir: root.to_s,
143
+ )
144
+ end
145
+
146
+ _, status = Timeout.timeout(opts.fetch(:timeout, DEFAULT_TIMEOUT)) { Process.wait2 }
147
+
148
+ if pid = spring_env.pid
149
+ @server_pid = pid
150
+ lines = `ps -A -o ppid= -o pid= | egrep '^\\s*#{@server_pid}'`.lines
151
+ @application_pids = lines.map { |l| l.split.last.to_i }
152
+ end
153
+
154
+ output = read_streams
155
+ puts dump_streams(command, output) if ENV["SPRING_DEBUG"]
156
+
157
+ @times << (Time.now - start_time) if @times
158
+
159
+ output.merge(status: status, command: command)
160
+ rescue Timeout::Error => e
161
+ raise e, "Output:\n\n#{dump_streams(command, read_streams)}"
162
+ end
163
+
164
+ def with_timing
165
+ @times = []
166
+ yield
167
+ ensure
168
+ @times = nil
169
+ end
170
+
171
+ def last_time
172
+ @times.last
173
+ end
174
+
175
+ def first_time
176
+ @times.first
177
+ end
178
+
179
+ def timing_ratio
180
+ last_time / first_time
181
+ end
182
+
183
+ def read_streams
184
+ {
185
+ stdout: read_stream(stdout.first),
186
+ stderr: read_stream(stderr.first),
187
+ log: read_stream(log_file)
188
+ }
189
+ end
190
+
191
+ def read_stream(stream)
192
+ output = ""
193
+ while IO.select([stream], [], [], 0.5) && !stream.eof?
194
+ output << stream.readpartial(10240)
195
+ end
196
+ output
197
+ end
198
+
199
+ def dump_streams(command, streams)
200
+ output = "$ #{command}\n"
201
+
202
+ streams.each do |name, stream|
203
+ unless stream.chomp.empty?
204
+ output << "--- #{name} ---\n"
205
+ output << "#{stream.chomp}\n"
206
+ end
207
+ end
208
+
209
+ output << "\n"
210
+ output
211
+ end
212
+
213
+ def debug(artifacts)
214
+ artifacts = artifacts.dup
215
+ artifacts.delete :status
216
+ dump_streams(artifacts.delete(:command), artifacts)
217
+ end
218
+
219
+ def await_reload
220
+ raise "no pid" if @application_pids.nil? || @application_pids.empty?
221
+
222
+ Timeout.timeout(DEFAULT_TIMEOUT) do
223
+ sleep 0.1 while @application_pids.any? { |p| process_alive?(p) }
224
+ end
225
+ end
226
+
227
+ def run!(*args)
228
+ artifacts = run(*args)
229
+ unless artifacts[:status].success?
230
+ raise "command failed\n\n#{debug(artifacts)}"
231
+ end
232
+ artifacts
233
+ end
234
+
235
+ def bundle
236
+ run! "(gem list bundler | grep bundler) || gem install bundler", timeout: nil
237
+ run! "bundle update", timeout: nil
238
+ end
239
+
240
+ private
241
+
242
+ def process_alive?(pid)
243
+ Process.kill 0, pid
244
+ true
245
+ rescue Errno::ESRCH
246
+ false
247
+ end
248
+ end
249
+
250
+ class ApplicationGenerator
251
+ attr_reader :version_constraint, :version, :application
252
+
253
+ def initialize(version_constraint)
254
+ @version_constraint = version_constraint
255
+ @version = RailsVersion.new(version_constraint.split(' ').last)
256
+ @application = Application.new(root)
257
+ @bundled = false
258
+ end
259
+
260
+ def root
261
+ "#{TEST_ROOT}/apps/rails-#{version.major}-#{version.minor}-spring-#{Spring::VERSION}"
262
+ end
263
+
264
+ def system(command)
265
+ if ENV["SPRING_DEBUG"]
266
+ puts "$ #{command}\n"
267
+ else
268
+ command = "#{command} > /dev/null"
269
+ end
270
+
271
+ Kernel.system(command) or raise "command failed: #{command}"
272
+ puts if ENV["SPRING_DEBUG"]
273
+ end
274
+
275
+ # Sporadic SSL errors keep causing test failures so there are anti-SSL workarounds here
276
+ def generate
277
+ Bundler.with_clean_env do
278
+ system("(gem list rails --installed --version '#{version_constraint}' || " \
279
+ "gem install rails --clear-sources --source http://rubygems.org --version '#{version_constraint}')")
280
+
281
+ skips = %w(--skip-bundle --skip-javascript --skip-sprockets)
282
+ skips << "--skip-spring" if version.bundles_spring?
283
+
284
+ system("rails '_#{version_constraint}_' new #{application.root} #{skips.join(' ')}")
285
+
286
+ FileUtils.mkdir_p(application.gem_home)
287
+ FileUtils.mkdir_p(application.user_home)
288
+ FileUtils.rm_rf(application.path("test/performance"))
289
+
290
+ File.write(application.gemfile, "#{application.gemfile.read}gem 'spring', '#{Spring::VERSION}'\n")
291
+
292
+ if version.needs_testunit?
293
+ File.write(application.gemfile, "#{application.gemfile.read}gem 'spring-commands-testunit'\n")
294
+ end
295
+
296
+ File.write(application.gemfile, application.gemfile.read.sub("https://rubygems.org", "http://rubygems.org"))
297
+
298
+ if application.path("bin").exist?
299
+ FileUtils.cp_r(application.path("bin"), application.path("bin_original"))
300
+ end
301
+ end
302
+
303
+ install_spring
304
+
305
+ application.run! "bundle exec rails g scaffold post title:string"
306
+ application.run! "bundle exec rake db:migrate db:test:clone"
307
+ end
308
+
309
+ def generate_if_missing
310
+ generate unless application.exists?
311
+ end
312
+
313
+ def install_spring
314
+ return if @installed
315
+
316
+ system("gem build spring.gemspec 2>&1")
317
+ application.run! "gem install ../../../spring-#{Spring::VERSION}.gem", timeout: nil
318
+
319
+ application.bundle
320
+
321
+ FileUtils.rm_rf application.path("bin")
322
+
323
+ if application.path("bin_original").exist?
324
+ FileUtils.cp_r application.path("bin_original"), application.path("bin")
325
+ end
326
+
327
+ application.run! "#{application.spring} binstub --all"
328
+ @installed = true
329
+ end
330
+
331
+ def copy_to(path)
332
+ FileUtils.rm_rf(path.to_s)
333
+ FileUtils.cp_r(application.root.to_s, path.to_s)
334
+ end
335
+ end
336
+ end
337
+ 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.beta3
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-13 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: