spring 0.0.10 → 0.0.11
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.
- data/.travis.yml +3 -0
- data/CHANGELOG.md +13 -2
- data/Gemfile +1 -1
- data/README.md +16 -11
- data/lib/spring/application.rb +97 -20
- data/lib/spring/application_manager.rb +16 -9
- data/lib/spring/client.rb +1 -1
- data/lib/spring/client/binstub.rb +1 -1
- data/lib/spring/client/rails.rb +8 -3
- data/lib/spring/client/run.rb +23 -6
- data/lib/spring/client/status.rb +2 -2
- data/lib/spring/commands.rb +3 -0
- data/lib/spring/commands/rails.rb +7 -0
- data/lib/spring/configuration.rb +1 -1
- data/lib/spring/env.rb +8 -2
- data/lib/spring/errors.rb +15 -1
- data/lib/spring/server.rb +27 -14
- data/lib/spring/version.rb +1 -1
- data/lib/spring/watcher.rb +1 -0
- data/lib/spring/watcher/abstract.rb +9 -7
- data/lib/spring/watcher/polling.rb +1 -1
- data/test/acceptance/app_test.rb +168 -86
- data/test/apps/.gitignore +3 -0
- data/test/unit/watcher_test.rb +12 -0
- metadata +4 -134
- data/test/apps/rails-3-2/.gitignore +0 -18
- data/test/apps/rails-3-2/Gemfile +0 -7
- data/test/apps/rails-3-2/README.rdoc +0 -261
- data/test/apps/rails-3-2/Rakefile +0 -7
- data/test/apps/rails-3-2/app/assets/images/rails.png +0 -0
- data/test/apps/rails-3-2/app/assets/javascripts/application.js +0 -15
- data/test/apps/rails-3-2/app/assets/javascripts/posts.js.coffee +0 -3
- data/test/apps/rails-3-2/app/assets/stylesheets/application.css +0 -13
- data/test/apps/rails-3-2/app/assets/stylesheets/posts.css.scss +0 -3
- data/test/apps/rails-3-2/app/assets/stylesheets/scaffolds.css.scss +0 -69
- data/test/apps/rails-3-2/app/controllers/application_controller.rb +0 -3
- data/test/apps/rails-3-2/app/controllers/posts_controller.rb +0 -83
- data/test/apps/rails-3-2/app/helpers/application_helper.rb +0 -2
- data/test/apps/rails-3-2/app/helpers/posts_helper.rb +0 -2
- data/test/apps/rails-3-2/app/mailers/.gitkeep +0 -0
- data/test/apps/rails-3-2/app/models/.gitkeep +0 -0
- data/test/apps/rails-3-2/app/models/post.rb +0 -3
- data/test/apps/rails-3-2/app/views/layouts/application.html.erb +0 -14
- data/test/apps/rails-3-2/app/views/posts/_form.html.erb +0 -21
- data/test/apps/rails-3-2/app/views/posts/edit.html.erb +0 -6
- data/test/apps/rails-3-2/app/views/posts/index.html.erb +0 -23
- data/test/apps/rails-3-2/app/views/posts/new.html.erb +0 -5
- data/test/apps/rails-3-2/app/views/posts/show.html.erb +0 -10
- data/test/apps/rails-3-2/config.ru +0 -4
- data/test/apps/rails-3-2/config/application.rb +0 -62
- data/test/apps/rails-3-2/config/boot.rb +0 -6
- data/test/apps/rails-3-2/config/database.yml +0 -25
- data/test/apps/rails-3-2/config/environment.rb +0 -5
- data/test/apps/rails-3-2/config/environments/development.rb +0 -37
- data/test/apps/rails-3-2/config/environments/production.rb +0 -67
- data/test/apps/rails-3-2/config/environments/test.rb +0 -37
- data/test/apps/rails-3-2/config/initializers/backtrace_silencers.rb +0 -7
- data/test/apps/rails-3-2/config/initializers/inflections.rb +0 -15
- data/test/apps/rails-3-2/config/initializers/mime_types.rb +0 -5
- data/test/apps/rails-3-2/config/initializers/secret_token.rb +0 -7
- data/test/apps/rails-3-2/config/initializers/session_store.rb +0 -8
- data/test/apps/rails-3-2/config/initializers/wrap_parameters.rb +0 -14
- data/test/apps/rails-3-2/config/locales/en.yml +0 -5
- data/test/apps/rails-3-2/config/routes.rb +0 -60
- data/test/apps/rails-3-2/config/spring.rb +0 -7
- data/test/apps/rails-3-2/db/migrate/20121109171227_create_posts.rb +0 -9
- data/test/apps/rails-3-2/db/schema.rb +0 -22
- data/test/apps/rails-3-2/db/seeds.rb +0 -7
- data/test/apps/rails-3-2/lib/assets/.gitkeep +0 -0
- data/test/apps/rails-3-2/lib/tasks/.gitkeep +0 -0
- data/test/apps/rails-3-2/log/.gitkeep +0 -0
- data/test/apps/rails-3-2/public/404.html +0 -26
- data/test/apps/rails-3-2/public/422.html +0 -26
- data/test/apps/rails-3-2/public/500.html +0 -25
- data/test/apps/rails-3-2/public/favicon.ico +0 -0
- data/test/apps/rails-3-2/public/index.html +0 -241
- data/test/apps/rails-3-2/public/robots.txt +0 -5
- data/test/apps/rails-3-2/script/rails +0 -6
- data/test/apps/rails-3-2/spec/dummy_spec.rb +0 -5
- data/test/apps/rails-3-2/test/fixtures/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/fixtures/posts.yml +0 -7
- data/test/apps/rails-3-2/test/functional/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/functional/posts_controller_test.rb +0 -49
- data/test/apps/rails-3-2/test/integration/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/test_helper.rb +0 -13
- data/test/apps/rails-3-2/test/unit/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/unit/helpers/posts_helper_test.rb +0 -4
- data/test/apps/rails-3-2/test/unit/post_test.rb +0 -7
- data/test/apps/rails-3-2/vendor/assets/javascripts/.gitkeep +0 -0
- data/test/apps/rails-3-2/vendor/assets/stylesheets/.gitkeep +0 -0
- data/test/apps/rails-3-2/vendor/plugins/.gitkeep +0 -0
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
## 0.0.11
|
|
2
|
+
|
|
3
|
+
* Added the `rails destroy` command.
|
|
4
|
+
* Global config file in `~/.spring.rb`
|
|
5
|
+
* Added logging for debugging. Specify a log file with the
|
|
6
|
+
`SPRING_LOG` environment variable.
|
|
7
|
+
* Fix hang on "Run `bundle install` to install missing gems"
|
|
8
|
+
* Added hack to make backtraces generated when running a command
|
|
9
|
+
quieter (by stripping out all of the lines relating to spring)
|
|
10
|
+
* Rails 4 is officially supported
|
|
11
|
+
|
|
1
12
|
## 0.0.10
|
|
2
13
|
|
|
3
|
-
* Added `Spring.
|
|
14
|
+
* Added `Spring.watch_method=` configuration option to switch between
|
|
4
15
|
polling and the `listen` gem. Previously, we used the `listen` gem if
|
|
5
16
|
it was available, but this makes the option explicit. Set
|
|
6
|
-
`Spring.
|
|
17
|
+
`Spring.watch_method = :listen` to use the listen gem.
|
|
7
18
|
* Fallback when Process.fork is not available. In such cases, the user
|
|
8
19
|
will not receive the speedup that Spring provides, but won't receive
|
|
9
20
|
an error either.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -7,13 +7,6 @@ problem as [spork](https://github.com/sporkrb/spork),
|
|
|
7
7
|
[zeus](https://github.com/burke/zeus) and
|
|
8
8
|
[commands](https://github.com/rails/commands).
|
|
9
9
|
|
|
10
|
-
I made it because we are having a discussion on the rails core team
|
|
11
|
-
about shipping something to solve this problem with rails. So this is my
|
|
12
|
-
proposal, as working code.
|
|
13
|
-
|
|
14
|
-
(At least I hope it's working code, but this is alpha software at the
|
|
15
|
-
moment. Please do try it and let me know if you hit problems.)
|
|
16
|
-
|
|
17
10
|
## Features
|
|
18
11
|
|
|
19
12
|
Spring is most similar to Zeus, but it's implemented in pure Ruby, and
|
|
@@ -48,6 +41,7 @@ Ruby versions supported:
|
|
|
48
41
|
Rails versions supported:
|
|
49
42
|
|
|
50
43
|
* 3.2
|
|
44
|
+
* 4.0
|
|
51
45
|
|
|
52
46
|
Spring makes extensive use of `Process#fork`, so won't be able to run on
|
|
53
47
|
any platform which doesn't support that (Windows, JRuby).
|
|
@@ -158,7 +152,7 @@ Note: Don't use spring binstubs with `bundle install --binstubs`. If
|
|
|
158
152
|
you do this, spring and bundler will overwrite each other. If _you will_
|
|
159
153
|
not be using a command with spring, use `bundle binstub [GEM]` to
|
|
160
154
|
generate a bundler binstub for that specific gem. If you _will_ be
|
|
161
|
-
using a command with spring, generate a spring binstub
|
|
155
|
+
using a command with spring, generate a spring binstub _instead of_ a
|
|
162
156
|
bundler binstub; spring will run your command inside the bundle anyway.
|
|
163
157
|
|
|
164
158
|
If we edit any of the application files, or test files, the change will
|
|
@@ -222,7 +216,7 @@ Spring stopped.
|
|
|
222
216
|
|
|
223
217
|
The following commands are shipped by default.
|
|
224
218
|
|
|
225
|
-
Custom commands can be specified in
|
|
219
|
+
Custom commands can be specified in the Spring config file. See
|
|
226
220
|
[`lib/spring/commands.rb`](https://github.com/jonleighton/spring/blob/master/lib/spring/commands.rb)
|
|
227
221
|
for examples.
|
|
228
222
|
|
|
@@ -275,7 +269,7 @@ speed-up).
|
|
|
275
269
|
|
|
276
270
|
## Configuration
|
|
277
271
|
|
|
278
|
-
Spring will read `config/spring.rb` for custom settings, described below.
|
|
272
|
+
Spring will read `~/.spring.rb` and `config/spring.rb` for custom settings, described below.
|
|
279
273
|
|
|
280
274
|
### Application root
|
|
281
275
|
|
|
@@ -291,7 +285,7 @@ Spring.application_root = './test/dummy'
|
|
|
291
285
|
### Running code before forking
|
|
292
286
|
|
|
293
287
|
There is no `Spring.before_fork` callback. To run something before the
|
|
294
|
-
fork, you can place it in `config/spring.rb` or in any of the files
|
|
288
|
+
fork, you can place it in `~/.spring.rb` or `config/spring.rb` or in any of the files
|
|
295
289
|
which get run when your application initializers, such as
|
|
296
290
|
`config/application.rb`, `config/environments/*.rb` or
|
|
297
291
|
`config/initializers/*.rb`.
|
|
@@ -343,3 +337,14 @@ You may need to add the [`listen` gem](https://github.com/guard/listen) to your
|
|
|
343
337
|
|
|
344
338
|
Spring needs a tmp directory. This will default to `Rails.root.join('tmp', 'spring')`.
|
|
345
339
|
You can set your own configuration directory by setting the `SPRING_TMP_PATH` environment variable.
|
|
340
|
+
|
|
341
|
+
## Troubleshooting
|
|
342
|
+
|
|
343
|
+
If you want to get more information about what spring is doing, you can
|
|
344
|
+
specify a log file with the `SPRING_LOG` environment variable:
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
spring stop # if spring is already running
|
|
348
|
+
export SPRING_LOG=/tmp/spring.log
|
|
349
|
+
spring rake -T
|
|
350
|
+
```
|
data/lib/spring/application.rb
CHANGED
|
@@ -1,69 +1,107 @@
|
|
|
1
1
|
require "set"
|
|
2
|
-
|
|
3
|
-
require "spring/configuration"
|
|
4
2
|
require "spring/watcher"
|
|
3
|
+
require "thread"
|
|
5
4
|
|
|
6
5
|
module Spring
|
|
7
6
|
class Application
|
|
8
|
-
attr_reader :manager, :watcher
|
|
7
|
+
attr_reader :manager, :watcher, :spring_env
|
|
9
8
|
|
|
10
9
|
def initialize(manager, watcher = Spring.watcher)
|
|
11
|
-
@manager
|
|
12
|
-
@watcher
|
|
13
|
-
@setup
|
|
10
|
+
@manager = manager
|
|
11
|
+
@watcher = watcher
|
|
12
|
+
@setup = Set.new
|
|
13
|
+
@spring_env = Env.new
|
|
14
|
+
@preloaded = false
|
|
15
|
+
@mutex = Mutex.new
|
|
16
|
+
@waiting = 0
|
|
17
|
+
@exiting = false
|
|
14
18
|
|
|
15
19
|
# Workaround for GC bug in Ruby 2 which causes segfaults if watcher.to_io
|
|
16
20
|
# instances get dereffed.
|
|
17
21
|
@fds = [manager, watcher.to_io]
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
def
|
|
24
|
+
def log(message)
|
|
25
|
+
spring_env.log "[application:#{ENV['RAILS_ENV']}] #{message}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def preloaded?
|
|
29
|
+
@preloaded
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def exiting?
|
|
33
|
+
@exiting
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def preload
|
|
37
|
+
log "preloading app"
|
|
38
|
+
|
|
21
39
|
require Spring.application_root_path.join("config", "application")
|
|
22
40
|
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
|
|
41
|
+
# config/environments/test.rb will have config.cache_classes = true. However
|
|
42
|
+
# we want it to be false so that we can reload files. This is a hack to
|
|
43
|
+
# override the effect of config.cache_classes = true. We can then actually
|
|
44
|
+
# set config.cache_classes = false after loading the environment.
|
|
45
|
+
Rails::Application.initializer :initialize_dependency_mechanism, group: :all do
|
|
27
46
|
ActiveSupport::Dependencies.mechanism = :load
|
|
28
47
|
end
|
|
29
48
|
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
# Ensure eager loading does not take place, even though it usually would do
|
|
50
|
+
# in test mode with config.cache_classes = true. Eager loading in this situation
|
|
51
|
+
# just makes the initial run take longer without much gain in subsequent runs,
|
|
52
|
+
# at least in my testing.
|
|
53
|
+
Rails::Application::Finisher.initializers.delete_if { |i| i.name == :eager_load! }
|
|
34
54
|
|
|
35
55
|
require Spring.application_root_path.join("config", "environment")
|
|
36
56
|
|
|
37
|
-
|
|
57
|
+
Rails.application.config.cache_classes = false
|
|
58
|
+
disconnect_database
|
|
38
59
|
|
|
39
60
|
watcher.add loaded_application_features
|
|
40
61
|
watcher.add Spring.gemfile, "#{Spring.gemfile}.lock"
|
|
41
62
|
watcher.add Rails.application.paths["config/initializers"]
|
|
42
63
|
|
|
43
|
-
|
|
64
|
+
@preloaded = true
|
|
44
65
|
end
|
|
45
66
|
|
|
46
67
|
def run
|
|
68
|
+
log "running"
|
|
47
69
|
watcher.start
|
|
48
70
|
|
|
49
71
|
loop do
|
|
50
72
|
IO.select(@fds)
|
|
51
73
|
|
|
52
74
|
if watcher.stale?
|
|
53
|
-
|
|
75
|
+
log "watcher stale; exiting"
|
|
76
|
+
manager.close
|
|
77
|
+
@exiting = true
|
|
78
|
+
try_exit
|
|
79
|
+
sleep
|
|
54
80
|
else
|
|
55
81
|
serve manager.recv_io(UNIXSocket)
|
|
56
82
|
end
|
|
57
83
|
end
|
|
58
84
|
end
|
|
59
85
|
|
|
86
|
+
def try_exit
|
|
87
|
+
@mutex.synchronize {
|
|
88
|
+
exit if exiting? && @waiting == 0
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
60
92
|
def serve(client)
|
|
93
|
+
log "got client"
|
|
61
94
|
manager.puts
|
|
62
95
|
|
|
63
96
|
streams = 3.times.map { client.recv_io }
|
|
97
|
+
[STDOUT, STDERR].zip(streams).each { |a, b| a.reopen(b) }
|
|
98
|
+
|
|
99
|
+
preload unless preloaded?
|
|
100
|
+
|
|
64
101
|
args = JSON.load(client.read(client.gets.to_i))
|
|
65
102
|
command = Spring.command(args.shift)
|
|
66
103
|
|
|
104
|
+
connect_database
|
|
67
105
|
setup command
|
|
68
106
|
|
|
69
107
|
ActionDispatch::Reloader.cleanup!
|
|
@@ -71,14 +109,15 @@ module Spring
|
|
|
71
109
|
|
|
72
110
|
pid = fork {
|
|
73
111
|
Process.setsid
|
|
74
|
-
|
|
112
|
+
STDIN.reopen(streams.last)
|
|
75
113
|
IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
|
|
76
114
|
|
|
77
|
-
|
|
115
|
+
connect_database
|
|
78
116
|
ARGV.replace(args)
|
|
79
117
|
srand
|
|
80
118
|
|
|
81
119
|
invoke_after_fork_callbacks
|
|
120
|
+
shush_backtraces
|
|
82
121
|
|
|
83
122
|
if command.respond_to?(:call)
|
|
84
123
|
command.call
|
|
@@ -92,17 +131,29 @@ module Spring
|
|
|
92
131
|
end
|
|
93
132
|
}
|
|
94
133
|
|
|
134
|
+
disconnect_database
|
|
135
|
+
[STDOUT, STDERR].each { |stream| stream.reopen(spring_env.log_file) }
|
|
136
|
+
|
|
137
|
+
log "forked #{pid}"
|
|
95
138
|
manager.puts pid
|
|
96
139
|
|
|
97
140
|
# Wait in a separate thread so we can run multiple commands at once
|
|
98
141
|
Thread.new {
|
|
142
|
+
@mutex.synchronize { @waiting += 1 }
|
|
143
|
+
|
|
99
144
|
_, status = Process.wait2 pid
|
|
145
|
+
log "#{pid} exited with #{status.exitstatus}"
|
|
146
|
+
|
|
100
147
|
streams.each(&:close)
|
|
101
148
|
client.puts(status.exitstatus)
|
|
102
149
|
client.close
|
|
150
|
+
|
|
151
|
+
@mutex.synchronize { @waiting -= 1 }
|
|
152
|
+
try_exit
|
|
103
153
|
}
|
|
104
154
|
|
|
105
155
|
rescue => e
|
|
156
|
+
log "exception: #{e}"
|
|
106
157
|
streams.each(&:close) if streams
|
|
107
158
|
client.puts(1)
|
|
108
159
|
client.close
|
|
@@ -131,5 +182,31 @@ module Spring
|
|
|
131
182
|
def loaded_application_features
|
|
132
183
|
$LOADED_FEATURES.select { |f| f.start_with?(File.realpath(Rails.root)) }
|
|
133
184
|
end
|
|
185
|
+
|
|
186
|
+
def disconnect_database
|
|
187
|
+
ActiveRecord::Base.remove_connection if defined?(ActiveRecord::Base)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def connect_database
|
|
191
|
+
ActiveRecord::Base.establish_connection if defined?(ActiveRecord::Base)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# This feels very naughty
|
|
195
|
+
def shush_backtraces
|
|
196
|
+
Kernel.module_eval do
|
|
197
|
+
old_raise = Kernel.method(:raise)
|
|
198
|
+
remove_method :raise
|
|
199
|
+
define_method :raise do |*args|
|
|
200
|
+
begin
|
|
201
|
+
old_raise.call(*args)
|
|
202
|
+
ensure
|
|
203
|
+
if $!
|
|
204
|
+
lib = File.expand_path("..", __FILE__)
|
|
205
|
+
$!.backtrace.reject! { |line| line.start_with?(lib) }
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
134
211
|
end
|
|
135
212
|
end
|
|
@@ -13,6 +13,10 @@ module Spring
|
|
|
13
13
|
@mutex = Mutex.new
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def log(message)
|
|
17
|
+
server.log(message)
|
|
18
|
+
end
|
|
19
|
+
|
|
16
20
|
# We're not using @mutex.synchronize to avoid the weird "<internal:prelude>:10"
|
|
17
21
|
# line which messes with backtraces in e.g. rspec
|
|
18
22
|
def synchronize
|
|
@@ -28,9 +32,6 @@ module Spring
|
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def restart
|
|
31
|
-
# Restarting is a background operation. If it fails, we don't want
|
|
32
|
-
# any terminal output. The user will see the output when they next
|
|
33
|
-
# try to run a command.
|
|
34
35
|
start_child(true)
|
|
35
36
|
end
|
|
36
37
|
|
|
@@ -46,10 +47,12 @@ module Spring
|
|
|
46
47
|
rescue Errno::ECONNRESET, Errno::EPIPE
|
|
47
48
|
# The child has died but has not been collected by the wait thread yet,
|
|
48
49
|
# so start a new child and try again.
|
|
50
|
+
log "child dead; starting"
|
|
49
51
|
start
|
|
50
52
|
yield
|
|
51
53
|
end
|
|
52
54
|
else
|
|
55
|
+
log "child not running; starting"
|
|
53
56
|
start
|
|
54
57
|
yield
|
|
55
58
|
end
|
|
@@ -63,8 +66,12 @@ module Spring
|
|
|
63
66
|
child.gets
|
|
64
67
|
end
|
|
65
68
|
|
|
66
|
-
child.gets
|
|
67
|
-
|
|
69
|
+
pid = child.gets
|
|
70
|
+
pid = pid.chomp.to_i if pid
|
|
71
|
+
log "got worker pid #{pid}"
|
|
72
|
+
pid
|
|
73
|
+
rescue Errno::ECONNRESET, Errno::EPIPE => e
|
|
74
|
+
log "#{e} while reading from child; returning no pid"
|
|
68
75
|
nil
|
|
69
76
|
ensure
|
|
70
77
|
client.close
|
|
@@ -76,13 +83,11 @@ module Spring
|
|
|
76
83
|
|
|
77
84
|
private
|
|
78
85
|
|
|
79
|
-
def start_child(
|
|
86
|
+
def start_child(preload = false)
|
|
80
87
|
server.application_starting
|
|
81
88
|
|
|
82
89
|
@child, child_socket = UNIXSocket.pair
|
|
83
90
|
@pid = fork {
|
|
84
|
-
[STDOUT, STDERR].each { |s| s.reopen('/dev/null', 'w') } if silence
|
|
85
|
-
|
|
86
91
|
(ObjectSpace.each_object(IO).to_a - [STDOUT, STDERR, STDIN, child_socket])
|
|
87
92
|
.reject(&:closed?)
|
|
88
93
|
.each(&:close)
|
|
@@ -93,7 +98,9 @@ module Spring
|
|
|
93
98
|
"spring app | #{spring_env.app_name} | started #{distance} ago | #{app_env} mode"
|
|
94
99
|
}
|
|
95
100
|
|
|
96
|
-
Application.new(child_socket)
|
|
101
|
+
app = Application.new(child_socket)
|
|
102
|
+
app.preload if preload
|
|
103
|
+
app.run
|
|
97
104
|
}
|
|
98
105
|
child_socket.close
|
|
99
106
|
end
|
data/lib/spring/client.rb
CHANGED
|
@@ -47,7 +47,7 @@ module Spring
|
|
|
47
47
|
# https://github.com/rubygems/rubygems/pull/435
|
|
48
48
|
|
|
49
49
|
glob = "{#{Gem::Specification.dirs.join(",")}}/spring-*.gemspec"
|
|
50
|
-
candidates = Dir[glob].to_a.
|
|
50
|
+
candidates = Dir[glob].to_a.sort_by { |c| Gem::Version.new(File.basename(c).split(/[-\.]/)[1...-1].join(".")) }
|
|
51
51
|
|
|
52
52
|
spec = Gem::Specification.load(candidates.last)
|
|
53
53
|
|
data/lib/spring/client/rails.rb
CHANGED
|
@@ -3,12 +3,13 @@ require "set"
|
|
|
3
3
|
module Spring
|
|
4
4
|
module Client
|
|
5
5
|
class Rails < Command
|
|
6
|
-
COMMANDS = Set.new %w(console runner generate)
|
|
6
|
+
COMMANDS = Set.new %w(console runner generate destroy)
|
|
7
7
|
|
|
8
8
|
ALIASES = {
|
|
9
9
|
"c" => "console",
|
|
10
10
|
"r" => "runner",
|
|
11
|
-
"g" => "generate"
|
|
11
|
+
"g" => "generate",
|
|
12
|
+
"d" => "destroy"
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
def self.description
|
|
@@ -21,7 +22,11 @@ module Spring
|
|
|
21
22
|
if COMMANDS.include?(command_name)
|
|
22
23
|
Run.call(["rails_#{command_name}", *args.drop(2)])
|
|
23
24
|
else
|
|
24
|
-
|
|
25
|
+
require "spring/configuration"
|
|
26
|
+
ARGV.shift
|
|
27
|
+
Object.const_set(:APP_PATH, Spring.application_root_path.join("config/application").to_s)
|
|
28
|
+
require Spring.application_root_path.join("config/boot")
|
|
29
|
+
require "rails/commands"
|
|
25
30
|
end
|
|
26
31
|
end
|
|
27
32
|
end
|
data/lib/spring/client/run.rb
CHANGED
|
@@ -6,13 +6,15 @@ module Spring
|
|
|
6
6
|
class Run < Command
|
|
7
7
|
FORWARDED_SIGNALS = %w(INT QUIT USR1 USR2 INFO) & Signal.list.keys
|
|
8
8
|
|
|
9
|
+
def log(message)
|
|
10
|
+
env.log "[client] #{message}"
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
def server
|
|
10
14
|
@server ||= UNIXSocket.open(env.socket_name)
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def call
|
|
14
|
-
Spring.verify_environment!
|
|
15
|
-
|
|
16
18
|
boot_server unless env.server_running?
|
|
17
19
|
verify_server_version
|
|
18
20
|
|
|
@@ -28,18 +30,24 @@ module Spring
|
|
|
28
30
|
|
|
29
31
|
def boot_server
|
|
30
32
|
env.socket_path.unlink if env.socket_path.exist?
|
|
31
|
-
|
|
33
|
+
|
|
34
|
+
pid = fork {
|
|
32
35
|
require "spring/server"
|
|
33
36
|
Spring::Server.boot
|
|
34
37
|
}
|
|
35
|
-
|
|
38
|
+
|
|
39
|
+
until env.socket_path.exist?
|
|
40
|
+
_, status = Process.waitpid2(pid, Process::WNOHANG)
|
|
41
|
+
exit status.exitstatus if status
|
|
42
|
+
sleep 0.1
|
|
43
|
+
end
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def verify_server_version
|
|
39
47
|
server_version = server.gets.chomp
|
|
40
48
|
if server_version != env.version
|
|
41
49
|
$stderr.puts <<-ERROR
|
|
42
|
-
There is a version mismatch
|
|
50
|
+
There is a version mismatch between the spring client and the server.
|
|
43
51
|
You should restart the server and make sure to use the same version.
|
|
44
52
|
|
|
45
53
|
CLIENT: #{env.version}, SERVER: #{server_version}
|
|
@@ -55,6 +63,8 @@ ERROR
|
|
|
55
63
|
end
|
|
56
64
|
|
|
57
65
|
def run_command(client, application)
|
|
66
|
+
log "sending command"
|
|
67
|
+
|
|
58
68
|
application.send_io STDOUT
|
|
59
69
|
application.send_io STDERR
|
|
60
70
|
application.send_io STDIN
|
|
@@ -70,9 +80,16 @@ ERROR
|
|
|
70
80
|
client.close
|
|
71
81
|
|
|
72
82
|
if pid && !pid.empty?
|
|
83
|
+
log "got pid: #{pid}"
|
|
84
|
+
|
|
73
85
|
forward_signals(pid.to_i)
|
|
74
|
-
|
|
86
|
+
status = application.read.to_i
|
|
87
|
+
|
|
88
|
+
log "got exit status #{status}"
|
|
89
|
+
|
|
90
|
+
exit status
|
|
75
91
|
else
|
|
92
|
+
log "got no pid"
|
|
76
93
|
exit 1
|
|
77
94
|
end
|
|
78
95
|
ensure
|