spring 1.7.2 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@ module Spring
4
4
  module Client
5
5
  class Stop < Command
6
6
  def self.description
7
- "Stop all spring processes for this project."
7
+ "Stop all Spring processes for this project."
8
8
  end
9
9
 
10
10
  def call
@@ -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 spring extensions which are in the Gemfile
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
@@ -5,7 +5,11 @@ module Spring
5
5
  attr_accessor :application_root, :quiet
6
6
 
7
7
  def gemfile
8
- ENV['BUNDLE_GEMFILE'] || "Gemfile"
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
@@ -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 spring " \
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 spring client to depend on AS, in order to keep its
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
@@ -1,3 +1,3 @@
1
1
  module Spring
2
- VERSION = "1.7.2"
2
+ VERSION = "2.1.1"
3
3
  end
@@ -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(&:exist?)
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
- files << item.realpath.to_s
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
@@ -1,3 +1,5 @@
1
+ require "spring/watcher/abstract"
2
+
1
3
  module Spring
2
4
  module Watcher
3
5
  class Polling < Abstract
@@ -10,7 +12,13 @@ module Spring
10
12
  end
11
13
 
12
14
  def check_stale
13
- synchronize { mark_stale if mtime < compute_mtime }
15
+ synchronize do
16
+ computed = compute_mtime
17
+ if mtime < computed
18
+ debug { "check_stale: mtime=#{mtime.inspect} < computed=#{computed.inspect}" }
19
+ mark_stale
20
+ end
21
+ end
14
22
  end
15
23
 
16
24
  def add(*)
@@ -19,36 +27,67 @@ module Spring
19
27
  end
20
28
 
21
29
  def start
30
+ debug { "start: poller=#{@poller.inspect}" }
22
31
  unless @poller
23
32
  @poller = Thread.new {
24
33
  Thread.current.abort_on_exception = true
25
34
 
26
- loop do
27
- Kernel.sleep latency
28
- check_stale
35
+ begin
36
+ until stale?
37
+ Kernel.sleep latency
38
+ check_stale
39
+ end
40
+ rescue Exception => e
41
+ debug do
42
+ "poller: aborted: #{e.class}: #{e}\n #{e.backtrace.join("\n ")}"
43
+ end
44
+ raise
45
+ ensure
46
+ @poller = nil
29
47
  end
30
48
  }
31
49
  end
32
50
  end
33
51
 
34
52
  def stop
53
+ debug { "stopping poller: #{@poller.inspect}" }
35
54
  if @poller
36
55
  @poller.kill
37
56
  @poller = nil
38
57
  end
39
58
  end
40
59
 
60
+ def running?
61
+ @poller && @poller.alive?
62
+ end
63
+
41
64
  def subjects_changed
42
- @mtime = compute_mtime
65
+ computed = compute_mtime
66
+ debug { "subjects_changed: mtime #{@mtime} -> #{computed}" }
67
+ @mtime = computed
43
68
  end
44
69
 
45
70
  private
46
71
 
47
72
  def compute_mtime
48
- expanded_files.map { |f| File.mtime(f).to_f }.max || 0
49
- rescue Errno::ENOENT
50
- # if a file does no longer exist, the watcher is always stale.
51
- Float::MAX
73
+ expanded_files.map do |f|
74
+ # Get the mtime of symlink targets. Ignore dangling symlinks.
75
+ if File.symlink?(f)
76
+ begin
77
+ File.mtime(f)
78
+ rescue Errno::ENOENT
79
+ 0
80
+ end
81
+ # If a file no longer exists, treat it as changed.
82
+ else
83
+ begin
84
+ File.mtime(f)
85
+ rescue Errno::ENOENT
86
+ debug { "compute_mtime: no longer exists: #{f}" }
87
+ Float::MAX
88
+ end
89
+ end.to_f
90
+ end.max || 0
52
91
  end
53
92
 
54
93
  def expanded_files
metadata CHANGED
@@ -1,31 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 2.1.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-07-01 00:00:00.000000000 Z
11
+ date: 2020-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.2.0
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 4.2.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: bump
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bump
42
+ name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -91,12 +91,6 @@ files:
91
91
  - lib/spring/process_title_updater.rb
92
92
  - lib/spring/server.rb
93
93
  - lib/spring/sid.rb
