zeus 0.15.10 → 0.15.12
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 +4 -4
- data/Gemfile.lock +15 -15
- data/build/zeus-darwin-amd64 +0 -0
- data/build/zeus-linux-386 +0 -0
- data/build/zeus-linux-amd64 +0 -0
- data/examples/custom_plan/cucumber_plan.rb +1 -0
- data/lib/zeus.rb +18 -26
- data/lib/zeus/load_tracking.rb +39 -33
- data/lib/zeus/version.rb +1 -1
- data/man/build/zeus +1 -1
- data/man/build/zeus-init +1 -1
- data/man/build/zeus-init.txt +1 -1
- data/man/build/zeus-start +1 -1
- data/man/build/zeus-start.txt +1 -1
- data/man/build/zeus.txt +1 -1
- data/spec/assets/boot.rb +2 -0
- data/spec/assets/boot_delayed.rb +2 -0
- data/spec/load_tracking_spec.rb +41 -49
- data/spec/zeus_spec.rb +85 -0
- data/zeus.gemspec +1 -1
- metadata +7 -5
- data/spec/assets/exit.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0b6652301511b13e06a1b60dbb808cc5e2161a2
|
4
|
+
data.tar.gz: 4898481f7b4acec5828dfa25a2351d31b5f166b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 187015a45fdb160f364da8c1ee05de7577642e79d114ca0982f5409cc582cb02bb764a0b0074750d72fa492dd52782ad1b77580691963c1fb83900d13d703345
|
7
|
+
data.tar.gz: c837a56c542b72057a3dbc324bf42dbc4f8cd75080f6b211e01f7e83053d3f9f15470eedfc40310d313e2399a3a53f8382d28c9ac38a95ab21c86602b3c90729
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
zeus (0.15.
|
4
|
+
zeus (0.15.12)
|
5
5
|
method_source (>= 0.6.7)
|
6
6
|
|
7
7
|
GEM
|
@@ -10,24 +10,24 @@ GEM
|
|
10
10
|
coderay (1.1.1)
|
11
11
|
diff-lcs (1.2.5)
|
12
12
|
method_source (0.8.2)
|
13
|
-
pry (0.10.
|
13
|
+
pry (0.10.4)
|
14
14
|
coderay (~> 1.1.0)
|
15
15
|
method_source (~> 0.8.1)
|
16
16
|
slop (~> 3.4)
|
17
|
-
rake (
|
18
|
-
rspec (3.
|
19
|
-
rspec-core (~> 3.
|
20
|
-
rspec-expectations (~> 3.
|
21
|
-
rspec-mocks (~> 3.
|
22
|
-
rspec-core (3.
|
23
|
-
rspec-support (~> 3.
|
24
|
-
rspec-expectations (3.
|
17
|
+
rake (12.0.0)
|
18
|
+
rspec (3.5.0)
|
19
|
+
rspec-core (~> 3.5.0)
|
20
|
+
rspec-expectations (~> 3.5.0)
|
21
|
+
rspec-mocks (~> 3.5.0)
|
22
|
+
rspec-core (3.5.4)
|
23
|
+
rspec-support (~> 3.5.0)
|
24
|
+
rspec-expectations (3.5.0)
|
25
25
|
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
-
rspec-support (~> 3.
|
27
|
-
rspec-mocks (3.
|
26
|
+
rspec-support (~> 3.5.0)
|
27
|
+
rspec-mocks (3.5.0)
|
28
28
|
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
-
rspec-support (~> 3.
|
30
|
-
rspec-support (3.
|
29
|
+
rspec-support (~> 3.5.0)
|
30
|
+
rspec-support (3.5.0)
|
31
31
|
slop (3.6.0)
|
32
32
|
|
33
33
|
PLATFORMS
|
@@ -41,4 +41,4 @@ DEPENDENCIES
|
|
41
41
|
zeus!
|
42
42
|
|
43
43
|
BUNDLED WITH
|
44
|
-
1.
|
44
|
+
1.13.7
|
data/build/zeus-darwin-amd64
CHANGED
Binary file
|
data/build/zeus-linux-386
CHANGED
Binary file
|
data/build/zeus-linux-amd64
CHANGED
Binary file
|
data/lib/zeus.rb
CHANGED
@@ -69,7 +69,9 @@ module Zeus
|
|
69
69
|
local.send_io(feature_pipe_r)
|
70
70
|
feature_pipe_r.close
|
71
71
|
|
72
|
-
|
72
|
+
Zeus::LoadTracking.set_feature_pipe(feature_pipe_w)
|
73
|
+
|
74
|
+
run_action(local, identifier)
|
73
75
|
|
74
76
|
# We are now 'connected'. From this point, we may receive requests to fork.
|
75
77
|
children = Set.new
|
@@ -97,10 +99,16 @@ module Zeus
|
|
97
99
|
elsif code == "S"
|
98
100
|
# Child, supposed to start another step:
|
99
101
|
@parent_pid = forked_from
|
102
|
+
|
103
|
+
Zeus::LoadTracking.clear_feature_pipe
|
104
|
+
|
100
105
|
throw(:boot_step, ident.to_sym)
|
101
106
|
else
|
102
107
|
# Child, supposed to run a command:
|
103
108
|
@parent_pid = forked_from
|
109
|
+
|
110
|
+
Zeus::LoadTracking.clear_feature_pipe
|
111
|
+
|
104
112
|
return [ident.to_sym, local]
|
105
113
|
end
|
106
114
|
end
|
@@ -176,12 +184,6 @@ module Zeus
|
|
176
184
|
}
|
177
185
|
end
|
178
186
|
|
179
|
-
def notify_features(pipe, features)
|
180
|
-
features.each do |t|
|
181
|
-
pipe.puts t
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
187
|
def report_error_to_master(local, error)
|
186
188
|
str = "R:"
|
187
189
|
str << "#{error.backtrace[0]}: #{error.message} (#{error.class})\n"
|
@@ -192,28 +194,18 @@ module Zeus
|
|
192
194
|
local.write str
|
193
195
|
end
|
194
196
|
|
195
|
-
def run_action(socket, identifier
|
197
|
+
def run_action(socket, identifier)
|
196
198
|
# Now we run the action and report its success/fail status to the master.
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
if err
|
203
|
-
# If we received an error, report features to the master syncronously.
|
204
|
-
# We need to do this before reporting the error to the master
|
205
|
-
# otherwise it will kill us before we can report features.
|
206
|
-
begin
|
207
|
-
notify_features(feature_pipe_w, features)
|
208
|
-
feature_pipe_w.close
|
209
|
-
ensure
|
210
|
-
report_error_to_master(socket, err)
|
199
|
+
begin
|
200
|
+
Zeus::LoadTracking.track_features_loaded_by do
|
201
|
+
plan.after_fork unless identifier == :boot
|
202
|
+
plan.send(identifier)
|
211
203
|
end
|
212
|
-
|
213
|
-
# If we booted successfully, report features in a new thread
|
214
|
-
# so we can immediately begin listening for commands.
|
204
|
+
|
215
205
|
socket.write "R:OK\0"
|
216
|
-
|
206
|
+
rescue => err
|
207
|
+
report_error_to_master(socket, err)
|
208
|
+
raise
|
217
209
|
end
|
218
210
|
end
|
219
211
|
end
|
data/lib/zeus/load_tracking.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
module Zeus
|
2
2
|
class LoadTracking
|
3
3
|
class << self
|
4
|
-
def
|
5
|
-
|
4
|
+
def add_feature(file)
|
5
|
+
full_path = File.expand_path(file)
|
6
|
+
return unless File.exist?(full_path) && @feature_pipe
|
7
|
+
notify_features([full_path])
|
8
|
+
end
|
9
|
+
|
10
|
+
# Internal: This should only be called by Zeus code
|
11
|
+
def track_features_loaded_by
|
12
|
+
old_features = $LOADED_FEATURES.dup
|
6
13
|
|
7
14
|
# Catch exceptions so we can determine the features
|
8
15
|
# that were being loaded at the time of the exception.
|
@@ -14,48 +21,47 @@ module Zeus
|
|
14
21
|
# the error is not in the backtrace, only the error message.
|
15
22
|
match = /\A([^:]+):\d+: syntax error/.match(err.message)
|
16
23
|
err_features << match[1] if match
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
raise
|
25
|
+
rescue ScriptError => err
|
26
|
+
raise
|
27
|
+
rescue => err
|
28
|
+
raise
|
29
|
+
ensure
|
30
|
+
if err && err.backtrace
|
31
|
+
err_features += err.backtrace.map { |b| b.split(':').first }
|
32
|
+
.select { |f| f.start_with?('/') }
|
33
|
+
.take_while { |f| f != __FILE__ }
|
34
|
+
end
|
20
35
|
|
21
|
-
|
22
|
-
err_features += err.backtrace.map { |b| b.split(':').first }
|
23
|
-
.select { |f| f.start_with?('/') }
|
24
|
-
.take_while { |f| f != __FILE__ }
|
36
|
+
notify_features(Set.new($LOADED_FEATURES) + err_features - old_features)
|
25
37
|
end
|
26
|
-
|
27
|
-
new_features = all_features + err_features - old_features
|
28
|
-
new_features.uniq!
|
29
|
-
|
30
|
-
[new_features, err]
|
31
38
|
end
|
32
39
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
full_path = File.expand_path(file)
|
38
|
-
|
39
|
-
if find_in_load_path(full_path) || File.exist?(full_path)
|
40
|
-
add_extra_feature(full_path)
|
41
|
-
end
|
40
|
+
# Internal: This should only be called by Zeus code
|
41
|
+
def set_feature_pipe(feature_pipe)
|
42
|
+
@feature_mutex = Mutex.new
|
43
|
+
@feature_pipe = feature_pipe
|
42
44
|
end
|
43
45
|
|
44
|
-
#
|
45
|
-
def
|
46
|
-
|
47
|
-
|
46
|
+
# Internal: This should only be called by Zeus code
|
47
|
+
def clear_feature_pipe
|
48
|
+
@feature_pipe.close
|
49
|
+
@feature_pipe = nil
|
50
|
+
@feature_mutex = nil
|
48
51
|
end
|
49
52
|
|
50
53
|
private
|
51
54
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
def notify_features(features)
|
56
|
+
unless @feature_pipe
|
57
|
+
raise "Attempted to report features to Zeus when not running as part of a Zeus process"
|
58
|
+
end
|
56
59
|
|
57
|
-
|
58
|
-
|
60
|
+
@feature_mutex.synchronize do
|
61
|
+
features.each do |t|
|
62
|
+
@feature_pipe.puts(t)
|
63
|
+
end
|
64
|
+
end
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
data/lib/zeus/version.rb
CHANGED
data/man/build/zeus
CHANGED
data/man/build/zeus-init
CHANGED
data/man/build/zeus-init.txt
CHANGED
data/man/build/zeus-start
CHANGED
data/man/build/zeus-start.txt
CHANGED
data/man/build/zeus.txt
CHANGED
data/spec/assets/boot.rb
ADDED
data/spec/load_tracking_spec.rb
CHANGED
@@ -6,55 +6,53 @@ describe "Zeus::LoadTracking" do
|
|
6
6
|
|
7
7
|
class MyError < StandardError; end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# add the dir path of the tempfile to LOAD_PATH
|
13
|
-
$LOAD_PATH << test_dirname
|
14
|
-
end
|
15
|
-
|
16
|
-
after { $LOAD_PATH.delete test_dirname }
|
17
|
-
|
18
|
-
it 'adds full filepath to $untracked_features' do
|
19
|
-
Zeus::LoadTracking.add_feature(test_filename)
|
9
|
+
def expect_to_load(expect_features, expect_err=NilClass)
|
10
|
+
buf = StringIO.new
|
11
|
+
Zeus::LoadTracking.set_feature_pipe(buf)
|
20
12
|
|
21
|
-
|
13
|
+
begin
|
14
|
+
Zeus::LoadTracking.track_features_loaded_by do
|
15
|
+
yield
|
22
16
|
end
|
17
|
+
rescue ScriptError => err
|
18
|
+
rescue => err
|
23
19
|
end
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
expect(err).to be_instance_of(expect_err)
|
22
|
+
expect(buf.string.strip.split("\n").sort).to eq(expect_features.sort)
|
23
|
+
end
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
def expand_asset_path(path)
|
26
|
+
File.join(__dir__, 'assets', path)
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
$untracked_features << "an_untracked_feature.rb"
|
37
|
-
end
|
29
|
+
describe '.add_feature' do
|
30
|
+
it 'tracks full filepath' do
|
31
|
+
relative_path = Pathname.new(test_filename).relative_path_from(Pathname.new(Dir.pwd)).to_s
|
38
32
|
|
39
|
-
|
33
|
+
expect_to_load([test_filename]) do
|
34
|
+
Zeus::LoadTracking.add_feature(relative_path)
|
40
35
|
end
|
41
36
|
end
|
42
|
-
end
|
43
37
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
38
|
+
it 'tracks loads' do
|
39
|
+
target = expand_asset_path('load.rb')
|
40
|
+
|
41
|
+
# The first `load` in Travis also pulls enc/trans/single_byte.so from the
|
42
|
+
# Ruby VM for some reason. Loading twice is harmless since this file is empty.
|
43
|
+
load(target)
|
49
44
|
|
50
|
-
|
51
|
-
|
45
|
+
expect_to_load([target]) do
|
46
|
+
load(target)
|
47
|
+
end
|
52
48
|
end
|
53
49
|
|
54
|
-
|
55
|
-
|
50
|
+
it 'does not error outside a tracking block without Zeus configured' do
|
51
|
+
Zeus::LoadTracking.add_feature(test_filename)
|
56
52
|
end
|
53
|
+
end
|
57
54
|
|
55
|
+
describe '.track_features_loaded_by' do
|
58
56
|
context 'loading valid code' do
|
59
57
|
it 'tracks successful require_relative' do
|
60
58
|
expect_to_load([expand_asset_path('require_relative.rb')]) do
|
@@ -67,35 +65,29 @@ describe "Zeus::LoadTracking" do
|
|
67
65
|
require expand_asset_path('require')
|
68
66
|
end
|
69
67
|
end
|
70
|
-
|
71
|
-
it 'tracks loads' do
|
72
|
-
expect_to_load([expand_asset_path('load.rb')]) do
|
73
|
-
load expand_asset_path('load.rb')
|
74
|
-
end
|
75
|
-
end
|
76
68
|
end
|
77
69
|
|
78
70
|
context 'loading invalid code' do
|
79
71
|
it 'tracks requires that raise a SyntaxError' do
|
80
|
-
|
72
|
+
files = [expand_asset_path('invalid_syntax.rb')]
|
73
|
+
# SyntaxError does not have a backtrace in 2.3+ (https://bugs.ruby-lang.org/issues/12811)
|
74
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0')
|
75
|
+
files << test_filename
|
76
|
+
end
|
77
|
+
|
78
|
+
expect_to_load(files, SyntaxError) do
|
81
79
|
require expand_asset_path('invalid_syntax')
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
85
83
|
it 'tracks requires that raise a RuntimeError' do
|
86
|
-
expect_to_load([expand_asset_path('runtime_error.rb')], RuntimeError) do
|
84
|
+
expect_to_load([test_filename, expand_asset_path('runtime_error.rb')], RuntimeError) do
|
87
85
|
require expand_asset_path('runtime_error')
|
88
86
|
end
|
89
87
|
end
|
90
88
|
|
91
|
-
it 'tracks requires that exit' do
|
92
|
-
expect_to_load([expand_asset_path('exit.rb')], SystemExit) do
|
93
|
-
require expand_asset_path('exit')
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
89
|
it 'tracks requires that throw in a method call' do
|
98
|
-
expect_to_load([expand_asset_path('raise.rb')], MyError) do
|
90
|
+
expect_to_load([test_filename, expand_asset_path('raise.rb')], MyError) do
|
99
91
|
require expand_asset_path('raise')
|
100
92
|
raise_it(MyError)
|
101
93
|
end
|
data/spec/zeus_spec.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'zeus'
|
2
|
+
|
3
|
+
describe Zeus do
|
4
|
+
class MyTestPlan < Zeus::Plan
|
5
|
+
def self.mutex
|
6
|
+
@mutex ||= Mutex.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.boot
|
10
|
+
require_relative 'assets/boot'
|
11
|
+
Thread.new do
|
12
|
+
mutex.synchronize do
|
13
|
+
Zeus::LoadTracking.add_feature(File.join(__dir__, 'assets', 'boot_delayed.rb'))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Zeus.plan = MyTestPlan
|
20
|
+
|
21
|
+
before do
|
22
|
+
MyTestPlan.mutex.lock
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
MyTestPlan.mutex.unlock if MyTestPlan.mutex.locked?
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'booting' do
|
30
|
+
before do
|
31
|
+
# Don't reopen STDOUT
|
32
|
+
Zeus.dummy_tty = true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'boots and tracks features' do
|
36
|
+
master_r, master_w = UNIXSocket.pair(Socket::SOCK_STREAM)
|
37
|
+
ENV['ZEUS_MASTER_FD'] = master_w.to_i.to_s
|
38
|
+
|
39
|
+
thr = Thread.new do
|
40
|
+
begin
|
41
|
+
Zeus.go
|
42
|
+
rescue Interrupt
|
43
|
+
return
|
44
|
+
rescue => e
|
45
|
+
STDERR.puts "Zeus terminated with exception: #{e.message}"
|
46
|
+
STDERR.puts e.backtrace.map {|line| " #{line}"}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
# Receive the control IO and start message
|
52
|
+
ctrl_io = master_r.recv_io(UNIXSocket)
|
53
|
+
begin
|
54
|
+
# We use recv instead of readline on the UNIXSocket to avoid
|
55
|
+
# converting it to a buffered reader. That seems to interact
|
56
|
+
# badly with passing file descriptors around on Linux.
|
57
|
+
proc_msg = "P:#{Process.pid}:0:boot\0"
|
58
|
+
expect(ctrl_io.recv(proc_msg.length)).to eq(proc_msg)
|
59
|
+
|
60
|
+
feature_io = ctrl_io.recv_io
|
61
|
+
|
62
|
+
ready_msg = "R:OK\0"
|
63
|
+
expect(ctrl_io.recv(ready_msg.length)).to eq(ready_msg)
|
64
|
+
begin
|
65
|
+
# We should receive the synchronously required feature immediately
|
66
|
+
expect(feature_io.readline).to eq(File.join(__dir__, 'assets', 'boot.rb') + "\n")
|
67
|
+
|
68
|
+
# We should receive the delayed feature after unlocking its mutex
|
69
|
+
MyTestPlan.mutex.unlock
|
70
|
+
expect(feature_io.readline).to eq(File.join(__dir__, 'assets', 'boot_delayed.rb') + "\n")
|
71
|
+
ensure
|
72
|
+
feature_io.close
|
73
|
+
end
|
74
|
+
ensure
|
75
|
+
ctrl_io.close
|
76
|
+
end
|
77
|
+
ensure
|
78
|
+
thr.raise(Interrupt.new)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'tracks features after booting has completed' do
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/zeus.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.email = ["burke@libbey.me"]
|
17
17
|
gem.description = %q{Boot any rails app in under a second}
|
18
18
|
gem.summary = %q{Zeus is an intelligent preloader for ruby applications. It allows normal development tasks to be run in a fraction of a second.}
|
19
|
-
gem.homepage = "
|
19
|
+
gem.homepage = "https://github.com/burke/zeus"
|
20
20
|
|
21
21
|
gem.files = files
|
22
22
|
gem.extensions = []
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zeus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.15.
|
4
|
+
version: 0.15.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Burke Libbey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: method_source
|
@@ -75,7 +75,8 @@ files:
|
|
75
75
|
- man/build/zeus-start
|
76
76
|
- man/build/zeus-start.txt
|
77
77
|
- man/build/zeus.txt
|
78
|
-
- spec/assets/
|
78
|
+
- spec/assets/boot.rb
|
79
|
+
- spec/assets/boot_delayed.rb
|
79
80
|
- spec/assets/invalid_syntax.rb
|
80
81
|
- spec/assets/load.rb
|
81
82
|
- spec/assets/raise.rb
|
@@ -87,8 +88,9 @@ files:
|
|
87
88
|
- spec/load_tracking_spec.rb
|
88
89
|
- spec/m_spec.rb
|
89
90
|
- spec/rails_spec.rb
|
91
|
+
- spec/zeus_spec.rb
|
90
92
|
- zeus.gemspec
|
91
|
-
homepage:
|
93
|
+
homepage: https://github.com/burke/zeus
|
92
94
|
licenses:
|
93
95
|
- MIT
|
94
96
|
metadata: {}
|
@@ -108,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
110
|
version: '0'
|
109
111
|
requirements: []
|
110
112
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.4.
|
113
|
+
rubygems_version: 2.4.8
|
112
114
|
signing_key:
|
113
115
|
specification_version: 4
|
114
116
|
summary: Zeus is an intelligent preloader for ruby applications. It allows normal
|
data/spec/assets/exit.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
exit(1)
|