spring 2.0.0 → 3.0.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.
- checksums.yaml +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +37 -24
- data/lib/spring/application.rb +39 -30
- data/lib/spring/application_manager.rb +4 -2
- data/lib/spring/binstub.rb +0 -20
- data/lib/spring/client/binstub.rb +13 -13
- data/lib/spring/client/help.rb +1 -1
- data/lib/spring/client/rails.rb +1 -1
- data/lib/spring/client/run.rb +16 -2
- data/lib/spring/client/stop.rb +1 -1
- data/lib/spring/commands.rb +1 -1
- data/lib/spring/configuration.rb +5 -1
- data/lib/spring/env.rb +2 -2
- data/lib/spring/errors.rb +1 -1
- data/lib/spring/process_title_updater.rb +1 -1
- data/lib/spring/version.rb +1 -1
- data/lib/spring/watcher/abstract.rb +33 -2
- data/lib/spring/watcher/polling.rb +46 -9
- metadata +13 -20
- data/lib/spring/test/acceptance_test.rb +0 -550
- data/lib/spring/test/application.rb +0 -229
- data/lib/spring/test/application_generator.rb +0 -139
- data/lib/spring/test/rails_version.rb +0 -23
- data/lib/spring/test/watcher_test.rb +0 -167
- data/lib/spring/test.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b33b73bbbedd5ed08ff1c6de6d040faaf347cfae0b6cc41c5378a834f0cefc87
|
4
|
+
data.tar.gz: 6e9c1f79634653bbf9875e6786a5e5d1df38d13d2f0b47fff129ff7a804a663c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e7c861899e73bec7b1dd623d0c486b66efdb257bc388caf10034dd11095f2feffa2695e09008d1669931f4e1c8d805c70ca7e403ea76431315f583d43664e37
|
7
|
+
data.tar.gz: 49587a245923eee35343818174edf141d2b687fb4b09cd9eeefe31c867848b03400cee41e98f2d5b35130d1b313c3f9b3433a557bfb5c5a20fc6fe4ae0822f7a
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -16,8 +16,8 @@ boot it every time you run a test, rake task or migration.
|
|
16
16
|
|
17
17
|
## Compatibility
|
18
18
|
|
19
|
-
* Ruby versions: MRI
|
20
|
-
* Rails versions:
|
19
|
+
* Ruby versions: MRI 2.5, MRI 2.6
|
20
|
+
* Rails versions: 5.2, 6.0 (Spring is installed by default when you do
|
21
21
|
`rails new` to generate your application)
|
22
22
|
|
23
23
|
Spring makes extensive use of `Process.fork`, so won't be able to
|
@@ -27,14 +27,14 @@ provide a speed up on platforms which don't support forking (Windows, JRuby).
|
|
27
27
|
|
28
28
|
### Setup
|
29
29
|
|
30
|
-
Add
|
30
|
+
Add Spring to your Gemfile:
|
31
31
|
|
32
32
|
``` ruby
|
33
33
|
gem "spring", group: :development
|
34
34
|
```
|
35
35
|
|
36
36
|
(Note: using `gem "spring", git: "..."` *won't* work and is not a
|
37
|
-
supported way of using
|
37
|
+
supported way of using Spring.)
|
38
38
|
|
39
39
|
It's recommended to 'springify' the executables in your `bin/`
|
40
40
|
directory:
|
@@ -54,17 +54,27 @@ rescue LoadError
|
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
57
|
-
On platforms where
|
58
|
-
hooks
|
57
|
+
On platforms where Spring is installed and supported, this snippet
|
58
|
+
hooks Spring into the execution of commands. In other cases, the snippet
|
59
59
|
will just be silently ignored and the lines after it will be executed as
|
60
60
|
normal.
|
61
61
|
|
62
62
|
If you don't want to prefix every command you type with `bin/`, you
|
63
|
-
can [use direnv](https://github.com/
|
63
|
+
can [use direnv](https://github.com/direnv/direnv#the-stdlib) to
|
64
64
|
automatically add `./bin` to your `PATH` when you `cd` into your application.
|
65
65
|
Simply create an `.envrc` file with the command `PATH_add bin` in your
|
66
66
|
Rails directory.
|
67
67
|
|
68
|
+
### Enable reloading
|
69
|
+
|
70
|
+
Spring reloads application code, and therefore needs the application to have
|
71
|
+
reloading enabled.
|
72
|
+
|
73
|
+
Please, make sure `config.cache_classes` is `false` in the environments that
|
74
|
+
Spring manages. That setting is typically configured in
|
75
|
+
`config/environments/*.rb`. In particular, make sure it is `false` for the
|
76
|
+
`test` environment.
|
77
|
+
|
68
78
|
### Usage
|
69
79
|
|
70
80
|
For this walkthrough I've generated a new Rails application, and run
|
@@ -90,7 +100,7 @@ user 0m0.281s
|
|
90
100
|
sys 0m0.066s
|
91
101
|
```
|
92
102
|
|
93
|
-
That wasn't particularly fast because it was the first run, so
|
103
|
+
That wasn't particularly fast because it was the first run, so Spring
|
94
104
|
had to boot the application. It's now running:
|
95
105
|
|
96
106
|
```
|
@@ -167,7 +177,7 @@ Spring is running:
|
|
167
177
|
26707 spring app | spring-demo-app | started 2 secs ago | development mode
|
168
178
|
```
|
169
179
|
|
170
|
-
There's no need to "shut down"
|
180
|
+
There's no need to "shut down" Spring. This will happen automatically
|
171
181
|
when you close your terminal. However if you do want to do a manual shut
|
172
182
|
down, use the `stop` command:
|
173
183
|
|
@@ -176,9 +186,11 @@ $ bin/spring stop
|
|
176
186
|
Spring stopped.
|
177
187
|
```
|
178
188
|
|
189
|
+
From within your code, you can check whether Spring is active with `if defined?(Spring)`.
|
190
|
+
|
179
191
|
### Removal
|
180
192
|
|
181
|
-
To remove
|
193
|
+
To remove Spring:
|
182
194
|
|
183
195
|
* 'Unspring' your bin/ executables: `bin/spring binstub --remove --all`
|
184
196
|
* Remove spring from your Gemfile
|
@@ -216,7 +228,7 @@ Spring::Commands::Rake.environment_matchers[:default] = "development"
|
|
216
228
|
### `rails console`, `rails generate`, `rails runner`
|
217
229
|
|
218
230
|
These execute the rails command you already know and love. If you run
|
219
|
-
a different sub command (e.g. `rails server`) then
|
231
|
+
a different sub command (e.g. `rails server`) then Spring will automatically
|
220
232
|
pass it through to the underlying `rails` executable (without the
|
221
233
|
speed-up).
|
222
234
|
|
@@ -230,18 +242,21 @@ You can add these to your Gemfile for additional commands:
|
|
230
242
|
* [spring-commands-testunit](https://github.com/jonleighton/spring-commands-testunit) - useful for
|
231
243
|
running `Test::Unit` tests on Rails 3, since only Rails 4 allows you
|
232
244
|
to use `rake test path/to/test` to run a particular test/directory.
|
245
|
+
* [spring-commands-parallel-tests](https://github.com/DocSpring/spring-commands-parallel-tests) - Adds the `parallel_*` commands from [`parallel_tests`](https://github.com/grosser/parallel_tests).
|
233
246
|
* [spring-commands-teaspoon](https://github.com/alejandrobabio/spring-commands-teaspoon.git)
|
234
247
|
* [spring-commands-m](https://github.com/gabrieljoelc/spring-commands-m.git)
|
235
248
|
* [spring-commands-rubocop](https://github.com/p0deje/spring-commands-rubocop)
|
249
|
+
* [spring-commands-rackup](https://github.com/wintersolutions/spring-commands-rackup)
|
250
|
+
* [spring-commands-rack-console](https://github.com/wintersolutions/spring-commands-rack-console)
|
236
251
|
|
237
252
|
## Use without adding to bundle
|
238
253
|
|
239
|
-
If you don't want
|
240
|
-
repository, it's possible to use
|
241
|
-
However, using
|
254
|
+
If you don't want Spring-related code checked into your source
|
255
|
+
repository, it's possible to use Spring without adding to your Gemfile.
|
256
|
+
However, using Spring binstubs without adding Spring to the Gemfile is not
|
242
257
|
supported.
|
243
258
|
|
244
|
-
To use
|
259
|
+
To use Spring like this, do a `gem install spring` and then prefix
|
245
260
|
commands with `spring`. For example, rather than running `bin/rake -T`,
|
246
261
|
you'd run `spring rake -T`.
|
247
262
|
|
@@ -252,12 +267,10 @@ run through Spring, set the `DISABLE_SPRING` environment variable.
|
|
252
267
|
|
253
268
|
## Class reloading
|
254
269
|
|
255
|
-
Spring uses Rails' class reloading mechanism
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
have used this mechanism with your `test` environment before, and this
|
260
|
-
can cause problems.
|
270
|
+
Spring uses Rails' class reloading mechanism to keep your code up to date
|
271
|
+
between test runs. This is the same mechanism which allows you to see changes
|
272
|
+
during development when you refresh the page. However, you may never have used
|
273
|
+
this mechanism with your `test` environment before, and this can cause problems.
|
261
274
|
|
262
275
|
It's important to realise that code reloading means that the constants
|
263
276
|
in your application are *different objects* after files have changed:
|
@@ -397,14 +410,14 @@ The following environment variables are used by Spring:
|
|
397
410
|
the long-running Spring server process. By default this is related to
|
398
411
|
the socket path; if the socket path is `/foo/bar/spring.sock` the
|
399
412
|
pidfile will be `/foo/bar/spring.pid`.
|
400
|
-
* `SPRING_SERVER_COMMAND` - The command to run to start up the
|
413
|
+
* `SPRING_SERVER_COMMAND` - The command to run to start up the Spring
|
401
414
|
server when it is not already running. Defaults to `spring _[version]_
|
402
415
|
server --background`.
|
403
416
|
|
404
417
|
## Troubleshooting
|
405
418
|
|
406
|
-
If you want to get more information about what
|
407
|
-
run
|
419
|
+
If you want to get more information about what Spring is doing, you can
|
420
|
+
run Spring explicitly in a separate terminal:
|
408
421
|
|
409
422
|
```
|
410
423
|
$ spring server
|
data/lib/spring/application.rb
CHANGED
@@ -66,7 +66,17 @@ module Spring
|
|
66
66
|
|
67
67
|
def start_watcher
|
68
68
|
@watcher = Spring.watcher
|
69
|
-
|
69
|
+
|
70
|
+
@watcher.on_stale do
|
71
|
+
state! :watcher_stale
|
72
|
+
end
|
73
|
+
|
74
|
+
if @watcher.respond_to? :on_debug
|
75
|
+
@watcher.on_debug do |message|
|
76
|
+
spring_env.log "[watcher:#{app_env}] #{message}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
70
80
|
@watcher.start
|
71
81
|
end
|
72
82
|
|
@@ -81,18 +91,20 @@ module Spring
|
|
81
91
|
|
82
92
|
require Spring.application_root_path.join("config", "application")
|
83
93
|
|
84
|
-
|
85
|
-
|
86
|
-
# override the effect of config.cache_classes = true. We can then actually
|
87
|
-
# set config.cache_classes = false after loading the environment.
|
88
|
-
Rails::Application.initializer :initialize_dependency_mechanism, group: :all do
|
89
|
-
ActiveSupport::Dependencies.mechanism = :load
|
94
|
+
unless Rails.respond_to?(:gem_version) && Rails.gem_version >= Gem::Version.new('5.2.0')
|
95
|
+
raise "Spring only supports Rails >= 5.2.0"
|
90
96
|
end
|
91
97
|
|
92
|
-
|
98
|
+
Rails::Application.initializer :ensure_reloading_is_enabled, group: :all do
|
99
|
+
if Rails.application.config.cache_classes
|
100
|
+
raise <<-MSG.strip_heredoc
|
101
|
+
Spring reloads, and therefore needs the application to have reloading enabled.
|
102
|
+
Please, set config.cache_classes to false in config/environments/#{Rails.env}.rb.
|
103
|
+
MSG
|
104
|
+
end
|
105
|
+
end
|
93
106
|
|
94
|
-
|
95
|
-
Rails.application.config.cache_classes = false
|
107
|
+
require Spring.application_root_path.join("config", "environment")
|
96
108
|
|
97
109
|
disconnect_database
|
98
110
|
|
@@ -137,7 +149,7 @@ module Spring
|
|
137
149
|
log "got client"
|
138
150
|
manager.puts
|
139
151
|
|
140
|
-
|
152
|
+
_stdout, stderr, _stdin = streams = 3.times.map { client.recv_io }
|
141
153
|
[STDOUT, STDERR, STDIN].zip(streams).each { |a, b| a.reopen(b) }
|
142
154
|
|
143
155
|
preload unless preloaded?
|
@@ -149,13 +161,7 @@ module Spring
|
|
149
161
|
setup command
|
150
162
|
|
151
163
|
if Rails.application.reloaders.any?(&:updated?)
|
152
|
-
|
153
|
-
if defined? ActiveSupport::Reloader
|
154
|
-
Rails.application.reloader.reload!
|
155
|
-
else
|
156
|
-
ActionDispatch::Reloader.cleanup!
|
157
|
-
ActionDispatch::Reloader.prepare!
|
158
|
-
end
|
164
|
+
Rails.application.reloader.reload!
|
159
165
|
end
|
160
166
|
|
161
167
|
pid = fork {
|
@@ -163,25 +169,27 @@ module Spring
|
|
163
169
|
IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
|
164
170
|
trap("TERM", "DEFAULT")
|
165
171
|
|
166
|
-
|
172
|
+
unless Spring.quiet
|
173
|
+
STDERR.puts "Running via Spring preloader in process #{Process.pid}"
|
174
|
+
|
175
|
+
if Rails.env.production?
|
176
|
+
STDERR.puts "WARNING: Spring is running in production. To fix " \
|
177
|
+
"this make sure the spring gem is only present " \
|
178
|
+
"in `development` and `test` groups in your Gemfile " \
|
179
|
+
"and make sure you always use " \
|
180
|
+
"`bundle install --without development test` in production"
|
181
|
+
end
|
182
|
+
end
|
167
183
|
|
168
184
|
ARGV.replace(args)
|
169
185
|
$0 = command.exec_name
|
170
186
|
|
171
|
-
# Delete all env vars which are unchanged from before
|
187
|
+
# Delete all env vars which are unchanged from before Spring started
|
172
188
|
original_env.each { |k, v| ENV.delete k if ENV[k] == v }
|
173
189
|
|
174
|
-
# Load in the current env vars, except those which *were* changed when
|
190
|
+
# Load in the current env vars, except those which *were* changed when Spring started
|
175
191
|
env.each { |k, v| ENV[k] ||= v }
|
176
192
|
|
177
|
-
# requiring is faster, so if config.cache_classes was true in
|
178
|
-
# the environment's config file, then we can respect that from
|
179
|
-
# here on as we no longer need constant reloading.
|
180
|
-
if @original_cache_classes
|
181
|
-
ActiveSupport::Dependencies.mechanism = :require
|
182
|
-
Rails.application.config.cache_classes = true
|
183
|
-
end
|
184
|
-
|
185
193
|
connect_database
|
186
194
|
srand
|
187
195
|
|
@@ -295,10 +303,11 @@ module Spring
|
|
295
303
|
def with_pty
|
296
304
|
PTY.open do |master, slave|
|
297
305
|
[STDOUT, STDERR, STDIN].each { |s| s.reopen slave }
|
298
|
-
|
306
|
+
reader_thread = Spring.failsafe_thread { master.read }
|
299
307
|
begin
|
300
308
|
yield
|
301
309
|
ensure
|
310
|
+
reader_thread.kill
|
302
311
|
reset_streams
|
303
312
|
end
|
304
313
|
end
|
@@ -7,6 +7,7 @@ module Spring
|
|
7
7
|
@spring_env = spring_env
|
8
8
|
@mutex = Mutex.new
|
9
9
|
@state = :running
|
10
|
+
@pid = nil
|
10
11
|
end
|
11
12
|
|
12
13
|
def log(message)
|
@@ -92,7 +93,8 @@ module Spring
|
|
92
93
|
def start_child(preload = false)
|
93
94
|
@child, child_socket = UNIXSocket.pair
|
94
95
|
|
95
|
-
Bundler.
|
96
|
+
Bundler.with_original_env do
|
97
|
+
bundler_dir = File.expand_path("../..", $LOADED_FEATURES.grep(/bundler\/setup\.rb$/).first)
|
96
98
|
@pid = Process.spawn(
|
97
99
|
{
|
98
100
|
"RAILS_ENV" => app_env,
|
@@ -101,7 +103,7 @@ module Spring
|
|
101
103
|
"SPRING_PRELOAD" => preload ? "1" : "0"
|
102
104
|
},
|
103
105
|
"ruby",
|
104
|
-
"
|
106
|
+
*(bundler_dir != RbConfig::CONFIG["rubylibdir"] ? ["-I", bundler_dir] : []),
|
105
107
|
"-I", File.expand_path("../..", __FILE__),
|
106
108
|
"-e", "require 'spring/application/boot'",
|
107
109
|
3 => child_socket,
|
data/lib/spring/binstub.rb
CHANGED
@@ -1,26 +1,6 @@
|
|
1
1
|
command = File.basename($0)
|
2
2
|
bin_path = File.expand_path("../../../bin/spring", __FILE__)
|
3
3
|
|
4
|
-
# When we run a command which does not go through Spring (e.g. DISABLE_SPRING
|
5
|
-
# is used, or we just call 'rails' or something) then we get this warning from
|
6
|
-
# Rubygems:
|
7
|
-
#
|
8
|
-
# WARN: Unresolved specs during Gem::Specification.reset: activesupport (<= 5.1, >= 4.2)
|
9
|
-
# WARN: Clearing out unresolved specs.
|
10
|
-
# Please report a bug if this causes problems.
|
11
|
-
#
|
12
|
-
# This happens due to our dependency on activesupport, when Bundler.setup gets
|
13
|
-
# called. We don't actually *use* the dependency; it is purely there to
|
14
|
-
# restrict the Rails version that we're compatible with.
|
15
|
-
#
|
16
|
-
# When the warning is shown, Rubygems just does the below.
|
17
|
-
# Therefore, by doing it ourselves here, we can avoid the warning.
|
18
|
-
if Gem::Specification.respond_to?(:unresolved_deps)
|
19
|
-
Gem::Specification.unresolved_deps.clear
|
20
|
-
else
|
21
|
-
Gem.unresolved_deps.clear
|
22
|
-
end
|
23
|
-
|
24
4
|
if command == "spring"
|
25
5
|
load bin_path
|
26
6
|
else
|
@@ -3,11 +3,11 @@ require 'set'
|
|
3
3
|
module Spring
|
4
4
|
module Client
|
5
5
|
class Binstub < Command
|
6
|
-
SHEBANG = /\#\!.*\n
|
6
|
+
SHEBANG = /\#\!.*\n(\#.*\n)*/
|
7
7
|
|
8
|
-
# If loading the bin/spring file works, it'll run
|
8
|
+
# If loading the bin/spring file works, it'll run Spring which will
|
9
9
|
# eventually call Kernel.exit. This means that in the client process
|
10
|
-
# we will never execute the lines after this block. But if the
|
10
|
+
# we will never execute the lines after this block. But if the Spring
|
11
11
|
# client is not invoked for whatever reason, then the Kernel.exit won't
|
12
12
|
# happen, and so we'll fall back to the lines after this block, which
|
13
13
|
# should cause the "unsprung" version of the command to run.
|
@@ -26,7 +26,7 @@ CODE
|
|
26
26
|
SPRING = <<'CODE'
|
27
27
|
#!/usr/bin/env ruby
|
28
28
|
|
29
|
-
# This file loads
|
29
|
+
# This file loads Spring without using Bundler, in order to be fast.
|
30
30
|
# It gets overwritten when you run the `spring binstub` command.
|
31
31
|
|
32
32
|
unless defined?(Spring)
|
@@ -34,7 +34,8 @@ unless defined?(Spring)
|
|
34
34
|
require 'bundler'
|
35
35
|
|
36
36
|
lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
|
37
|
-
|
37
|
+
spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
|
38
|
+
if spring
|
38
39
|
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
39
40
|
gem 'spring', spring.version
|
40
41
|
require 'spring/binstub'
|
@@ -45,11 +46,10 @@ CODE
|
|
45
46
|
OLD_BINSTUB = %{if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?}
|
46
47
|
|
47
48
|
BINSTUB_VARIATIONS = Regexp.union [
|
48
|
-
%{begin\n load File.expand_path("../spring", __FILE__)\nrescue LoadError\nend\n},
|
49
49
|
%{begin\n load File.expand_path('../spring', __FILE__)\nrescue LoadError\nend\n},
|
50
50
|
%{begin\n spring_bin_path = File.expand_path('../spring', __FILE__)\n load spring_bin_path\nrescue LoadError => e\n raise unless e.message.end_with? spring_bin_path, 'spring/binstub'\nend\n},
|
51
51
|
LOADER
|
52
|
-
]
|
52
|
+
].map { |binstub| /#{Regexp.escape(binstub).gsub("'", "['\"]")}/ }
|
53
53
|
|
54
54
|
class Item
|
55
55
|
attr_reader :command, :existing
|
@@ -78,7 +78,7 @@ CODE
|
|
78
78
|
generate(fallback)
|
79
79
|
status "upgraded"
|
80
80
|
elsif existing.include?(LOADER)
|
81
|
-
status "
|
81
|
+
status "Spring already present"
|
82
82
|
elsif existing =~ BINSTUB_VARIATIONS
|
83
83
|
upgraded = existing.sub(BINSTUB_VARIATIONS, LOADER)
|
84
84
|
File.write(command.binstub, upgraded)
|
@@ -93,15 +93,15 @@ CODE
|
|
93
93
|
end
|
94
94
|
|
95
95
|
File.write(command.binstub, "#{head}#{shebang}#{LOADER}#{tail}")
|
96
|
-
status "
|
96
|
+
status "Spring inserted"
|
97
97
|
else
|
98
|
-
status "doesn't appear to be ruby, so cannot use
|
98
|
+
status "doesn't appear to be ruby, so cannot use Spring", $stderr
|
99
99
|
exit 1
|
100
100
|
end
|
101
101
|
end
|
102
102
|
else
|
103
103
|
generate
|
104
|
-
status "generated with
|
104
|
+
status "generated with Spring"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -118,7 +118,7 @@ CODE
|
|
118
118
|
def remove
|
119
119
|
if existing
|
120
120
|
File.write(command.binstub, existing.sub(BINSTUB_VARIATIONS, ""))
|
121
|
-
status "
|
121
|
+
status "Spring removed"
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
@@ -126,7 +126,7 @@ CODE
|
|
126
126
|
attr_reader :bindir, :items
|
127
127
|
|
128
128
|
def self.description
|
129
|
-
"Generate
|
129
|
+
"Generate Spring based binstubs. Use --all to generate a binstub for all known commands. Use --remove to revert."
|
130
130
|
end
|
131
131
|
|
132
132
|
def self.rails_command
|
data/lib/spring/client/help.rb
CHANGED
@@ -32,7 +32,7 @@ module Spring
|
|
32
32
|
def formatted_help
|
33
33
|
["Version: #{env.version}\n",
|
34
34
|
"Usage: spring COMMAND [ARGS]\n",
|
35
|
-
*command_help("
|
35
|
+
*command_help("Spring itself", spring_commands),
|
36
36
|
'',
|
37
37
|
*command_help("your application", application_commands)].join("\n")
|
38
38
|
end
|
data/lib/spring/client/rails.rb
CHANGED
@@ -14,7 +14,7 @@ module Spring
|
|
14
14
|
}
|
15
15
|
|
16
16
|
def self.description
|
17
|
-
"Run a rails command. The following sub commands will use
|
17
|
+
"Run a rails command. The following sub commands will use Spring: #{COMMANDS.to_a.join ', '}."
|
18
18
|
end
|
19
19
|
|
20
20
|
def call
|
data/lib/spring/client/run.rb
CHANGED
@@ -44,7 +44,7 @@ module Spring
|
|
44
44
|
require "spring/commands"
|
45
45
|
|
46
46
|
if Spring.command?(args.first)
|
47
|
-
# Command installed since
|
47
|
+
# Command installed since Spring started
|
48
48
|
stop_server
|
49
49
|
cold_run
|
50
50
|
else
|
@@ -116,7 +116,7 @@ module Spring
|
|
116
116
|
def verify_server_version
|
117
117
|
server_version = server.gets.chomp
|
118
118
|
if server_version != env.version
|
119
|
-
$stderr.puts "There is a version mismatch between the
|
119
|
+
$stderr.puts "There is a version mismatch between the Spring client " \
|
120
120
|
"(#{env.version}) and the server (#{server_version})."
|
121
121
|
|
122
122
|
if server_booted?
|
@@ -161,6 +161,8 @@ module Spring
|
|
161
161
|
if pid && !pid.empty?
|
162
162
|
log "got pid: #{pid}"
|
163
163
|
|
164
|
+
suspend_resume_on_tstp_cont(pid)
|
165
|
+
|
164
166
|
forward_signals(application)
|
165
167
|
status = application.read.to_i
|
166
168
|
|
@@ -181,6 +183,18 @@ module Spring
|
|
181
183
|
end
|
182
184
|
end
|
183
185
|
|
186
|
+
def suspend_resume_on_tstp_cont(pid)
|
187
|
+
trap("TSTP") {
|
188
|
+
log "suspended"
|
189
|
+
Process.kill("STOP", pid.to_i)
|
190
|
+
Process.kill("STOP", Process.pid)
|
191
|
+
}
|
192
|
+
trap("CONT") {
|
193
|
+
log "resumed"
|
194
|
+
Process.kill("CONT", pid.to_i)
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
184
198
|
def forward_signals(application)
|
185
199
|
@signal_queue.each { |sig| kill sig, application }
|
186
200
|
|
data/lib/spring/client/stop.rb
CHANGED
data/lib/spring/commands.rb
CHANGED
@@ -32,7 +32,7 @@ module Spring
|
|
32
32
|
# then we need to be under bundler.
|
33
33
|
require "bundler/setup"
|
34
34
|
|
35
|
-
# Auto-require any
|
35
|
+
# Auto-require any Spring extensions which are in the Gemfile
|
36
36
|
Gem::Specification.map(&:name).grep(/^spring-/).each do |command|
|
37
37
|
begin
|
38
38
|
require command
|
data/lib/spring/configuration.rb
CHANGED
@@ -5,7 +5,11 @@ module Spring
|
|
5
5
|
attr_accessor :application_root, :quiet
|
6
6
|
|
7
7
|
def gemfile
|
8
|
-
|
8
|
+
if /\s1.9.[0-9]/ === Bundler.ruby_scope.gsub(/[\/\s]+/,'')
|
9
|
+
ENV["BUNDLE_GEMFILE"] || "Gemfile"
|
10
|
+
else
|
11
|
+
Bundler.default_gemfile
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def after_fork_callbacks
|
data/lib/spring/env.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require "pathname"
|
2
|
-
require "fileutils"
|
3
2
|
require "digest/md5"
|
4
|
-
require "tmpdir"
|
5
3
|
|
6
4
|
require "spring/version"
|
7
5
|
require "spring/sid"
|
@@ -33,10 +31,12 @@ module Spring
|
|
33
31
|
end
|
34
32
|
|
35
33
|
def tmp_path
|
34
|
+
require "tmpdir"
|
36
35
|
path = Pathname.new(
|
37
36
|
ENV["SPRING_TMP_PATH"] ||
|
38
37
|
File.join(ENV['XDG_RUNTIME_DIR'] || Dir.tmpdir, "spring-#{Process.uid}")
|
39
38
|
)
|
39
|
+
require "fileutils"
|
40
40
|
FileUtils.mkdir_p(path) unless path.exist?
|
41
41
|
path
|
42
42
|
end
|
data/lib/spring/errors.rb
CHANGED
@@ -24,7 +24,7 @@ module Spring
|
|
24
24
|
|
25
25
|
def message
|
26
26
|
"Spring was unable to find your config/application.rb file. " \
|
27
|
-
"Your project root was detected at #{project_root}, so
|
27
|
+
"Your project root was detected at #{project_root}, so Spring " \
|
28
28
|
"looked for #{project_root}/config/application.rb but it doesn't exist. You can " \
|
29
29
|
"configure the root of your application by setting Spring.application_root in " \
|
30
30
|
"config/spring.rb."
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spring
|
2
2
|
# Yes, I know this reimplements a bunch of stuff in Active Support, but
|
3
|
-
# I don't want the
|
3
|
+
# I don't want the Spring client to depend on AS, in order to keep its
|
4
4
|
# load time down.
|
5
5
|
class ProcessTitleUpdater
|
6
6
|
SECOND = 1
|
data/lib/spring/version.rb
CHANGED
@@ -23,9 +23,21 @@ module Spring
|
|
23
23
|
@directories = Set.new
|
24
24
|
@stale = false
|
25
25
|
@listeners = []
|
26
|
+
|
27
|
+
@on_debug = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_debug(&block)
|
31
|
+
@on_debug = block
|
32
|
+
end
|
33
|
+
|
34
|
+
def debug
|
35
|
+
@on_debug.call(yield) if @on_debug
|
26
36
|
end
|
27
37
|
|
28
38
|
def add(*items)
|
39
|
+
debug { "watcher: add: #{items.inspect}" }
|
40
|
+
|
29
41
|
items = items.flatten.map do |item|
|
30
42
|
item = Pathname.new(item)
|
31
43
|
|
@@ -36,14 +48,30 @@ module Spring
|
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
39
|
-
items = items.select
|
51
|
+
items = items.select do |item|
|
52
|
+
if item.symlink?
|
53
|
+
item.readlink.exist?.tap do |exists|
|
54
|
+
if !exists
|
55
|
+
debug { "add: ignoring dangling symlink: #{item.inspect} -> #{item.readlink.inspect}" }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
item.exist?
|
60
|
+
end
|
61
|
+
end
|
40
62
|
|
41
63
|
synchronize {
|
42
64
|
items.each do |item|
|
43
65
|
if item.directory?
|
44
66
|
directories << item.realpath.to_s
|
45
67
|
else
|
46
|
-
|
68
|
+
begin
|
69
|
+
files << item.realpath.to_s
|
70
|
+
rescue Errno::ENOENT
|
71
|
+
# Race condition. Ignore symlinks whose target was removed
|
72
|
+
# since the check above, or are deeply chained.
|
73
|
+
debug { "add: ignoring now-dangling symlink: #{item.inspect} -> #{item.readlink.inspect}" }
|
74
|
+
end
|
47
75
|
end
|
48
76
|
end
|
49
77
|
|
@@ -56,16 +84,19 @@ module Spring
|
|
56
84
|
end
|
57
85
|
|
58
86
|
def on_stale(&block)
|
87
|
+
debug { "added listener: #{block.inspect}" }
|
59
88
|
@listeners << block
|
60
89
|
end
|
61
90
|
|
62
91
|
def mark_stale
|
63
92
|
return if stale?
|
64
93
|
@stale = true
|
94
|
+
debug { "marked stale, calling listeners: listeners=#{@listeners.inspect}" }
|
65
95
|
@listeners.each(&:call)
|
66
96
|
end
|
67
97
|
|
68
98
|
def restart
|
99
|
+
debug { "restarting" }
|
69
100
|
stop
|
70
101
|
start
|
71
102
|
end
|