spring 1.6.4 → 1.7.1
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/README.md +40 -4
- data/lib/spring/application.rb +21 -4
- data/lib/spring/application/boot.rb +2 -1
- data/lib/spring/application_manager.rb +4 -3
- data/lib/spring/client.rb +2 -0
- data/lib/spring/client/run.rb +61 -38
- data/lib/spring/client/server.rb +18 -0
- data/lib/spring/env.rb +15 -8
- data/lib/spring/server.rb +27 -7
- data/lib/spring/test/acceptance_test.rb +31 -5
- data/lib/spring/test/application.rb +6 -2
- data/lib/spring/test/application_generator.rb +4 -0
- data/lib/spring/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d14dc08475fd37c9118d173aea5ec37900657430
|
4
|
+
data.tar.gz: d6fbda6c06dfe77c7bdaa27f6a5cc45019ca5266
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb7c61300a47f81d7ca46c5bf6bb50f679c665bb076b7d05fcacf923d8dc06a8b03b85313ea3f1f465e83fedb4f9ff38641270f9185439156261b03232a58201
|
7
|
+
data.tar.gz: e5bf9351f6bd9af0150cd0cdba8a04b556445a5cf485e69d89d2b6c3007cd91800a9f19c45732cae1e315805153cbab18911f6191d3c7508efc74c516170ad55
|
data/README.md
CHANGED
@@ -290,6 +290,13 @@ false
|
|
290
290
|
So to avoid this problem, don't save off references to application
|
291
291
|
constants in your initialization code.
|
292
292
|
|
293
|
+
## Using Spring with a containerized development environment
|
294
|
+
|
295
|
+
As of Spring 1.7, there is some support for doing this. See [this
|
296
|
+
example
|
297
|
+
repository](https://github.com/jonleighton/spring-docker-example) for
|
298
|
+
information about how to do it with [Docker](https://www.docker.com/).
|
299
|
+
|
293
300
|
## Configuration
|
294
301
|
|
295
302
|
Spring will read `~/.spring.rb` and `config/spring.rb` for custom
|
@@ -365,13 +372,42 @@ a command runs:
|
|
365
372
|
Spring.quiet = true
|
366
373
|
```
|
367
374
|
|
375
|
+
### Environment variables
|
376
|
+
|
377
|
+
The following environment variables are used by Spring:
|
378
|
+
|
379
|
+
* `DISABLE_SPRING` - If set, Spring will be bypassed and your
|
380
|
+
application will boot in a foreground process
|
381
|
+
* `SPRING_LOG` - The path to a file which Spring will write log messages
|
382
|
+
to.
|
383
|
+
* `SPRING_TMP_PATH` - The directory where Spring should write its temporary
|
384
|
+
files (a pidfile and a socket). By default we use the
|
385
|
+
`XDG_RUNTIME_DIR` environment variable, or else `Dir.tmpdir`, and then
|
386
|
+
create a directory in that named `spring-$UID`. We don't use your
|
387
|
+
Rails application's `tmp/` directory because that may be on a
|
388
|
+
filesystem which doesn't support UNIX sockets.
|
389
|
+
* `SPRING_APPLICATION_ID` - Used to identify distinct Rails
|
390
|
+
applications. By default it is an MD5 hash of the current
|
391
|
+
`RUBY_VERSION`, and the path to your Rails project root.
|
392
|
+
* `SPRING_SOCKET` - The path which should be used for the UNIX socket
|
393
|
+
which Spring uses to communicate with the long-running Spring server
|
394
|
+
process. By default this is `SPRING_TMP_PATH/SPRING_APPLICATION_ID`.
|
395
|
+
* `SPRING_PIDFILE` - The path which should be used to store the pid of
|
396
|
+
the long-running Spring server process. By default this is related to
|
397
|
+
the socket path; if the socket path is `/foo/bar/spring.sock` the
|
398
|
+
pidfile will be `/foo/bar/spring.pid`.
|
399
|
+
* `SPRING_SERVER_COMMAND` - The command to run to start up the spring
|
400
|
+
server when it is not already running. Defaults to `spring _[version]_
|
401
|
+
server --background`.
|
402
|
+
|
368
403
|
## Troubleshooting
|
369
404
|
|
370
405
|
If you want to get more information about what spring is doing, you can
|
371
|
-
|
406
|
+
run spring explicitly in a separate terminal:
|
372
407
|
|
373
408
|
```
|
374
|
-
|
375
|
-
export SPRING_LOG=/tmp/spring.log
|
376
|
-
spring rake -T
|
409
|
+
$ spring server
|
377
410
|
```
|
411
|
+
|
412
|
+
Logging output will be printed to stdout. You can also send log output
|
413
|
+
to a file with the `SPRING_LOG` environment variable.
|
data/lib/spring/application.rb
CHANGED
@@ -6,10 +6,10 @@ module Spring
|
|
6
6
|
class Application
|
7
7
|
attr_reader :manager, :watcher, :spring_env, :original_env
|
8
8
|
|
9
|
-
def initialize(manager, original_env)
|
9
|
+
def initialize(manager, original_env, spring_env = Env.new)
|
10
10
|
@manager = manager
|
11
11
|
@original_env = original_env
|
12
|
-
@spring_env =
|
12
|
+
@spring_env = spring_env
|
13
13
|
@mutex = Mutex.new
|
14
14
|
@waiting = Set.new
|
15
15
|
@preloaded = false
|
@@ -149,11 +149,17 @@ module Spring
|
|
149
149
|
setup command
|
150
150
|
|
151
151
|
if Rails.application.reloaders.any?(&:updated?)
|
152
|
-
|
153
|
-
|
152
|
+
# Rails 5.1 forward-compat. AD::R is deprecated to AS::R in Rails 5.
|
153
|
+
if defined? ActiveSupport::Reloader
|
154
|
+
Rails.application.reloader.reload!
|
155
|
+
else
|
156
|
+
ActionDispatch::Reloader.cleanup!
|
157
|
+
ActionDispatch::Reloader.prepare!
|
158
|
+
end
|
154
159
|
end
|
155
160
|
|
156
161
|
pid = fork {
|
162
|
+
Process.setsid
|
157
163
|
IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
|
158
164
|
trap("TERM", "DEFAULT")
|
159
165
|
|
@@ -313,6 +319,17 @@ module Spring
|
|
313
319
|
exit_if_finished
|
314
320
|
end
|
315
321
|
}
|
322
|
+
|
323
|
+
Thread.new {
|
324
|
+
while signal = client.gets.chomp
|
325
|
+
begin
|
326
|
+
Process.kill(signal, -Process.getpgid(pid))
|
327
|
+
client.puts(0)
|
328
|
+
rescue Errno::ESRCH
|
329
|
+
client.puts(1)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
}
|
316
333
|
end
|
317
334
|
|
318
335
|
private
|
@@ -5,7 +5,8 @@ require "spring/application"
|
|
5
5
|
|
6
6
|
app = Spring::Application.new(
|
7
7
|
UNIXSocket.for_fd(3),
|
8
|
-
Spring::JSON.load(ENV.delete("SPRING_ORIGINAL_ENV").dup)
|
8
|
+
Spring::JSON.load(ENV.delete("SPRING_ORIGINAL_ENV").dup),
|
9
|
+
Spring::Env.new(log_file: IO.for_fd(4))
|
9
10
|
)
|
10
11
|
|
11
12
|
Signal.trap("TERM") { app.terminate }
|
@@ -2,9 +2,9 @@ module Spring
|
|
2
2
|
class ApplicationManager
|
3
3
|
attr_reader :pid, :child, :app_env, :spring_env, :status
|
4
4
|
|
5
|
-
def initialize(app_env)
|
5
|
+
def initialize(app_env, spring_env)
|
6
6
|
@app_env = app_env
|
7
|
-
@spring_env =
|
7
|
+
@spring_env = spring_env
|
8
8
|
@mutex = Mutex.new
|
9
9
|
@state = :running
|
10
10
|
end
|
@@ -104,7 +104,8 @@ module Spring
|
|
104
104
|
"-I", File.expand_path("../..", $LOADED_FEATURES.grep(/bundler\/setup\.rb$/).first),
|
105
105
|
"-I", File.expand_path("../..", __FILE__),
|
106
106
|
"-e", "require 'spring/application/boot'",
|
107
|
-
3 => child_socket
|
107
|
+
3 => child_socket,
|
108
|
+
4 => spring_env.log_file,
|
108
109
|
)
|
109
110
|
end
|
110
111
|
|
data/lib/spring/client.rb
CHANGED
@@ -9,6 +9,7 @@ require "spring/client/stop"
|
|
9
9
|
require "spring/client/status"
|
10
10
|
require "spring/client/rails"
|
11
11
|
require "spring/client/version"
|
12
|
+
require "spring/client/server"
|
12
13
|
|
13
14
|
module Spring
|
14
15
|
module Client
|
@@ -22,6 +23,7 @@ module Spring
|
|
22
23
|
"rails" => Client::Rails,
|
23
24
|
"-v" => Client::Version,
|
24
25
|
"--version" => Client::Version,
|
26
|
+
"server" => Client::Server,
|
25
27
|
}
|
26
28
|
|
27
29
|
def self.run(args)
|
data/lib/spring/client/run.rb
CHANGED
@@ -6,31 +6,36 @@ module Spring
|
|
6
6
|
module Client
|
7
7
|
class Run < Command
|
8
8
|
FORWARDED_SIGNALS = %w(INT QUIT USR1 USR2 INFO WINCH) & Signal.list.keys
|
9
|
-
|
9
|
+
CONNECT_TIMEOUT = 1
|
10
|
+
BOOT_TIMEOUT = 10
|
11
|
+
|
12
|
+
attr_reader :server
|
10
13
|
|
11
14
|
def initialize(args)
|
12
15
|
super
|
13
|
-
|
16
|
+
|
17
|
+
@signal_queue = []
|
18
|
+
@server_booted = false
|
14
19
|
end
|
15
20
|
|
16
21
|
def log(message)
|
17
22
|
env.log "[client] #{message}"
|
18
23
|
end
|
19
24
|
|
20
|
-
def
|
21
|
-
@server
|
25
|
+
def connect
|
26
|
+
@server = UNIXSocket.open(env.socket_name)
|
22
27
|
end
|
23
28
|
|
24
29
|
def call
|
25
|
-
|
26
|
-
|
27
|
-
|
30
|
+
begin
|
31
|
+
connect
|
32
|
+
rescue Errno::ENOENT, Errno::ECONNRESET, Errno::ECONNREFUSED
|
28
33
|
cold_run
|
34
|
+
else
|
35
|
+
warm_run
|
29
36
|
end
|
30
|
-
rescue Errno::ECONNRESET
|
31
|
-
exit 1
|
32
37
|
ensure
|
33
|
-
server.close if
|
38
|
+
server.close if server
|
34
39
|
end
|
35
40
|
|
36
41
|
def warm_run
|
@@ -49,6 +54,7 @@ module Spring
|
|
49
54
|
|
50
55
|
def cold_run
|
51
56
|
boot_server
|
57
|
+
connect
|
52
58
|
run
|
53
59
|
end
|
54
60
|
|
@@ -60,24 +66,37 @@ module Spring
|
|
60
66
|
queue_signals
|
61
67
|
connect_to_application(client)
|
62
68
|
run_command(client, application)
|
69
|
+
rescue Errno::ECONNRESET
|
70
|
+
exit 1
|
63
71
|
end
|
64
72
|
|
65
73
|
def boot_server
|
66
74
|
env.socket_path.unlink if env.socket_path.exist?
|
67
75
|
|
68
|
-
pid
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
)
|
76
|
+
pid = Process.spawn(gem_env, env.server_command, out: File::NULL)
|
77
|
+
timeout = Time.now + BOOT_TIMEOUT
|
78
|
+
|
79
|
+
@server_booted = true
|
73
80
|
|
74
81
|
until env.socket_path.exist?
|
75
82
|
_, status = Process.waitpid2(pid, Process::WNOHANG)
|
76
|
-
|
83
|
+
|
84
|
+
if status
|
85
|
+
exit status.exitstatus
|
86
|
+
elsif Time.now > timeout
|
87
|
+
$stderr.puts "Starting Spring server with `#{env.server_command}` " \
|
88
|
+
"timed out after #{BOOT_TIMEOUT} seconds"
|
89
|
+
exit 1
|
90
|
+
end
|
91
|
+
|
77
92
|
sleep 0.1
|
78
93
|
end
|
79
94
|
end
|
80
95
|
|
96
|
+
def server_booted?
|
97
|
+
@server_booted
|
98
|
+
end
|
99
|
+
|
81
100
|
def gem_env
|
82
101
|
bundle = Bundler.bundle_path.to_s
|
83
102
|
paths = Gem.path + ENV["GEM_PATH"].to_s.split(File::PATH_SEPARATOR)
|
@@ -97,13 +116,17 @@ module Spring
|
|
97
116
|
def verify_server_version
|
98
117
|
server_version = server.gets.chomp
|
99
118
|
if server_version != env.version
|
100
|
-
$stderr.puts
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
119
|
+
$stderr.puts "There is a version mismatch between the spring client " \
|
120
|
+
"(#{env.version}) and the server (#{server_version})."
|
121
|
+
|
122
|
+
if server_booted?
|
123
|
+
$stderr.puts "We already tried to reboot the server, but the mismatch is still present."
|
124
|
+
exit 1
|
125
|
+
else
|
126
|
+
$stderr.puts "Restarting to resolve."
|
127
|
+
stop_server
|
128
|
+
cold_run
|
129
|
+
end
|
107
130
|
end
|
108
131
|
end
|
109
132
|
|
@@ -111,7 +134,7 @@ ERROR
|
|
111
134
|
server.send_io client
|
112
135
|
send_json server, "args" => args, "default_rails_env" => default_rails_env
|
113
136
|
|
114
|
-
if IO.select([server], [], [],
|
137
|
+
if IO.select([server], [], [], CONNECT_TIMEOUT)
|
115
138
|
server.gets or raise CommandNotFound
|
116
139
|
else
|
117
140
|
raise "Error connecting to Spring server"
|
@@ -138,7 +161,7 @@ ERROR
|
|
138
161
|
if pid && !pid.empty?
|
139
162
|
log "got pid: #{pid}"
|
140
163
|
|
141
|
-
forward_signals(
|
164
|
+
forward_signals(application)
|
142
165
|
status = application.read.to_i
|
143
166
|
|
144
167
|
log "got exit status #{status}"
|
@@ -158,26 +181,26 @@ ERROR
|
|
158
181
|
end
|
159
182
|
end
|
160
183
|
|
161
|
-
def forward_signals(
|
162
|
-
@signal_queue.each { |sig| kill sig,
|
184
|
+
def forward_signals(application)
|
185
|
+
@signal_queue.each { |sig| kill sig, application }
|
163
186
|
|
164
187
|
FORWARDED_SIGNALS.each do |sig|
|
165
|
-
trap(sig) { forward_signal sig,
|
188
|
+
trap(sig) { forward_signal sig, application }
|
166
189
|
end
|
167
|
-
rescue Errno::ESRCH
|
168
190
|
end
|
169
191
|
|
170
|
-
def forward_signal(sig,
|
171
|
-
kill(sig,
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
192
|
+
def forward_signal(sig, application)
|
193
|
+
if kill(sig, application) != 0
|
194
|
+
# If the application process is gone, then don't block the
|
195
|
+
# signal on this process.
|
196
|
+
trap(sig, 'DEFAULT')
|
197
|
+
Process.kill(sig, Process.pid)
|
198
|
+
end
|
177
199
|
end
|
178
200
|
|
179
|
-
def kill(sig,
|
180
|
-
|
201
|
+
def kill(sig, application)
|
202
|
+
application.puts(sig)
|
203
|
+
application.gets.to_i
|
181
204
|
end
|
182
205
|
|
183
206
|
def send_json(socket, data)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Spring
|
2
|
+
module Client
|
3
|
+
class Server < Command
|
4
|
+
def self.description
|
5
|
+
"Explicitly start a Spring server in the foreground"
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
require "spring/server"
|
10
|
+
Spring::Server.boot(foreground: foreground?)
|
11
|
+
end
|
12
|
+
|
13
|
+
def foreground?
|
14
|
+
!args.include?("--background")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/spring/env.rb
CHANGED
@@ -14,10 +14,10 @@ module Spring
|
|
14
14
|
class Env
|
15
15
|
attr_reader :log_file
|
16
16
|
|
17
|
-
def initialize(
|
18
|
-
@root = root
|
19
|
-
@project_root = root
|
20
|
-
@log_file = File.open(ENV["SPRING_LOG"] || File::NULL, "a")
|
17
|
+
def initialize(options = {})
|
18
|
+
@root = options[:root]
|
19
|
+
@project_root = options[:root]
|
20
|
+
@log_file = options[:log_file] || File.open(ENV["SPRING_LOG"] || File::NULL, "a")
|
21
21
|
end
|
22
22
|
|
23
23
|
def root
|
@@ -33,17 +33,20 @@ module Spring
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def tmp_path
|
36
|
-
path = Pathname.new(
|
36
|
+
path = Pathname.new(
|
37
|
+
ENV["SPRING_TMP_PATH"] ||
|
38
|
+
File.join(ENV['XDG_RUNTIME_DIR'] || Dir.tmpdir, "spring-#{Process.uid}")
|
39
|
+
)
|
37
40
|
FileUtils.mkdir_p(path) unless path.exist?
|
38
41
|
path
|
39
42
|
end
|
40
43
|
|
41
44
|
def application_id
|
42
|
-
Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)
|
45
|
+
ENV["SPRING_APPLICATION_ID"] || Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)
|
43
46
|
end
|
44
47
|
|
45
48
|
def socket_path
|
46
|
-
tmp_path.join(application_id)
|
49
|
+
Pathname.new(ENV["SPRING_SOCKET"] || tmp_path.join(application_id))
|
47
50
|
end
|
48
51
|
|
49
52
|
def socket_name
|
@@ -51,7 +54,7 @@ module Spring
|
|
51
54
|
end
|
52
55
|
|
53
56
|
def pidfile_path
|
54
|
-
|
57
|
+
Pathname.new(ENV["SPRING_PIDFILE"] || socket_path.dirname.join("#{socket_path.basename(".*")}.pid"))
|
55
58
|
end
|
56
59
|
|
57
60
|
def pid
|
@@ -105,5 +108,9 @@ module Spring
|
|
105
108
|
rescue Errno::ESRCH
|
106
109
|
# already dead
|
107
110
|
end
|
111
|
+
|
112
|
+
def server_command
|
113
|
+
ENV["SPRING_SERVER_COMMAND"] || "#{File.expand_path("../../../bin/spring", __FILE__)} server --background"
|
114
|
+
end
|
108
115
|
end
|
109
116
|
end
|
data/lib/spring/server.rb
CHANGED
@@ -10,19 +10,24 @@ require "spring/commands"
|
|
10
10
|
|
11
11
|
module Spring
|
12
12
|
class Server
|
13
|
-
def self.boot
|
14
|
-
new.boot
|
13
|
+
def self.boot(options = {})
|
14
|
+
new(options).boot
|
15
15
|
end
|
16
16
|
|
17
17
|
attr_reader :env
|
18
18
|
|
19
|
-
def initialize(
|
20
|
-
@
|
21
|
-
@
|
19
|
+
def initialize(options = {})
|
20
|
+
@foreground = options.fetch(:foreground, false)
|
21
|
+
@env = options[:env] || default_env
|
22
|
+
@applications = Hash.new { |h, k| h[k] = ApplicationManager.new(k, env) }
|
22
23
|
@pidfile = env.pidfile_path.open('a')
|
23
24
|
@mutex = Mutex.new
|
24
25
|
end
|
25
26
|
|
27
|
+
def foreground?
|
28
|
+
@foreground
|
29
|
+
end
|
30
|
+
|
26
31
|
def log(message)
|
27
32
|
env.log "[server] #{message}"
|
28
33
|
end
|
@@ -31,8 +36,8 @@ module Spring
|
|
31
36
|
Spring.verify_environment
|
32
37
|
|
33
38
|
write_pidfile
|
34
|
-
set_pgid
|
35
|
-
ignore_signals
|
39
|
+
set_pgid unless foreground?
|
40
|
+
ignore_signals unless foreground?
|
36
41
|
set_exit_hook
|
37
42
|
set_process_title
|
38
43
|
start_server
|
@@ -42,6 +47,7 @@ module Spring
|
|
42
47
|
server = UNIXServer.open(env.socket_name)
|
43
48
|
log "started on #{env.socket_name}"
|
44
49
|
loop { serve server.accept }
|
50
|
+
rescue Interrupt
|
45
51
|
end
|
46
52
|
|
47
53
|
def serve(client)
|
@@ -126,5 +132,19 @@ module Spring
|
|
126
132
|
"spring server | #{env.app_name} | started #{distance} ago"
|
127
133
|
}
|
128
134
|
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def default_env
|
139
|
+
Env.new(log_file: default_log_file)
|
140
|
+
end
|
141
|
+
|
142
|
+
def default_log_file
|
143
|
+
if foreground? && !ENV["SPRING_LOG"]
|
144
|
+
$stdout
|
145
|
+
else
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
end
|
129
149
|
end
|
130
150
|
end
|
@@ -28,6 +28,10 @@ module Spring
|
|
28
28
|
@app ||= Spring::Test::Application.new("#{Spring::Test.root}/apps/tmp")
|
29
29
|
end
|
30
30
|
|
31
|
+
def spring_env
|
32
|
+
app.spring_env
|
33
|
+
end
|
34
|
+
|
31
35
|
def assert_output(artifacts, expected)
|
32
36
|
expected.each do |stream, output|
|
33
37
|
assert artifacts[stream].include?(output),
|
@@ -92,14 +96,14 @@ module Spring
|
|
92
96
|
|
93
97
|
test "help message when called without arguments" do
|
94
98
|
assert_success "bin/spring", stdout: 'Usage: spring COMMAND [ARGS]'
|
95
|
-
assert
|
99
|
+
assert spring_env.server_running?
|
96
100
|
end
|
97
101
|
|
98
102
|
test "shows help" do
|
99
103
|
assert_success "bin/spring help", stdout: 'Usage: spring COMMAND [ARGS]'
|
100
104
|
assert_success "bin/spring -h", stdout: 'Usage: spring COMMAND [ARGS]'
|
101
105
|
assert_success "bin/spring --help", stdout: 'Usage: spring COMMAND [ARGS]'
|
102
|
-
refute
|
106
|
+
refute spring_env.server_running?
|
103
107
|
end
|
104
108
|
|
105
109
|
test "tells the user that spring is being used when used automatically via binstubs" do
|
@@ -184,10 +188,10 @@ module Spring
|
|
184
188
|
|
185
189
|
test "stop command kills server" do
|
186
190
|
app.run app.spring_test_command
|
187
|
-
assert
|
191
|
+
assert spring_env.server_running?, "The server should be running but it isn't"
|
188
192
|
|
189
193
|
assert_success "bin/spring stop"
|
190
|
-
assert !
|
194
|
+
assert !spring_env.server_running?, "The server should not be running but it is"
|
191
195
|
end
|
192
196
|
|
193
197
|
test "custom commands" do
|
@@ -400,7 +404,7 @@ module Spring
|
|
400
404
|
end
|
401
405
|
|
402
406
|
test "can define client tasks" do
|
403
|
-
File.write("#{app.
|
407
|
+
File.write("#{app.spring_client_config}", <<-RUBY)
|
404
408
|
Spring::Client::COMMANDS["foo"] = lambda { |args| puts "bar -- \#{args.inspect}" }
|
405
409
|
RUBY
|
406
410
|
assert_success "bin/spring foo --baz", stdout: "bar -- [\"foo\", \"--baz\"]\n"
|
@@ -508,6 +512,28 @@ module Spring
|
|
508
512
|
2.times { assert_success "bundle exec rails runner ''" }
|
509
513
|
end
|
510
514
|
end
|
515
|
+
|
516
|
+
test "booting a foreground server" do
|
517
|
+
FileUtils.cd(app.root) do
|
518
|
+
assert !spring_env.server_running?
|
519
|
+
app.run "spring server &"
|
520
|
+
|
521
|
+
Timeout.timeout(1) do
|
522
|
+
sleep 0.1 until spring_env.server_running?
|
523
|
+
end
|
524
|
+
|
525
|
+
assert_success app.spring_test_command
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
test "server boot timeout" do
|
530
|
+
app.env["SPRING_SERVER_COMMAND"] = "sleep 1"
|
531
|
+
File.write("#{app.spring_client_config}", %(
|
532
|
+
Spring::Client::Run.const_set(:BOOT_TIMEOUT, 0.1)
|
533
|
+
))
|
534
|
+
|
535
|
+
assert_failure "bin/rails runner ''", stderr: "timed out"
|
536
|
+
end
|
511
537
|
end
|
512
538
|
end
|
513
539
|
end
|
@@ -9,7 +9,7 @@ module Spring
|
|
9
9
|
|
10
10
|
def initialize(root)
|
11
11
|
@root = Pathname.new(root)
|
12
|
-
@spring_env = Spring::Env.new(root)
|
12
|
+
@spring_env = Spring::Env.new(root: root)
|
13
13
|
end
|
14
14
|
|
15
15
|
def exists?
|
@@ -88,6 +88,10 @@ module Spring
|
|
88
88
|
path "config/spring.rb"
|
89
89
|
end
|
90
90
|
|
91
|
+
def spring_client_config
|
92
|
+
path "config/spring_client.rb"
|
93
|
+
end
|
94
|
+
|
91
95
|
def run(command, opts = {})
|
92
96
|
start_time = Time.now
|
93
97
|
|
@@ -117,7 +121,7 @@ module Spring
|
|
117
121
|
|
118
122
|
output.merge(status: status, command: command)
|
119
123
|
rescue Timeout::Error => e
|
120
|
-
raise
|
124
|
+
raise Timeout::Error, "While running command:\n\n#{dump_streams(command, read_streams)}"
|
121
125
|
end
|
122
126
|
|
123
127
|
def with_timing
|
@@ -58,6 +58,10 @@ module Spring
|
|
58
58
|
append_to_file(application.gemfile, "gem 'spring-commands-testunit'")
|
59
59
|
end
|
60
60
|
|
61
|
+
if RUBY_VERSION == "1.9.3"
|
62
|
+
append_to_file(application.gemfile, "gem 'mime-types', '~> 2'")
|
63
|
+
end
|
64
|
+
|
61
65
|
rewrite_file(application.gemfile) do |c|
|
62
66
|
c.sub!("https://rubygems.org", "http://rubygems.org")
|
63
67
|
c.gsub!(/(gem '(byebug|web-console|sdoc|jbuilder)')/, "# \\1")
|
data/lib/spring/version.rb
CHANGED
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.
|
4
|
+
version: 1.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Leighton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/spring/client/help.rb
|
76
76
|
- lib/spring/client/rails.rb
|
77
77
|
- lib/spring/client/run.rb
|
78
|
+
- lib/spring/client/server.rb
|
78
79
|
- lib/spring/client/status.rb
|
79
80
|
- lib/spring/client/stop.rb
|
80
81
|
- lib/spring/client/version.rb
|