spring 2.0.2 → 4.1.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 +5 -5
- data/LICENSE.txt +1 -0
- data/README.md +66 -39
- data/lib/spring/application.rb +58 -38
- data/lib/spring/application_manager.rb +4 -2
- data/lib/spring/binstub.rb +0 -20
- data/lib/spring/client/binstub.rb +32 -40
- data/lib/spring/client/help.rb +1 -1
- data/lib/spring/client/rails.rb +4 -4
- data/lib/spring/client/run.rb +23 -4
- data/lib/spring/client/stop.rb +1 -1
- data/lib/spring/commands.rb +11 -4
- data/lib/spring/configuration.rb +22 -2
- data/lib/spring/env.rb +3 -4
- data/lib/spring/errors.rb +1 -1
- data/lib/spring/json.rb +27 -30
- data/lib/spring/process_title_updater.rb +1 -1
- data/lib/spring/server.rb +2 -1
- data/lib/spring/version.rb +1 -1
- data/lib/spring/watcher/abstract.rb +4 -5
- data/lib/spring/watcher/polling.rb +1 -1
- metadata +15 -22
- data/lib/spring/sid.rb +0 -42
- data/lib/spring/test/acceptance_test.rb +0 -558
- data/lib/spring/test/application.rb +0 -229
- data/lib/spring/test/application_generator.rb +0 -144
- data/lib/spring/test/rails_version.rb +0 -23
- data/lib/spring/test/watcher_test.rb +0 -194
- 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: 557c3aebe1211983306061278ab800f1232e42d67a40bc4042c24560ff44409d
|
|
4
|
+
data.tar.gz: 6c1cdb2f00e1f7893d0fbf60b49d76d8841dd9c931dfa79c45387ddbec1bea5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1da8511a30a3802f6b96ce29b342e70bf136de411278624758a55b73140130902ad7e1afa488df1f48a06685b1980b0f5dd9b9185f27e36ec3d3ba43b9c27841
|
|
7
|
+
data.tar.gz: c05785038b3a2a048c2b6e9f95f0979561c292714029ec58da934f1cd5e139b3e66b3da9d917082717e83891ac922292f636b53183de580672325b52c58665a9
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Spring
|
|
2
2
|
|
|
3
|
-
[](
|
|
3
|
+
[](https://github.com/rails/spring/actions/workflows/ci.yml?branch=main)
|
|
4
|
+
[](https://badge.fury.io/rb/spring)
|
|
5
5
|
|
|
6
6
|
Spring is a Rails application preloader. It speeds up development by
|
|
7
|
-
keeping your application running in the background so you don't need to
|
|
7
|
+
keeping your application running in the background, so you don't need to
|
|
8
8
|
boot it every time you run a test, rake task or migration.
|
|
9
9
|
|
|
10
10
|
## Features
|
|
@@ -16,9 +16,9 @@ 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:
|
|
21
|
-
|
|
19
|
+
* Ruby versions: MRI 2.7, MRI 3.0, MRI 3.1
|
|
20
|
+
* Rails versions: 6.0, 6.1, 7.0
|
|
21
|
+
* Bundler v2.1+
|
|
22
22
|
|
|
23
23
|
Spring makes extensive use of `Process.fork`, so won't be able to
|
|
24
24
|
provide a speed up on platforms which don't support forking (Windows, JRuby).
|
|
@@ -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:
|
|
@@ -50,21 +50,35 @@ code into relevant existing executables. The snippet looks like this:
|
|
|
50
50
|
``` ruby
|
|
51
51
|
begin
|
|
52
52
|
load File.expand_path('../spring', __FILE__)
|
|
53
|
-
rescue LoadError
|
|
53
|
+
rescue LoadError => e
|
|
54
|
+
raise unless e.message.include?('spring')
|
|
54
55
|
end
|
|
55
56
|
```
|
|
56
57
|
|
|
57
|
-
On platforms where
|
|
58
|
-
hooks
|
|
59
|
-
will just be silently ignored and the lines after it will be executed as
|
|
58
|
+
On platforms where Spring is installed and supported, this snippet
|
|
59
|
+
hooks Spring into the execution of commands. In other cases, the snippet
|
|
60
|
+
will just be silently ignored, and the lines after it will be executed as
|
|
60
61
|
normal.
|
|
61
62
|
|
|
62
63
|
If you don't want to prefix every command you type with `bin/`, you
|
|
63
|
-
can [use direnv](https://github.com/
|
|
64
|
+
can [use direnv](https://github.com/direnv/direnv#the-stdlib) to
|
|
64
65
|
automatically add `./bin` to your `PATH` when you `cd` into your application.
|
|
65
66
|
Simply create an `.envrc` file with the command `PATH_add bin` in your
|
|
66
67
|
Rails directory.
|
|
67
68
|
|
|
69
|
+
### Enable reloading
|
|
70
|
+
|
|
71
|
+
Spring reloads application code, and therefore needs the application to have
|
|
72
|
+
reloading enabled.
|
|
73
|
+
|
|
74
|
+
Ensure that `config.enable_reloading` is `true` in the environments that
|
|
75
|
+
Spring manages. That setting is typically configured in
|
|
76
|
+
`config/environments/*.rb`. In particular, make sure it is `true` for the
|
|
77
|
+
`test` environment.
|
|
78
|
+
|
|
79
|
+
Note: in versions of Rails before 7, the setting is called `cache_classes`,
|
|
80
|
+
and it needs to be `false` for Spring to work.
|
|
81
|
+
|
|
68
82
|
### Usage
|
|
69
83
|
|
|
70
84
|
For this walkthrough I've generated a new Rails application, and run
|
|
@@ -90,7 +104,7 @@ user 0m0.281s
|
|
|
90
104
|
sys 0m0.066s
|
|
91
105
|
```
|
|
92
106
|
|
|
93
|
-
That wasn't particularly fast because it was the first run, so
|
|
107
|
+
That wasn't particularly fast because it was the first run, so Spring
|
|
94
108
|
had to boot the application. It's now running:
|
|
95
109
|
|
|
96
110
|
```
|
|
@@ -167,8 +181,8 @@ Spring is running:
|
|
|
167
181
|
26707 spring app | spring-demo-app | started 2 secs ago | development mode
|
|
168
182
|
```
|
|
169
183
|
|
|
170
|
-
There's no need to "shut down"
|
|
171
|
-
when you close your terminal. However if you do want to do a manual shut
|
|
184
|
+
There's no need to "shut down" Spring. This will happen automatically
|
|
185
|
+
when you close your terminal. However, if you do want to do a manual shut
|
|
172
186
|
down, use the `stop` command:
|
|
173
187
|
|
|
174
188
|
```
|
|
@@ -176,9 +190,11 @@ $ bin/spring stop
|
|
|
176
190
|
Spring stopped.
|
|
177
191
|
```
|
|
178
192
|
|
|
193
|
+
From within your code, you can check whether Spring is active with `if defined?(Spring)`.
|
|
194
|
+
|
|
179
195
|
### Removal
|
|
180
196
|
|
|
181
|
-
To remove
|
|
197
|
+
To remove Spring:
|
|
182
198
|
|
|
183
199
|
* 'Unspring' your bin/ executables: `bin/spring binstub --remove --all`
|
|
184
200
|
* Remove spring from your Gemfile
|
|
@@ -186,12 +202,13 @@ To remove spring:
|
|
|
186
202
|
### Deployment
|
|
187
203
|
|
|
188
204
|
You must not install Spring on your production environment. To prevent it from
|
|
189
|
-
being installed,
|
|
205
|
+
being installed, run the `bundle config set without 'development test'` before
|
|
190
206
|
`bundle install` command which is used to install gems on your production
|
|
191
207
|
machines:
|
|
192
208
|
|
|
193
209
|
```
|
|
194
|
-
$ bundle
|
|
210
|
+
$ bundle config set without 'development test'
|
|
211
|
+
$ bundle install
|
|
195
212
|
```
|
|
196
213
|
|
|
197
214
|
## Commands
|
|
@@ -216,7 +233,7 @@ Spring::Commands::Rake.environment_matchers[:default] = "development"
|
|
|
216
233
|
### `rails console`, `rails generate`, `rails runner`
|
|
217
234
|
|
|
218
235
|
These execute the rails command you already know and love. If you run
|
|
219
|
-
a different sub command (e.g. `rails server`) then
|
|
236
|
+
a different sub command (e.g. `rails server`) then Spring will automatically
|
|
220
237
|
pass it through to the underlying `rails` executable (without the
|
|
221
238
|
speed-up).
|
|
222
239
|
|
|
@@ -230,18 +247,22 @@ You can add these to your Gemfile for additional commands:
|
|
|
230
247
|
* [spring-commands-testunit](https://github.com/jonleighton/spring-commands-testunit) - useful for
|
|
231
248
|
running `Test::Unit` tests on Rails 3, since only Rails 4 allows you
|
|
232
249
|
to use `rake test path/to/test` to run a particular test/directory.
|
|
250
|
+
* [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
251
|
* [spring-commands-teaspoon](https://github.com/alejandrobabio/spring-commands-teaspoon.git)
|
|
234
252
|
* [spring-commands-m](https://github.com/gabrieljoelc/spring-commands-m.git)
|
|
235
253
|
* [spring-commands-rubocop](https://github.com/p0deje/spring-commands-rubocop)
|
|
254
|
+
* [spring-commands-rackup](https://github.com/wintersolutions/spring-commands-rackup)
|
|
255
|
+
* [spring-commands-rack-console](https://github.com/wintersolutions/spring-commands-rack-console)
|
|
256
|
+
* [spring-commands-standard](https://github.com/lakim/spring-commands-standard)
|
|
236
257
|
|
|
237
258
|
## Use without adding to bundle
|
|
238
259
|
|
|
239
|
-
If you don't want
|
|
240
|
-
repository, it's possible to use
|
|
241
|
-
However, using
|
|
260
|
+
If you don't want Spring-related code checked into your source
|
|
261
|
+
repository, it's possible to use Spring without adding to your Gemfile.
|
|
262
|
+
However, using Spring binstubs without adding Spring to the Gemfile is not
|
|
242
263
|
supported.
|
|
243
264
|
|
|
244
|
-
To use
|
|
265
|
+
To use Spring like this, do a `gem install spring` and then prefix
|
|
245
266
|
commands with `spring`. For example, rather than running `bin/rake -T`,
|
|
246
267
|
you'd run `spring rake -T`.
|
|
247
268
|
|
|
@@ -252,12 +273,10 @@ run through Spring, set the `DISABLE_SPRING` environment variable.
|
|
|
252
273
|
|
|
253
274
|
## Class reloading
|
|
254
275
|
|
|
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.
|
|
276
|
+
Spring uses Rails' class reloading mechanism to keep your code up to date
|
|
277
|
+
between test runs. This is the same mechanism which allows you to see changes
|
|
278
|
+
during development when you refresh the page. However, you may never have used
|
|
279
|
+
this mechanism with your `test` environment before, and this can cause problems.
|
|
261
280
|
|
|
262
281
|
It's important to realise that code reloading means that the constants
|
|
263
282
|
in your application are *different objects* after files have changed:
|
|
@@ -357,7 +376,7 @@ application restart, you can specify them with `Spring.watch`:
|
|
|
357
376
|
Spring.watch "config/some_config_file.yml"
|
|
358
377
|
```
|
|
359
378
|
|
|
360
|
-
By default Spring polls the filesystem for changes once every 0.2 seconds. This
|
|
379
|
+
By default, Spring polls the filesystem for changes once every 0.2 seconds. This
|
|
361
380
|
method requires zero configuration, but if you find that it's using too
|
|
362
381
|
much CPU, then you can use event-based file system listening by
|
|
363
382
|
installing the
|
|
@@ -373,38 +392,46 @@ a command runs:
|
|
|
373
392
|
Spring.quiet = true
|
|
374
393
|
```
|
|
375
394
|
|
|
395
|
+
You can also set the initial state of the `quiet` configuration option to true
|
|
396
|
+
by setting the `SPRING_QUIET` environment variable before executing Spring.
|
|
397
|
+
This is useful if you want to set quiet mode when invoking the Spring executable
|
|
398
|
+
in a subprocess, and cannot or prefer not to set it programmatically
|
|
399
|
+
via the `Spring.quiet` option in `~/.spring.rb` or the app's `config/spring.rb`.
|
|
400
|
+
|
|
376
401
|
### Environment variables
|
|
377
402
|
|
|
378
403
|
The following environment variables are used by Spring:
|
|
379
404
|
|
|
380
|
-
* `DISABLE_SPRING` - If set, Spring will be bypassed and your
|
|
405
|
+
* `DISABLE_SPRING` - If set, Spring will be bypassed, and your
|
|
381
406
|
application will boot in a foreground process
|
|
382
407
|
* `SPRING_LOG` - The path to a file which Spring will write log messages
|
|
383
408
|
to.
|
|
384
409
|
* `SPRING_TMP_PATH` - The directory where Spring should write its temporary
|
|
385
|
-
files (a pidfile and a socket). By default we use the
|
|
410
|
+
files (a pidfile and a socket). By default, we use the
|
|
386
411
|
`XDG_RUNTIME_DIR` environment variable, or else `Dir.tmpdir`, and then
|
|
387
412
|
create a directory in that named `spring-$UID`. We don't use your
|
|
388
413
|
Rails application's `tmp/` directory because that may be on a
|
|
389
414
|
filesystem which doesn't support UNIX sockets.
|
|
390
415
|
* `SPRING_APPLICATION_ID` - Used to identify distinct Rails
|
|
391
|
-
applications. By default it is an MD5 hash of the current
|
|
416
|
+
applications. By default, it is an MD5 hash of the current
|
|
392
417
|
`RUBY_VERSION`, and the path to your Rails project root.
|
|
393
418
|
* `SPRING_SOCKET` - The path which should be used for the UNIX socket
|
|
394
419
|
which Spring uses to communicate with the long-running Spring server
|
|
395
|
-
process. By default this is `SPRING_TMP_PATH/SPRING_APPLICATION_ID`.
|
|
420
|
+
process. By default, this is `SPRING_TMP_PATH/SPRING_APPLICATION_ID`.
|
|
396
421
|
* `SPRING_PIDFILE` - The path which should be used to store the pid of
|
|
397
|
-
the long-running Spring server process. By default this is related to
|
|
422
|
+
the long-running Spring server process. By default, this is related to
|
|
398
423
|
the socket path; if the socket path is `/foo/bar/spring.sock` the
|
|
399
424
|
pidfile will be `/foo/bar/spring.pid`.
|
|
400
|
-
* `
|
|
425
|
+
* `SPRING_QUIET` - If set, the initial state of the `Spring.quiet`
|
|
426
|
+
configuration option will default to `true`.
|
|
427
|
+
* `SPRING_SERVER_COMMAND` - The command to run to start up the Spring
|
|
401
428
|
server when it is not already running. Defaults to `spring _[version]_
|
|
402
429
|
server --background`.
|
|
403
430
|
|
|
404
431
|
## Troubleshooting
|
|
405
432
|
|
|
406
|
-
If you want to get more information about what
|
|
407
|
-
run
|
|
433
|
+
If you want to get more information about what Spring is doing, you can
|
|
434
|
+
run Spring explicitly in a separate terminal:
|
|
408
435
|
|
|
409
436
|
```
|
|
410
437
|
$ spring server
|
data/lib/spring/application.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require "spring/boot"
|
|
2
|
-
require "set"
|
|
3
2
|
require "pty"
|
|
4
3
|
|
|
5
4
|
module Spring
|
|
@@ -11,7 +10,8 @@ module Spring
|
|
|
11
10
|
@original_env = original_env
|
|
12
11
|
@spring_env = spring_env
|
|
13
12
|
@mutex = Mutex.new
|
|
14
|
-
@waiting =
|
|
13
|
+
@waiting = {}
|
|
14
|
+
@clients = {}
|
|
15
15
|
@preloaded = false
|
|
16
16
|
@state = :initialized
|
|
17
17
|
@interrupt = IO.pipe
|
|
@@ -91,18 +91,20 @@ module Spring
|
|
|
91
91
|
|
|
92
92
|
require Spring.application_root_path.join("config", "application")
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# override the effect of config.cache_classes = true. We can then actually
|
|
97
|
-
# set config.cache_classes = false after loading the environment.
|
|
98
|
-
Rails::Application.initializer :initialize_dependency_mechanism, group: :all do
|
|
99
|
-
ActiveSupport::Dependencies.mechanism = :load
|
|
94
|
+
unless Rails.respond_to?(:gem_version) && Rails.gem_version >= Gem::Version.new('6.0.0')
|
|
95
|
+
raise "Spring only supports Rails >= 6.0.0"
|
|
100
96
|
end
|
|
101
97
|
|
|
102
|
-
|
|
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
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
Rails.application.config.cache_classes = false
|
|
107
|
+
require Spring.application_root_path.join("config", "environment")
|
|
106
108
|
|
|
107
109
|
disconnect_database
|
|
108
110
|
|
|
@@ -113,7 +115,7 @@ module Spring
|
|
|
113
115
|
raise e unless initialized?
|
|
114
116
|
ensure
|
|
115
117
|
watcher.add loaded_application_features
|
|
116
|
-
watcher.add Spring.gemfile,
|
|
118
|
+
watcher.add Spring.gemfile, Spring.gemfile_lock
|
|
117
119
|
|
|
118
120
|
if defined?(Rails) && Rails.application
|
|
119
121
|
watcher.add Rails.application.paths["config/initializers"]
|
|
@@ -125,7 +127,12 @@ module Spring
|
|
|
125
127
|
end
|
|
126
128
|
|
|
127
129
|
def eager_preload
|
|
128
|
-
with_pty
|
|
130
|
+
with_pty do
|
|
131
|
+
# we can't see stderr and there could be issues when it's overflown
|
|
132
|
+
# see https://github.com/rails/spring/issues/396
|
|
133
|
+
STDERR.reopen("/dev/null")
|
|
134
|
+
preload
|
|
135
|
+
end
|
|
129
136
|
end
|
|
130
137
|
|
|
131
138
|
def run
|
|
@@ -147,10 +154,23 @@ module Spring
|
|
|
147
154
|
log "got client"
|
|
148
155
|
manager.puts
|
|
149
156
|
|
|
150
|
-
|
|
157
|
+
@clients[client] = true
|
|
158
|
+
|
|
159
|
+
_stdout, stderr, _stdin = streams = 3.times.map { client.recv_io }
|
|
151
160
|
[STDOUT, STDERR, STDIN].zip(streams).each { |a, b| a.reopen(b) }
|
|
152
161
|
|
|
153
|
-
|
|
162
|
+
if preloaded?
|
|
163
|
+
client.puts(0) # preload success
|
|
164
|
+
else
|
|
165
|
+
begin
|
|
166
|
+
preload
|
|
167
|
+
client.puts(0) # preload success
|
|
168
|
+
rescue Exception
|
|
169
|
+
log "preload failed"
|
|
170
|
+
client.puts(1) # preload failure
|
|
171
|
+
raise
|
|
172
|
+
end
|
|
173
|
+
end
|
|
154
174
|
|
|
155
175
|
args, env = JSON.load(client.read(client.gets.to_i)).values_at("args", "env")
|
|
156
176
|
command = Spring.command(args.shift)
|
|
@@ -159,39 +179,39 @@ module Spring
|
|
|
159
179
|
setup command
|
|
160
180
|
|
|
161
181
|
if Rails.application.reloaders.any?(&:updated?)
|
|
162
|
-
|
|
163
|
-
if defined? ActiveSupport::Reloader
|
|
164
|
-
Rails.application.reloader.reload!
|
|
165
|
-
else
|
|
166
|
-
ActionDispatch::Reloader.cleanup!
|
|
167
|
-
ActionDispatch::Reloader.prepare!
|
|
168
|
-
end
|
|
182
|
+
Rails.application.reloader.reload!
|
|
169
183
|
end
|
|
170
184
|
|
|
171
185
|
pid = fork {
|
|
186
|
+
# Make sure to close other clients otherwise their graceful termination
|
|
187
|
+
# will be impossible due to reference from this fork.
|
|
188
|
+
@clients.each_key { |c| c.close if c != client }
|
|
189
|
+
|
|
172
190
|
Process.setsid
|
|
173
191
|
IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
|
|
174
192
|
trap("TERM", "DEFAULT")
|
|
175
193
|
|
|
176
|
-
|
|
194
|
+
unless Spring.quiet
|
|
195
|
+
STDERR.puts "Running via Spring preloader in process #{Process.pid}"
|
|
196
|
+
|
|
197
|
+
if Rails.env.production?
|
|
198
|
+
STDERR.puts "WARNING: Spring is running in production. To fix " \
|
|
199
|
+
"this make sure the spring gem is only present " \
|
|
200
|
+
"in `development` and `test` groups in your Gemfile " \
|
|
201
|
+
"and make sure you always use " \
|
|
202
|
+
"`bundle install --without development test` in production"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
177
205
|
|
|
178
206
|
ARGV.replace(args)
|
|
179
207
|
$0 = command.exec_name
|
|
180
208
|
|
|
181
|
-
# Delete all env vars which are unchanged from before
|
|
209
|
+
# Delete all env vars which are unchanged from before Spring started
|
|
182
210
|
original_env.each { |k, v| ENV.delete k if ENV[k] == v }
|
|
183
211
|
|
|
184
|
-
# Load in the current env vars, except those which *were* changed when
|
|
212
|
+
# Load in the current env vars, except those which *were* changed when Spring started
|
|
185
213
|
env.each { |k, v| ENV[k] ||= v }
|
|
186
214
|
|
|
187
|
-
# requiring is faster, so if config.cache_classes was true in
|
|
188
|
-
# the environment's config file, then we can respect that from
|
|
189
|
-
# here on as we no longer need constant reloading.
|
|
190
|
-
if @original_cache_classes
|
|
191
|
-
ActiveSupport::Dependencies.mechanism = :require
|
|
192
|
-
Rails.application.config.cache_classes = true
|
|
193
|
-
end
|
|
194
|
-
|
|
195
215
|
connect_database
|
|
196
216
|
srand
|
|
197
217
|
|
|
@@ -229,7 +249,7 @@ module Spring
|
|
|
229
249
|
if exiting?
|
|
230
250
|
# Ensure that we do not ignore subsequent termination attempts
|
|
231
251
|
log "forced exit"
|
|
232
|
-
@waiting.
|
|
252
|
+
@waiting.each_key { |pid| Process.kill("TERM", pid) }
|
|
233
253
|
Kernel.exit
|
|
234
254
|
else
|
|
235
255
|
state! :terminating
|
|
@@ -282,13 +302,13 @@ module Spring
|
|
|
282
302
|
Kernel.module_eval do
|
|
283
303
|
old_raise = Kernel.method(:raise)
|
|
284
304
|
remove_method :raise
|
|
285
|
-
define_method :raise do |*args|
|
|
305
|
+
define_method :raise do |*args, **kwargs|
|
|
286
306
|
begin
|
|
287
|
-
old_raise.call(*args)
|
|
307
|
+
old_raise.call(*args, **kwargs)
|
|
288
308
|
ensure
|
|
289
309
|
if $!
|
|
290
310
|
lib = File.expand_path("..", __FILE__)
|
|
291
|
-
$!.backtrace.reject! { |line| line.start_with?(lib) }
|
|
311
|
+
$!.backtrace.reject! { |line| line.start_with?(lib) } unless $!.backtrace.frozen?
|
|
292
312
|
end
|
|
293
313
|
end
|
|
294
314
|
end
|
|
@@ -321,7 +341,7 @@ module Spring
|
|
|
321
341
|
end
|
|
322
342
|
|
|
323
343
|
def wait(pid, streams, client)
|
|
324
|
-
@mutex.synchronize { @waiting
|
|
344
|
+
@mutex.synchronize { @waiting[pid] = true }
|
|
325
345
|
|
|
326
346
|
# Wait in a separate thread so we can run multiple commands at once
|
|
327
347
|
Spring.failsafe_thread {
|
|
@@ -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
|
|
@@ -1,56 +1,48 @@
|
|
|
1
|
-
require 'set'
|
|
2
|
-
|
|
3
1
|
module Spring
|
|
4
2
|
module Client
|
|
5
3
|
class Binstub < Command
|
|
6
|
-
SHEBANG = /\#\!.*\n
|
|
4
|
+
SHEBANG = /\#\!.*\n(\#.*\n)*/
|
|
7
5
|
|
|
8
|
-
# If loading the bin/spring file works, it'll run
|
|
6
|
+
# If loading the bin/spring file works, it'll run Spring which will
|
|
9
7
|
# eventually call Kernel.exit. This means that in the client process
|
|
10
|
-
# we will never execute the lines after this block. But if the
|
|
8
|
+
# we will never execute the lines after this block. But if the Spring
|
|
11
9
|
# client is not invoked for whatever reason, then the Kernel.exit won't
|
|
12
10
|
# happen, and so we'll fall back to the lines after this block, which
|
|
13
11
|
# should cause the "unsprung" version of the command to run.
|
|
14
|
-
LOADER =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
rescue LoadError => e
|
|
18
|
-
raise unless e.message.include?('spring')
|
|
19
|
-
end
|
|
20
|
-
CODE
|
|
12
|
+
LOADER = <<~CODE
|
|
13
|
+
load File.expand_path("spring", __dir__)
|
|
14
|
+
CODE
|
|
21
15
|
|
|
22
16
|
# The defined? check ensures these lines don't execute when we load the
|
|
23
17
|
# binstub from the application process. Which means that in the application
|
|
24
18
|
# process we'll execute the lines which come after the LOADER block, which
|
|
25
19
|
# is what we want.
|
|
26
|
-
SPRING =
|
|
27
|
-
#!/usr/bin/env ruby
|
|
28
|
-
|
|
29
|
-
# This file loads
|
|
30
|
-
# It gets overwritten when you run the `spring binstub` command.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
CODE
|
|
20
|
+
SPRING = <<~CODE
|
|
21
|
+
#!/usr/bin/env ruby
|
|
22
|
+
|
|
23
|
+
# This file loads Spring without using loading other gems in the Gemfile, in order to be fast.
|
|
24
|
+
# It gets overwritten when you run the `spring binstub` command.
|
|
25
|
+
|
|
26
|
+
if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"])
|
|
27
|
+
require "bundler"
|
|
28
|
+
|
|
29
|
+
Bundler.locked_gems.specs.find { |spec| spec.name == "spring" }&.tap do |spring|
|
|
30
|
+
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
|
31
|
+
gem "spring", spring.version
|
|
32
|
+
require "spring/binstub"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
CODE
|
|
45
36
|
|
|
46
37
|
OLD_BINSTUB = %{if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?}
|
|
47
38
|
|
|
48
39
|
BINSTUB_VARIATIONS = Regexp.union [
|
|
49
|
-
%{
|
|
40
|
+
%{load File.expand_path("spring", __dir__)\n},
|
|
41
|
+
%{begin\n load File.expand_path('../spring', __FILE__)\nrescue LoadError => e\n raise unless e.message.include?('spring')\nend\n},
|
|
50
42
|
%{begin\n load File.expand_path('../spring', __FILE__)\nrescue LoadError\nend\n},
|
|
51
43
|
%{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},
|
|
52
44
|
LOADER
|
|
53
|
-
]
|
|
45
|
+
].map { |binstub| /#{Regexp.escape(binstub).gsub("'", "['\"]")}/ }
|
|
54
46
|
|
|
55
47
|
class Item
|
|
56
48
|
attr_reader :command, :existing
|
|
@@ -79,7 +71,7 @@ CODE
|
|
|
79
71
|
generate(fallback)
|
|
80
72
|
status "upgraded"
|
|
81
73
|
elsif existing.include?(LOADER)
|
|
82
|
-
status "
|
|
74
|
+
status "Spring already present"
|
|
83
75
|
elsif existing =~ BINSTUB_VARIATIONS
|
|
84
76
|
upgraded = existing.sub(BINSTUB_VARIATIONS, LOADER)
|
|
85
77
|
File.write(command.binstub, upgraded)
|
|
@@ -94,15 +86,15 @@ CODE
|
|
|
94
86
|
end
|
|
95
87
|
|
|
96
88
|
File.write(command.binstub, "#{head}#{shebang}#{LOADER}#{tail}")
|
|
97
|
-
status "
|
|
89
|
+
status "Spring inserted"
|
|
98
90
|
else
|
|
99
|
-
status "doesn't appear to be ruby, so cannot use
|
|
91
|
+
status "doesn't appear to be ruby, so cannot use Spring", $stderr
|
|
100
92
|
exit 1
|
|
101
93
|
end
|
|
102
94
|
end
|
|
103
95
|
else
|
|
104
96
|
generate
|
|
105
|
-
status "generated with
|
|
97
|
+
status "generated with Spring"
|
|
106
98
|
end
|
|
107
99
|
end
|
|
108
100
|
|
|
@@ -119,7 +111,7 @@ CODE
|
|
|
119
111
|
def remove
|
|
120
112
|
if existing
|
|
121
113
|
File.write(command.binstub, existing.sub(BINSTUB_VARIATIONS, ""))
|
|
122
|
-
status "
|
|
114
|
+
status "Spring removed"
|
|
123
115
|
end
|
|
124
116
|
end
|
|
125
117
|
end
|
|
@@ -127,7 +119,7 @@ CODE
|
|
|
127
119
|
attr_reader :bindir, :items
|
|
128
120
|
|
|
129
121
|
def self.description
|
|
130
|
-
"Generate
|
|
122
|
+
"Generate Spring based binstubs. Use --all to generate a binstub for all known commands. Use --remove to revert."
|
|
131
123
|
end
|
|
132
124
|
|
|
133
125
|
def self.rails_command
|
|
@@ -147,7 +139,7 @@ CODE
|
|
|
147
139
|
@mode = :add
|
|
148
140
|
@items = args.drop(1)
|
|
149
141
|
.map { |name| find_commands name }
|
|
150
|
-
.
|
|
142
|
+
.flatten.uniq
|
|
151
143
|
.map { |command| Item.new(command) }
|
|
152
144
|
end
|
|
153
145
|
|
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
|