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