94
- - lib/spring/test.rb
95
- - lib/spring/test/acceptance_test.rb
96
- - lib/spring/test/application.rb
97
- - lib/spring/test/application_generator.rb
98
- - lib/spring/test/rails_version.rb
99
- - lib/spring/test/watcher_test.rb
100
94
  - lib/spring/version.rb
101
95
  - lib/spring/watcher.rb
102
96
  - lib/spring/watcher/abstract.rb
@@ -113,15 +107,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
107
  requirements:
114
108
  - - ">="
115
109
  - !ruby/object:Gem::Version
116
- version: '0'
110
+ version: 2.4.0
117
111
  required_rubygems_version: !ruby/object:Gem::Requirement
118
112
  requirements:
119
113
  - - ">="
120
114
  - !ruby/object:Gem::Version
121
115
  version: '0'
122
116
  requirements: []
123
- rubyforge_project:
124
- rubygems_version: 2.5.1
117
+ rubygems_version: 3.0.3
125
118
  signing_key:
126
119
  specification_version: 4
127
120
  summary: Rails application preloader
@@ -1,18 +0,0 @@
1
- require "active_support"
2
- require "active_support/test_case"
3
-
4
- ActiveSupport.test_order = :random
5
-
6
- module Spring
7
- module Test
8
- class << self
9
- attr_accessor :root
10
- end
11
-
12
- require "spring/test/application"
13
- require "spring/test/application_generator"
14
- require "spring/test/rails_version"
15
- require "spring/test/watcher_test"
16
- require "spring/test/acceptance_test"
17
- end
18
- end
@@ -1,539 +0,0 @@
1
- require "io/wait"
2
- require "timeout"
3
- require "spring/sid"
4
- require "spring/client"
5
- require "active_support/core_ext/string/strip"
6
-
7
- module Spring
8
- module Test
9
- class AcceptanceTest < ActiveSupport::TestCase
10
- runnables.delete self # prevent Minitest running this class
11
-
12
- DEFAULT_SPEEDUP = 0.8
13
-
14
- def rails_version
15
- ENV['RAILS_VERSION'] || '~> 4.2.0'
16
- end
17
-
18
- # Extension point for spring-watchers-listen
19
- def generator_klass
20
- Spring::Test::ApplicationGenerator
21
- end
22
-
23
- def generator
24
- @@generator ||= generator_klass.new(rails_version)
25
- end
26
-
27
- def app
28
- @app ||= Spring::Test::Application.new("#{Spring::Test.root}/apps/tmp")
29
- end
30
-
31
- def spring_env
32
- app.spring_env
33
- end
34
-
35
- def assert_output(artifacts, expected)
36
- expected.each do |stream, output|
37
- assert artifacts[stream].include?(output),
38
- "expected #{stream} to include '#{output}'.\n\n#{app.debug(artifacts)}"
39
- end
40
- end
41
-
42
- def assert_success(command, expected_output = nil)
43
- artifacts = app.run(*Array(command))
44
- assert artifacts[:status].success?, "expected successful exit status\n\n#{app.debug(artifacts)}"
45
- assert_output artifacts, expected_output if expected_output
46
- end
47
-
48
- def assert_failure(command, expected_output = nil)
49
- artifacts = app.run(*Array(command))
50
- assert !artifacts[:status].success?, "expected unsuccessful exit status\n\n#{app.debug(artifacts)}"
51
- assert_output artifacts, expected_output if expected_output
52
- end
53
-
54
- def refute_output_includes(command, not_expected)
55
- artifacts = app.run(*Array(command))
56
- not_expected.each do |stream, output|
57
- assert !artifacts[stream].include?(output),
58
- "expected #{stream} to not include '#{output}'.\n\n#{app.debug(artifacts)}"
59
- end
60
- end
61
-
62
- def assert_speedup(ratio = DEFAULT_SPEEDUP)
63
- if ENV['CI']
64
- yield
65
- else
66
- app.with_timing do
67
- yield
68
- assert app.timing_ratio < ratio, "#{app.last_time} was not less than #{ratio} of #{app.first_time}"
69
- end
70
- end
71
- end
72
-
73
- def without_gem(name)
74
- gem_home = app.gem_home.join('gems')
75
- FileUtils.mv(gem_home.join(name), app.root)
76
- yield
77
- ensure
78
- FileUtils.mv(app.root.join(name), gem_home)
79
- end
80
-
81
- setup do
82
- generator.generate_if_missing
83
- generator.install_spring
84
- generator.copy_to(app.root)
85
- end
86
-
87
- teardown do
88
- app.stop_spring
89
- end
90
-
91
- test "basic" do
92
- assert_speedup do
93
- 2.times { app.run app.spring_test_command }
94
- end
95
- end
96
-
97
- test "help message when called without arguments" do
98
- assert_success "bin/spring", stdout: 'Usage: spring COMMAND [ARGS]'
99
- assert spring_env.server_running?
100
- end
101
-
102
- test "shows help" do
103
- assert_success "bin/spring help", stdout: 'Usage: spring COMMAND [ARGS]'
104
- assert_success "bin/spring -h", stdout: 'Usage: spring COMMAND [ARGS]'
105
- assert_success "bin/spring --help", stdout: 'Usage: spring COMMAND [ARGS]'
106
- refute spring_env.server_running?
107
- end
108
-
109
- test "tells the user that spring is being used when used automatically via binstubs" do
110
- assert_success "bin/rails runner ''", stderr: "Running via Spring preloader in process"
111
- assert_success app.spring_test_command, stderr: "Running via Spring preloader in process"
112
- end
113
-
114
- test "does not tell the user that spring is being used when used automatically via binstubs but quiet is enabled" do
115
- File.write("#{app.user_home}/.spring.rb", "Spring.quiet = true")
116
- assert_success "bin/rails runner ''"
117
- refute_output_includes "bin/rails runner ''", stderr: 'Running via Spring preloader in process'
118
- end
119
-
120
- test "test changes are picked up" do
121
- assert_speedup do
122
- assert_success app.spring_test_command, stdout: "0 failures"
123
-
124
- File.write(app.test, app.test.read.sub("get :index", "raise 'omg'"))
125
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
126
- end
127
- end
128
-
129
- test "code changes are picked up" do
130
- assert_speedup do
131
- assert_success app.spring_test_command, stdout: "0 failures"
132
-
133
- File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
134
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
135
- end
136
- end
137
-
138
- test "code changes in pre-referenced app files are picked up" do
139
- File.write(app.path("config/initializers/load_posts_controller.rb"), "PostsController\n")
140
-
141
- assert_speedup do
142
- assert_success app.spring_test_command, stdout: "0 failures"
143
-
144
- File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
145
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
146
- end
147
- end
148
-
149
- test "app gets reloaded when preloaded files change" do
150
- assert_success app.spring_test_command
151
-
152
- File.write(app.application_config, app.application_config.read + <<-RUBY.strip_heredoc)
153
- class Foo
154
- def self.omg
155
- raise "omg"
156
- end
157
- end
158
- RUBY
159
- File.write(app.test, app.test.read.sub("get :index", "Foo.omg"))
160
-
161
- app.await_reload
162
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
163
- end
164
-
165
- test "app gets reloaded even with a ton of boot output" do
166
- limit = UNIXSocket.pair.first.getsockopt(:SOCKET, :SNDBUF).int
167
-
168
- assert_success app.spring_test_command
169
- File.write(app.path("config/initializers/verbose.rb"), "#{limit}.times { puts 'x' }")
170
-
171
- app.await_reload
172
- assert_success app.spring_test_command
173
- end
174
-
175
- test "app recovers when a boot-level error is introduced" do
176
- config = app.application_config.read
177
-
178
- assert_success app.spring_test_command
179
-
180
- File.write(app.application_config, "#{config}\nomg")
181
- app.await_reload
182
-
183
- assert_failure app.spring_test_command
184
-
185
- File.write(app.application_config, config)
186
- assert_success app.spring_test_command
187
- end
188
-
189
- test "stop command kills server" do
190
- app.run app.spring_test_command
191
- assert spring_env.server_running?, "The server should be running but it isn't"
192
-
193
- assert_success "bin/spring stop"
194
- assert !spring_env.server_running?, "The server should not be running but it is"
195
- end
196
-
197
- test "custom commands" do
198
- # Start spring before setting up the command, to test that it gracefully upgrades itself
199
- assert_success "bin/rails runner ''"
200
-
201
- File.write(app.spring_config, <<-RUBY.strip_heredoc)
202
- class CustomCommand
203
- def call
204
- puts "omg"
205
- end
206
-
207
- def exec_name
208
- "rake"
209
- end
210
- end
211
-
212
- Spring.register_command "custom", CustomCommand.new
213
- RUBY
214
-
215
- assert_success "bin/spring custom", stdout: "omg"
216
-
217
- assert_success "bin/spring binstub custom"
218
- assert_success "bin/custom", stdout: "omg"
219
-
220
- app.env["DISABLE_SPRING"] = "1"
221
- assert_success %{bin/custom -e 'puts "foo"'}, stdout: "foo"
222
- end
223
-
224
- test "binstub" do
225
- assert_success "bin/rails server --help", stdout: "Usage: rails server" # rails command fallback
226
-
227
- assert_success "#{app.spring} binstub rake", stdout: "bin/rake: spring already present"
228
-
229
- assert_success "#{app.spring} binstub --remove rake", stdout: "bin/rake: spring removed"
230
- assert !app.path("bin/rake").read.include?(Spring::Client::Binstub::LOADER)
231
- assert_success "bin/rake -T", stdout: "rake db:migrate"
232
- end
233
-
234
- test "binstub remove all" do
235
- assert_success "bin/spring binstub --remove --all"
236
- refute File.exist?(app.path("bin/spring"))
237
- end
238
-
239
- test "binstub when spring gem is missing" do
240
- without_gem "spring-#{Spring::VERSION}" do
241
- File.write(app.gemfile, app.gemfile.read.gsub(/gem 'spring.*/, ""))
242
- assert_success "bin/rake -T", stdout: "rake db:migrate"
243
- end
244
- end
245
-
246
- test "binstub when spring binary is missing" do
247
- begin
248
- File.rename(app.path("bin/spring"), app.path("bin/spring.bak"))
249
- assert_success "bin/rake -T", stdout: "rake db:migrate"
250
- ensure
251
- File.rename(app.path("bin/spring.bak"), app.path("bin/spring"))
252
- end
253
- end
254
-
255
- test "binstub upgrade with old binstub" do
256
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
257
- #!/usr/bin/env ruby
258
-
259
- if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
260
- exec "bundle", "exec", "rake", *ARGV
261
- else
262
- ARGV.unshift "rake"
263
- load Gem.bin_path("spring", "spring")
264
- end
265
- RUBY
266
-
267
- File.write(app.path("bin/rails"), <<-RUBY.strip_heredoc)
268
- #!/usr/bin/env ruby
269
-
270
- if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
271
- APP_PATH = File.expand_path('../../config/application', __FILE__)
272
- require_relative '../config/boot'
273
- require 'rails/commands'
274
- else
275
- ARGV.unshift "rails"
276
- load Gem.bin_path("spring", "spring")
277
- end
278
- RUBY
279
-
280
- assert_success "bin/spring binstub --all", stdout: "upgraded"
281
-
282
- expected = <<-RUBY.gsub(/^ /, "")
283
- #!/usr/bin/env ruby
284
- #{Spring::Client::Binstub::LOADER.strip}
285
- require 'bundler/setup'
286
- load Gem.bin_path('rake', 'rake')
287
- RUBY
288
- assert_equal expected, app.path("bin/rake").read
289
-
290
- expected = <<-RUBY.gsub(/^ /, "")
291
- #!/usr/bin/env ruby
292
- #{Spring::Client::Binstub::LOADER.strip}
293
- APP_PATH = File.expand_path('../../config/application', __FILE__)
294
- require_relative '../config/boot'
295
- require 'rails/commands'
296
- RUBY
297
- assert_equal expected, app.path("bin/rails").read
298
- end
299
-
300
- test "binstub upgrade with new binstub variations" do
301
- expected = <<-RUBY.gsub(/^ /, "")
302
- #!/usr/bin/env ruby
303
- #{Spring::Client::Binstub::LOADER.strip}
304
- require 'bundler/setup'
305
- load Gem.bin_path('rake', 'rake')
306
- RUBY
307
-
308
- # older variation with double quotes
309
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
310
- #!/usr/bin/env ruby
311
- begin
312
- load File.expand_path("../spring", __FILE__)
313
- rescue LoadError
314
- end
315
- require 'bundler/setup'
316
- load Gem.bin_path('rake', 'rake')
317
- RUBY
318
-
319
- assert_success "bin/spring binstub rake", stdout: "bin/rake: upgraded"
320
- assert_equal expected, app.path("bin/rake").read
321
-
322
- # newer variation with single quotes
323
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
324
- #!/usr/bin/env ruby
325
- begin
326
- load File.expand_path('../spring', __FILE__)
327
- rescue LoadError
328
- end
329
- require 'bundler/setup'
330
- load Gem.bin_path('rake', 'rake')
331
- RUBY
332
-
333
- assert_success "bin/spring binstub rake", stdout: "bin/rake: upgraded"
334
- assert_equal expected, app.path("bin/rake").read
335
-
336
- # newer variation which checks end of exception message
337
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
338
- #!/usr/bin/env ruby
339
- begin
340
- spring_bin_path = File.expand_path('../spring', __FILE__)
341
- load spring_bin_path
342
- rescue LoadError => e
343
- raise unless e.message.end_with? spring_bin_path, 'spring/binstub'
344
- end
345
- require 'bundler/setup'
346
- load Gem.bin_path('rake', 'rake')
347
- RUBY
348
-
349
- assert_success "bin/spring binstub rake", stdout: "bin/rake: upgraded"
350
- assert_equal expected, app.path("bin/rake").read
351
- end
352
-
353
- test "binstub remove with new binstub variations" do
354
- # older variation with double quotes
355
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
356
- #!/usr/bin/env ruby
357
- begin
358
- load File.expand_path("../spring", __FILE__)
359
- rescue LoadError
360
- end
361
- require 'bundler/setup'
362
- load Gem.bin_path('rake', 'rake')
363
- RUBY
364
-
365
- # newer variation with single quotes
366
- File.write(app.path("bin/rails"), <<-RUBY.strip_heredoc)
367
- #!/usr/bin/env ruby
368
- begin
369
- load File.expand_path('../spring', __FILE__)
370
- rescue LoadError
371
- end
372
- APP_PATH = File.expand_path('../../config/application', __FILE__)
373
- require_relative '../config/boot'
374
- require 'rails/commands'
375
- RUBY
376
-
377
- assert_success "bin/spring binstub --remove rake", stdout: "bin/rake: spring removed"
378
- assert_success "bin/spring binstub --remove rails", stdout: "bin/rails: spring removed"
379
-
380
- expected = <<-RUBY.strip_heredoc
381
- #!/usr/bin/env ruby
382
- require 'bundler/setup'
383
- load Gem.bin_path('rake', 'rake')
384
- RUBY
385
- assert_equal expected, app.path("bin/rake").read
386
-
387
- expected = <<-RUBY.strip_heredoc
388
- #!/usr/bin/env ruby
389
- APP_PATH = File.expand_path('../../config/application', __FILE__)
390
- require_relative '../config/boot'
391
- require 'rails/commands'
392
- RUBY
393
- assert_equal expected, app.path("bin/rails").read
394
- end
395
-
396
- test "after fork callback" do
397
- File.write(app.spring_config, "Spring.after_fork { puts '!callback!' }")
398
- assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
399
- end
400
-
401
- test "global config file evaluated" do
402
- File.write("#{app.user_home}/.spring.rb", "Spring.after_fork { puts '!callback!' }")
403
- assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
404
- end
405
-
406
- test "can define client tasks" do
407
- File.write("#{app.spring_client_config}", <<-RUBY)
408
- Spring::Client::COMMANDS["foo"] = lambda { |args| puts "bar -- \#{args.inspect}" }
409
- RUBY
410
- assert_success "bin/spring foo --baz", stdout: "bar -- [\"foo\", \"--baz\"]\n"
411
- end
412
-
413
- test "missing config/application.rb" do
414
- app.application_config.delete
415
- assert_failure "bin/rake -T", stderr: "unable to find your config/application.rb"
416
- end
417
-
418
- test "piping" do
419
- assert_success "bin/rake -T | grep db", stdout: "rake db:migrate"
420
- end
421
-
422
- test "status" do
423
- assert_success "bin/spring status", stdout: "Spring is not running"
424
- assert_success "bin/rails runner ''"
425
- assert_success "bin/spring status", stdout: "Spring is running"
426
- end
427
-
428
- test "runner command sets Rails environment from command-line options" do
429
- assert_success "bin/rails runner -e test 'puts Rails.env'", stdout: "test"
430
- assert_success "bin/rails runner --environment=test 'puts Rails.env'", stdout: "test"
431
- end
432
-
433
- test "forcing rails env via environment variable" do
434
- app.env['RAILS_ENV'] = 'test'
435
- assert_success "bin/rake -p 'Rails.env'", stdout: "test"
436
- end
437
-
438
- test "setting env vars with rake" do
439
- File.write(app.path("lib/tasks/env.rake"), <<-RUBY.strip_heredoc)
440
- task :print_rails_env => :environment do
441
- puts Rails.env
442
- end
443
-
444
- task :print_env do
445
- ENV.each { |k, v| puts "\#{k}=\#{v}" }
446
- end
447
-
448
- task(:default).clear.enhance [:print_rails_env]
449
- RUBY
450
-
451
- assert_success "bin/rake RAILS_ENV=test print_rails_env", stdout: "test"
452
- assert_success "bin/rake FOO=bar print_env", stdout: "FOO=bar"
453
- assert_success "bin/rake", stdout: "test"
454
- end
455
-
456
- test "changing the Gemfile works" do
457
- assert_success %(bin/rails runner 'require "sqlite3"')
458
-
459
- File.write(app.gemfile, app.gemfile.read.sub(%{gem 'sqlite3'}, %{# gem 'sqlite3'}))
460
- app.await_reload
461
-
462
- assert_failure %(bin/rails runner 'require "sqlite3"'), stderr: "sqlite3"
463
- end
464
-
465
- test "changing the Gemfile works when spring calls into itself" do
466
- File.write(app.path("script.rb"), <<-RUBY.strip_heredoc)
467
- gemfile = Rails.root.join("Gemfile")
468
- File.write(gemfile, "\#{gemfile.read}gem 'text'\\n")
469
- Bundler.with_clean_env do
470
- system(#{app.env.inspect}, "bundle install")
471
- end
472
- output = `\#{Rails.root.join('bin/rails')} runner 'require "text"; puts "done";'`
473
- exit output.include? "done\n"
474
- RUBY
475
-
476
- assert_success [%(bin/rails runner 'load Rails.root.join("script.rb")'), timeout: 60]
477
- end
478
-
479
- test "changing the environment between runs" do
480
- File.write(app.application_config, "#{app.application_config.read}\nENV['BAR'] = 'bar'")
481
-
482
- app.env["OMG"] = "1"
483
- app.env["FOO"] = "1"
484
- app.env["RUBYOPT"] = "-rubygems"
485
-
486
- assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "1"
487
- assert_success %(bin/rails runner 'p ENV["BAR"]'), stdout: "bar"
488
- assert_success %(bin/rails runner 'p ENV.key?("BUNDLE_GEMFILE")'), stdout: "true"
489
- assert_success %(bin/rails runner 'p ENV["RUBYOPT"]'), stdout: "bundler"
490
-
491
- app.env["OMG"] = "2"
492
- app.env.delete "FOO"
493
-
494
- assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "2"
495
- assert_success %(bin/rails runner 'p ENV.key?("FOO")'), stdout: "false"
496
- end
497
-
498
- test "Kernel.raise remains private" do
499
- expr = "p Kernel.private_instance_methods.include?(:raise)"
500
- assert_success %(bin/rails runner '#{expr}'), stdout: "true"
501
- end
502
-
503
- test "custom bundle path" do
504
- bundle_path = app.path(".bundle/#{Bundler.ruby_scope}")
505
- bundle_path.dirname.mkpath
506
-
507
- FileUtils.cp_r "#{app.gem_home}/", bundle_path.to_s
508
-
509
- app.run! "bundle install --path .bundle --clean --local"
510
-
511
- assert_speedup do
512
- 2.times { assert_success "bundle exec rails runner ''" }
513
- end
514
- end
515
-
516
- test "booting a foreground server" do
517
- FileUtils.cd(app.root) do
518
- assert !spring_env.server_running?
519
- assert_success "bin/spring server &"
520
-
521
- Timeout.timeout(10) do
522
- sleep 0.1 until spring_env.server_running? && spring_env.socket_path.exist?
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
537
- end
538
- end
539
- end