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.
- checksums.yaml +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +24 -18
- data/lib/spring/application.rb +47 -9
- data/lib/spring/application_manager.rb +4 -2
- data/lib/spring/client/binstub.rb +16 -19
- data/lib/spring/client/help.rb +1 -1
- data/lib/spring/client/rails.rb +1 -1
- data/lib/spring/client/run.rb +16 -2
- data/lib/spring/client/stop.rb +1 -1
- data/lib/spring/commands.rb +1 -1
- data/lib/spring/configuration.rb +5 -1
- data/lib/spring/errors.rb +1 -1
- data/lib/spring/process_title_updater.rb +1 -1
- data/lib/spring/version.rb +1 -1
- data/lib/spring/watcher/abstract.rb +33 -2
- data/lib/spring/watcher/polling.rb +48 -9
- metadata +11 -18
- data/lib/spring/test.rb +0 -18
- data/lib/spring/test/acceptance_test.rb +0 -539
- data/lib/spring/test/application.rb +0 -222
- data/lib/spring/test/application_generator.rb +0 -139
- data/lib/spring/test/rails_version.rb +0 -40
- data/lib/spring/test/watcher_test.rb +0 -167
data/lib/spring/client/stop.rb
CHANGED
data/lib/spring/commands.rb
CHANGED
@@ -32,7 +32,7 @@ module Spring
|
|
32
32
|
# then we need to be under bundler.
|
33
33
|
require "bundler/setup"
|
34
34
|
|
35
|
-
# Auto-require any
|
35
|
+
# Auto-require any Spring extensions which are in the Gemfile
|
36
36
|
Gem::Specification.map(&:name).grep(/^spring-/).each do |command|
|
37
37
|
begin
|
38
38
|
require command
|
data/lib/spring/configuration.rb
CHANGED
@@ -5,7 +5,11 @@ module Spring
|
|
5
5
|
attr_accessor :application_root, :quiet
|
6
6
|
|
7
7
|
def gemfile
|
8
|
-
|
8
|
+
if /\s1.9.[0-9]/ === Bundler.ruby_scope.gsub(/[\/\s]+/,'')
|
9
|
+
ENV["BUNDLE_GEMFILE"] || "Gemfile"
|
10
|
+
else
|
11
|
+
Bundler.default_gemfile
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def after_fork_callbacks
|
data/lib/spring/errors.rb
CHANGED
@@ -24,7 +24,7 @@ module Spring
|
|
24
24
|
|
25
25
|
def message
|
26
26
|
"Spring was unable to find your config/application.rb file. " \
|
27
|
-
"Your project root was detected at #{project_root}, so
|
27
|
+
"Your project root was detected at #{project_root}, so Spring " \
|
28
28
|
"looked for #{project_root}/config/application.rb but it doesn't exist. You can " \
|
29
29
|
"configure the root of your application by setting Spring.application_root in " \
|
30
30
|
"config/spring.rb."
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spring
|
2
2
|
# Yes, I know this reimplements a bunch of stuff in Active Support, but
|
3
|
-
# I don't want the
|
3
|
+
# I don't want the Spring client to depend on AS, in order to keep its
|
4
4
|
# load time down.
|
5
5
|
class ProcessTitleUpdater
|
6
6
|
SECOND = 1
|
data/lib/spring/version.rb
CHANGED
@@ -23,9 +23,21 @@ module Spring
|
|
23
23
|
@directories = Set.new
|
24
24
|
@stale = false
|
25
25
|
@listeners = []
|
26
|
+
|
27
|
+
@on_debug = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_debug(&block)
|
31
|
+
@on_debug = block
|
32
|
+
end
|
33
|
+
|
34
|
+
def debug
|
35
|
+
@on_debug.call(yield) if @on_debug
|
26
36
|
end
|
27
37
|
|
28
38
|
def add(*items)
|
39
|
+
debug { "watcher: add: #{items.inspect}" }
|
40
|
+
|
29
41
|
items = items.flatten.map do |item|
|
30
42
|
item = Pathname.new(item)
|
31
43
|
|
@@ -36,14 +48,30 @@ module Spring
|
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
39
|
-
items = items.select
|
51
|
+
items = items.select do |item|
|
52
|
+
if item.symlink?
|
53
|
+
item.readlink.exist?.tap do |exists|
|
54
|
+
if !exists
|
55
|
+
debug { "add: ignoring dangling symlink: #{item.inspect} -> #{item.readlink.inspect}" }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
item.exist?
|
60
|
+
end
|
61
|
+
end
|
40
62
|
|
41
63
|
synchronize {
|
42
64
|
items.each do |item|
|
43
65
|
if item.directory?
|
44
66
|
directories << item.realpath.to_s
|
45
67
|
else
|
46
|
-
|
68
|
+
begin
|
69
|
+
files << item.realpath.to_s
|
70
|
+
rescue Errno::ENOENT
|
71
|
+
# Race condition. Ignore symlinks whose target was removed
|
72
|
+
# since the check above, or are deeply chained.
|
73
|
+
debug { "add: ignoring now-dangling symlink: #{item.inspect} -> #{item.readlink.inspect}" }
|
74
|
+
end
|
47
75
|
end
|
48
76
|
end
|
49
77
|
|
@@ -56,16 +84,19 @@ module Spring
|
|
56
84
|
end
|
57
85
|
|
58
86
|
def on_stale(&block)
|
87
|
+
debug { "added listener: #{block.inspect}" }
|
59
88
|
@listeners << block
|
60
89
|
end
|
61
90
|
|
62
91
|
def mark_stale
|
63
92
|
return if stale?
|
64
93
|
@stale = true
|
94
|
+
debug { "marked stale, calling listeners: listeners=#{@listeners.inspect}" }
|
65
95
|
@listeners.each(&:call)
|
66
96
|
end
|
67
97
|
|
68
98
|
def restart
|
99
|
+
debug { "restarting" }
|
69
100
|
stop
|
70
101
|
start
|
71
102
|
end
|
@@ -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
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
49
|
-
|
50
|
-
|
51
|
-
|
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.
|
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:
|
11
|
+
date: 2020-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
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:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
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:
|
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:
|
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
|
-
|
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
|
data/lib/spring/test.rb
DELETED
@@ -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
|