spring 1.7.2 → 2.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.
@@ -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