restartable 0.2.2 → 1.0.0
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 +9 -9
- data/.rubocop.yml +59 -0
- data/.travis.yml +13 -4
- data/Gemfile +1 -1
- data/README.markdown +5 -2
- data/bin/restartable +9 -3
- data/features/restarting.feature +20 -15
- data/features/step_definitions/restartable_steps.rb +32 -23
- data/lib/restartable.rb +41 -35
- data/restartable.gemspec +5 -2
- metadata +23 -8
- data/TODO +0 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTU0NzIyODRhMDJlMDgzYmViODZmYTA3OGJkMDY4Y2I3YTA4YTgwZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
7
|
-
|
6
|
+
MWQyMDc2MTM2NWE1OTIwNDE4YjJmZTU3ZGNkYTljOGNmMjYwNWY2NQ==
|
7
|
+
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OGM0NTE3NWRkY2ViNWNmMzU1MjJmNTg2ZGFlOWE0YTBmMzQ1MDAwZTVkYjlj
|
10
|
+
ZDFjMjQxMDdjNTk4ZDllMDM5N2M2MGY1MDkyMGFjNTEyZTdjMzMzMDIyMDQ1
|
11
|
+
NGE5NDlkZDg2ZDFkZTdlNzgzNmZhYWVhZmUwYTg5OGNlZTIxZjI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjhjNGM3MjlhNDk0ZWJkMDBiZjJiMWNjNWYyY2I5N2NjYjY4YmZlOTBmNDdm
|
14
|
+
NjdhZTEwY2U1YWVjNTk2ZWQyMjg0ZGRjZDY1YzQzMWQyNGRlY2Q0YTc5ZjI2
|
15
|
+
ZWQyNjMyYTk0MTVhZmJjNDQ0YWJmN2Y4MDdhMmQ3M2Y5YzI1MDM=
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- '*.gemspec'
|
4
|
+
|
5
|
+
Lint/EndAlignment:
|
6
|
+
AlignWith: variable
|
7
|
+
|
8
|
+
Lint/Eval:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Metrics/AbcSize:
|
12
|
+
Max: 20
|
13
|
+
|
14
|
+
Metrics/MethodLength:
|
15
|
+
Max: 20
|
16
|
+
|
17
|
+
Style/AccessModifierIndentation:
|
18
|
+
EnforcedStyle: outdent
|
19
|
+
|
20
|
+
Style/BracesAroundHashParameters:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/CaseIndentation:
|
24
|
+
IndentWhenRelativeTo: end
|
25
|
+
|
26
|
+
Style/DotPosition:
|
27
|
+
EnforcedStyle: trailing
|
28
|
+
|
29
|
+
Style/DoubleNegation:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/Encoding:
|
33
|
+
EnforcedStyle: when_needed
|
34
|
+
|
35
|
+
Style/HashSyntax:
|
36
|
+
EnforcedStyle: hash_rockets
|
37
|
+
|
38
|
+
Style/IfUnlessModifier:
|
39
|
+
MaxLineLength: 40
|
40
|
+
|
41
|
+
Style/IndentHash:
|
42
|
+
EnforcedStyle: consistent
|
43
|
+
|
44
|
+
Style/PercentLiteralDelimiters:
|
45
|
+
PreferredDelimiters:
|
46
|
+
'%w': '[]'
|
47
|
+
'%W': '[]'
|
48
|
+
|
49
|
+
Style/Semicolon:
|
50
|
+
AllowAsExpressionSeparator: true
|
51
|
+
|
52
|
+
Style/SpaceBeforeBlockBraces:
|
53
|
+
EnforcedStyle: no_space
|
54
|
+
|
55
|
+
Style/SpaceInsideHashLiteralBraces:
|
56
|
+
EnforcedStyle: no_space
|
57
|
+
|
58
|
+
Style/TrailingComma:
|
59
|
+
EnforcedStyleForMultiline: comma
|
data/.travis.yml
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
3
|
- 1.8.7
|
4
|
-
- 1.9.2
|
5
4
|
- 1.9.3
|
6
|
-
- 2.0
|
7
|
-
-
|
8
|
-
script:
|
5
|
+
- '2.0'
|
6
|
+
- '2.1'
|
7
|
+
script:
|
8
|
+
if [ -n "$RUBOCOP" ]; then
|
9
|
+
bundle exec rubocop
|
10
|
+
; else
|
11
|
+
bundle exec cucumber
|
12
|
+
; fi
|
13
|
+
matrix:
|
14
|
+
fast_finish: true
|
15
|
+
include:
|
16
|
+
- env: RUBOCOP=true
|
17
|
+
rvm: default
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
[](https://rubygems.org/gems/restartable)
|
2
|
+
[](https://travis-ci.org/toy/restartable)
|
3
|
+
[](https://codeclimate.com/github/toy/restartable)
|
4
|
+
[](https://gemnasium.com/toy/restartable)
|
5
|
+
|
1
6
|
# restartable
|
2
7
|
|
3
8
|
Run code, Ctrl-C to restart, two Ctrl-C to stop.
|
4
9
|
|
5
|
-
[](https://travis-ci.org/toy/restartable)
|
6
|
-
|
7
10
|
## Copyright
|
8
11
|
|
9
12
|
Copyright (c) 2012-2014 Ivan Kuchin. See LICENSE.txt for details.
|
data/bin/restartable
CHANGED
@@ -14,6 +14,12 @@ Usege:
|
|
14
14
|
|
15
15
|
TEXT
|
16
16
|
|
17
|
+
op.on('-r', '--on-restart CMD', 'Run CMD on restart') do |cmd|
|
18
|
+
(options[:on_restart] ||= []) << proc{ system cmd }
|
19
|
+
end
|
20
|
+
|
21
|
+
op.separator nil
|
22
|
+
|
17
23
|
op.on_tail('-h', '--help', 'Show full help') do
|
18
24
|
puts option_parser.help
|
19
25
|
exit
|
@@ -27,11 +33,11 @@ end
|
|
27
33
|
|
28
34
|
begin
|
29
35
|
option_parser.order!
|
30
|
-
|
36
|
+
fail OptionParser::ParseError, 'No command to run' if ARGV.empty?
|
31
37
|
rescue OptionParser::ParseError => e
|
32
|
-
abort "#{e
|
38
|
+
abort "#{e}\n\n#{option_parser.help}"
|
33
39
|
end
|
34
40
|
|
35
41
|
Restartable.new(options) do
|
36
|
-
exec
|
42
|
+
exec(*ARGV)
|
37
43
|
end
|
data/features/restarting.feature
CHANGED
@@ -1,32 +1,37 @@
|
|
1
1
|
Feature: Restarting
|
2
2
|
|
3
3
|
Scenario Outline: Restarting and terminating
|
4
|
+
Given I have set on restart to `$stdout.puts 'Restart!'`
|
4
5
|
Given I have invoked restartable with `<code>`
|
5
6
|
|
6
7
|
When I have waited for 1 second
|
7
8
|
Then I should see "^C to restart, double ^C to stop" in stderr
|
8
9
|
And I should see "Hello world!" in stdout
|
9
|
-
And there should be
|
10
|
+
And there should be a child process
|
10
11
|
When I interrupt restartable
|
11
|
-
Then I should see "Killing children…"
|
12
|
-
And
|
12
|
+
Then I should see "Killing children…" in stderr
|
13
|
+
And I should see "Waiting ^C 0.5 second than restart…" in stderr within <timeout> seconds
|
14
|
+
And child process should terminate
|
13
15
|
|
14
16
|
When I have waited for 1 second
|
15
|
-
Then I should see "
|
17
|
+
Then I should see "Restart!" in stdout
|
18
|
+
And I should see "^C to restart, double ^C to stop" in stderr
|
16
19
|
And I should see "Hello world!" in stdout
|
17
|
-
And there should be
|
20
|
+
And there should be a child process
|
18
21
|
When I interrupt restartable twice
|
19
22
|
Then I should see "Killing children…" and "Don't restart!" in stderr
|
20
|
-
And
|
23
|
+
And child process should terminate within <timeout> seconds
|
21
24
|
And restartable should finish
|
25
|
+
And I should not see "Waiting ^C 0.5 second than restart…" in stderr
|
26
|
+
And I should not see "Restart!" in stdout
|
22
27
|
|
23
28
|
Examples:
|
24
|
-
| code |
|
25
|
-
| $stdout.puts "Hello world!" |
|
26
|
-
| $stdout.puts "Hello world!"; 100.times{ sleep 1 } |
|
27
|
-
| exec 'echo "Hello world!"; sleep 100' |
|
28
|
-
| system 'echo "Hello world!"; sleep 100' |
|
29
|
-
| fork{ $stdout.puts "Hello world!"; 100.times{ sleep 1 } } |
|
30
|
-
| fork{ fork{ fork{ $stdout.puts "Hello world!"; 100.times{ sleep 1 } } } } |
|
31
|
-
| Signal.trap("INT"){}; $stdout.puts "Hello world!"; 100.times{ sleep 1 } |
|
32
|
-
| Signal.trap("INT"){}; Signal.trap("TERM"){}; $stdout.puts "Hello world!"; 100.times{ sleep 1 } |
|
29
|
+
| code | timeout |
|
30
|
+
| $stdout.puts "Hello world!" | 5 |
|
31
|
+
| $stdout.puts "Hello world!"; 100.times{ sleep 1 } | 5 |
|
32
|
+
| exec 'echo "Hello world!"; sleep 100' | 5 |
|
33
|
+
| system 'echo "Hello world!"; sleep 100' | 5 |
|
34
|
+
| fork{ $stdout.puts "Hello world!"; 100.times{ sleep 1 } } | 5 |
|
35
|
+
| fork{ fork{ fork{ $stdout.puts "Hello world!"; 100.times{ sleep 1 } } } } | 5 |
|
36
|
+
| Signal.trap("INT"){}; $stdout.puts "Hello world!"; 100.times{ sleep 1 } | 15 |
|
37
|
+
| Signal.trap("INT"){}; Signal.trap("TERM"){}; $stdout.puts "Hello world!"; 100.times{ sleep 1 } | 25 |
|
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'restartable'
|
2
2
|
|
3
|
+
Given(/^I have set on restart to `(.*?)`$/) do |command|
|
4
|
+
(@on_restart ||= []) << proc{ eval(command) }
|
5
|
+
end
|
6
|
+
|
3
7
|
Given(/^I have invoked restartable with `(.*?)`$/) do |command|
|
4
8
|
@stdout = IO.pipe
|
5
9
|
@stderr = IO.pipe
|
@@ -13,7 +17,7 @@ Given(/^I have invoked restartable with `(.*?)`$/) do |command|
|
|
13
17
|
@stderr[0].close
|
14
18
|
STDERR.reopen(@stderr[1])
|
15
19
|
|
16
|
-
Restartable.new do
|
20
|
+
Restartable.new(:on_restart => @on_restart) do
|
17
21
|
Signal.trap('INT', 'EXIT')
|
18
22
|
eval(command)
|
19
23
|
end
|
@@ -27,17 +31,16 @@ When(/^I have waited for (\d+) second$/) do |seconds|
|
|
27
31
|
sleep seconds.to_i
|
28
32
|
end
|
29
33
|
|
30
|
-
Then(/^
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Timeout::timeout(60) do
|
34
|
+
Then(/^
|
35
|
+
I\ should\ see\ "(.*?)"
|
36
|
+
\ in\ std(out|err)
|
37
|
+
(?:\ within\ (\d+)\ seconds)?
|
38
|
+
$/x) do |arg, io_name, timeout|
|
39
|
+
io = (io_name == 'out' ? @stdout : @stderr)[0]
|
40
|
+
Timeout.timeout(timeout ? timeout.to_i : 5) do
|
38
41
|
strings = arg.split(/".*?"/)
|
39
42
|
until strings.empty?
|
40
|
-
line =
|
43
|
+
line = io.gets
|
41
44
|
strings.reject! do |string|
|
42
45
|
line.include?(string)
|
43
46
|
end
|
@@ -45,34 +48,40 @@ Then(/^I should see "(.*?)" in stderr$/) do |arg|
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
51
|
+
Then(/^I should not see "(.*?)" in std(out|err)$/) do |arg, io_name|
|
52
|
+
io = (io_name == 'out' ? @stdout : @stderr)[0]
|
53
|
+
strings = arg.split(/".*?"/)
|
54
|
+
while (line = io.gets)
|
55
|
+
if strings.any?{ |string| line.include?(string) }
|
56
|
+
fail "Got #{line}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
48
61
|
When(/^I interrupt restartable$/) do
|
49
62
|
Process.kill('INT', -@pid)
|
50
63
|
end
|
51
64
|
|
52
65
|
When(/^I interrupt restartable twice$/) do
|
53
|
-
|
66
|
+
step 'I interrupt restartable'
|
54
67
|
sleep 0.1
|
55
|
-
|
68
|
+
step 'I interrupt restartable'
|
56
69
|
end
|
57
70
|
|
58
|
-
Then(/^there should be
|
59
|
-
Timeout
|
60
|
-
until Sys::ProcTable.ps.any?{ |pe| pe.ppid == @pid }
|
61
|
-
sleep 1
|
62
|
-
end
|
71
|
+
Then(/^there should be a child process$/) do
|
72
|
+
Timeout.timeout(5) do
|
73
|
+
sleep 1 until Sys::ProcTable.ps.any?{ |pe| pe.ppid == @pid }
|
63
74
|
end
|
64
75
|
end
|
65
76
|
|
66
|
-
Then(/^
|
67
|
-
Timeout
|
68
|
-
until Sys::ProcTable.ps.none?{ |pe| pe.ppid == @pid }
|
69
|
-
sleep 1
|
70
|
-
end
|
77
|
+
Then(/^child process should terminate(?: within (\d+) seconds)?$/) do |timeout|
|
78
|
+
Timeout.timeout(timeout ? timeout.to_i : 5) do
|
79
|
+
sleep 1 until Sys::ProcTable.ps.none?{ |pe| pe.ppid == @pid }
|
71
80
|
end
|
72
81
|
end
|
73
82
|
|
74
83
|
Then(/^restartable should finish$/) do
|
75
|
-
Timeout
|
84
|
+
Timeout.timeout(5) do
|
76
85
|
Process.wait(@pid)
|
77
86
|
end
|
78
87
|
end
|
data/lib/restartable.rb
CHANGED
@@ -3,26 +3,25 @@
|
|
3
3
|
require 'sys/proctable'
|
4
4
|
require 'colored'
|
5
5
|
require 'thread'
|
6
|
+
require 'English'
|
6
7
|
|
8
|
+
# Main interface
|
7
9
|
class Restartable
|
8
10
|
def self.version
|
9
11
|
Gem.loaded_specs['restartable'].version.to_s rescue 'DEV'
|
10
12
|
end
|
11
13
|
|
12
14
|
def initialize(options = {}, &block)
|
13
|
-
@
|
15
|
+
@on_restart = Array(options[:on_restart])
|
16
|
+
@block = block
|
14
17
|
run!
|
15
18
|
end
|
16
19
|
|
17
20
|
private
|
18
21
|
|
19
22
|
def run!
|
20
|
-
Signal.trap('INT')
|
21
|
-
|
22
|
-
end
|
23
|
-
Signal.trap('TERM') do
|
24
|
-
terminate!
|
25
|
-
end
|
23
|
+
Signal.trap('INT'){ interrupt! }
|
24
|
+
Signal.trap('TERM'){ terminate! }
|
26
25
|
|
27
26
|
until @stop
|
28
27
|
@interrupted = nil
|
@@ -34,10 +33,11 @@ private
|
|
34
33
|
end
|
35
34
|
sleep 0.1 until @interrupted
|
36
35
|
kill_children!
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
break if @stop
|
37
|
+
$stderr << "Waiting ^C 0.5 second than restart…\n".yellow.bold
|
38
|
+
sleep 0.5
|
39
|
+
break if @stop
|
40
|
+
@on_restart.each(&:call)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -58,26 +58,35 @@ private
|
|
58
58
|
WAIT_SIGNALS = [[5, 'INT'], [3, 'INT'], [1, 'INT'], [3, 'TERM'], [5, 'KILL']]
|
59
59
|
|
60
60
|
def kill_children!
|
61
|
-
until
|
61
|
+
until children_pids.empty?
|
62
62
|
$stderr << "Killing children…\n".yellow.bold
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
|
64
|
+
signal_pair = 0
|
65
|
+
|
66
|
+
begin
|
67
|
+
time, signal = WAIT_SIGNALS[signal_pair]
|
68
|
+
Timeout.timeout(time) do
|
69
|
+
Process.waitall
|
70
|
+
wait_children
|
68
71
|
end
|
72
|
+
rescue Timeout::Error
|
73
|
+
$stderr << "…SIG#{signal}…\n".yellow
|
74
|
+
signal_children!(signal)
|
75
|
+
retry if WAIT_SIGNALS[signal_pair += 1]
|
69
76
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def wait_children
|
81
|
+
children_pids.each do |pid|
|
82
|
+
begin
|
83
|
+
loop do
|
84
|
+
Process.kill(0, pid)
|
85
|
+
sleep 1
|
78
86
|
end
|
87
|
+
rescue Errno::ESRCH
|
88
|
+
next
|
79
89
|
end
|
80
|
-
ripper.terminate
|
81
90
|
end
|
82
91
|
end
|
83
92
|
|
@@ -86,6 +95,7 @@ private
|
|
86
95
|
begin
|
87
96
|
Process.kill(signal, pid)
|
88
97
|
rescue Errno::ESRCH
|
98
|
+
next
|
89
99
|
end
|
90
100
|
end
|
91
101
|
end
|
@@ -94,15 +104,11 @@ private
|
|
94
104
|
pgrp = Process.getpgrp
|
95
105
|
Sys::ProcTable.ps.select do |pe|
|
96
106
|
pgrp == case
|
97
|
-
when pe.respond_to?(:pgid)
|
98
|
-
|
99
|
-
when pe.respond_to?(:
|
100
|
-
|
101
|
-
when pe.respond_to?(:ppid)
|
102
|
-
pe.ppid
|
103
|
-
else
|
104
|
-
raise 'Can\'t find process group id'
|
107
|
+
when pe.respond_to?(:pgid) then pe.pgid
|
108
|
+
when pe.respond_to?(:pgrp) then pe.pgrp
|
109
|
+
when pe.respond_to?(:ppid) then pe.ppid
|
110
|
+
else fail 'Can\'t find process group id'
|
105
111
|
end
|
106
|
-
end.map(&:pid) - [
|
112
|
+
end.map(&:pid) - [$PROCESS_ID]
|
107
113
|
end
|
108
114
|
end
|
data/restartable.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'restartable'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '1.0.0'
|
6
6
|
s.summary = %q{Run code, Ctrl-C to restart, once more Ctrl-C to stop}
|
7
7
|
s.homepage = "http://github.com/toy/#{s.name}"
|
8
8
|
s.authors = ['Ivan Kuchin']
|
@@ -18,5 +18,8 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_dependency 'colored', '~> 1.2'
|
19
19
|
s.add_dependency 'sys-proctable', '~> 0.9.3'
|
20
20
|
s.add_development_dependency 'cucumber'
|
21
|
-
s.add_development_dependency 'rspec'
|
21
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('1.9.3')
|
23
|
+
s.add_development_dependency 'rubocop', '~> 0.27'
|
24
|
+
end
|
22
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restartable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Kuchin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored
|
@@ -56,16 +56,30 @@ dependencies:
|
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '3.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.27'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.27'
|
69
83
|
description:
|
70
84
|
email:
|
71
85
|
executables:
|
@@ -74,11 +88,11 @@ extensions: []
|
|
74
88
|
extra_rdoc_files: []
|
75
89
|
files:
|
76
90
|
- .gitignore
|
91
|
+
- .rubocop.yml
|
77
92
|
- .travis.yml
|
78
93
|
- Gemfile
|
79
94
|
- LICENSE.txt
|
80
95
|
- README.markdown
|
81
|
-
- TODO
|
82
96
|
- bin/restartable
|
83
97
|
- features/restarting.feature
|
84
98
|
- features/step_definitions/restartable_steps.rb
|
@@ -104,10 +118,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
118
|
version: '0'
|
105
119
|
requirements: []
|
106
120
|
rubyforge_project: restartable
|
107
|
-
rubygems_version: 2.
|
121
|
+
rubygems_version: 2.4.5
|
108
122
|
signing_key:
|
109
123
|
specification_version: 4
|
110
124
|
summary: Run code, Ctrl-C to restart, once more Ctrl-C to stop
|
111
125
|
test_files:
|
112
126
|
- features/restarting.feature
|
113
127
|
- features/step_definitions/restartable_steps.rb
|
128
|
+
has_rdoc:
|