tty-process-ctl 0.4.0 → 0.5.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.
- data/Gemfile +7 -6
- data/Gemfile.lock +2 -0
- data/VERSION +1 -1
- data/lib/tty-process-ctl.rb +80 -22
- data/spec/tty-process-ctl_spec.rb +166 -85
- data/tty-process-ctl.gemspec +5 -2
- metadata +26 -15
data/Gemfile
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
3
|
group :development do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
gem "rake", "~> 0.9"
|
5
|
+
gem "rspec", "~> 2.8"
|
6
|
+
gem "rdoc", "~> 3.12"
|
7
|
+
gem "bundler", "~> 1.1"
|
8
|
+
gem "jeweler", "~> 1.8"
|
9
|
+
gem "simplecov", ">= 0"
|
10
|
+
gem "cli", "~> 1.0"
|
10
11
|
end
|
data/Gemfile.lock
CHANGED
@@ -11,6 +11,7 @@ GEM
|
|
11
11
|
rdoc
|
12
12
|
json (1.7.5)
|
13
13
|
multi_json (1.3.6)
|
14
|
+
rake (0.9.2.2)
|
14
15
|
rdoc (3.12)
|
15
16
|
json (~> 1.4)
|
16
17
|
rspec (2.11.0)
|
@@ -33,6 +34,7 @@ DEPENDENCIES
|
|
33
34
|
bundler (~> 1.1)
|
34
35
|
cli (~> 1.0)
|
35
36
|
jeweler (~> 1.8)
|
37
|
+
rake (~> 0.9)
|
36
38
|
rdoc (~> 3.12)
|
37
39
|
rspec (~> 2.8)
|
38
40
|
simplecov
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/tty-process-ctl.rb
CHANGED
@@ -4,18 +4,43 @@ require 'pty'
|
|
4
4
|
require 'io/console'
|
5
5
|
|
6
6
|
class TTYProcessCtl
|
7
|
-
|
7
|
+
Timeout = Class.new(Timeout::Error)
|
8
|
+
|
9
|
+
class Listener
|
10
|
+
def initialize(&callback)
|
11
|
+
@callback = callback
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(message)
|
15
|
+
@callback.call(message)
|
16
|
+
rescue LocalJumpError => error
|
17
|
+
# brake in listener
|
18
|
+
close if error.reason == :break
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_close(&callback)
|
22
|
+
@on_close = callback unless closed?
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
@on_close.call(self) if @on_close
|
28
|
+
@closed = true
|
29
|
+
end
|
30
|
+
|
31
|
+
def closed?
|
32
|
+
@closed
|
33
|
+
end
|
8
34
|
end
|
9
35
|
|
10
36
|
include Enumerable
|
11
37
|
|
12
38
|
def initialize(command, options = {})
|
13
|
-
@
|
14
|
-
@max_messages = options[:max_messages] || 4000
|
39
|
+
@backlog_size = options[:backlog_size] || 4000
|
15
40
|
@command = command
|
16
41
|
|
42
|
+
@listeners = []
|
17
43
|
@out_queue = Queue.new
|
18
|
-
@messages = []
|
19
44
|
|
20
45
|
@r, @w, @pid = PTY.spawn(@command)
|
21
46
|
@w.echo = false # disable echoing of commands
|
@@ -47,18 +72,26 @@ class TTYProcessCtl
|
|
47
72
|
raise IOError.new("process '#{@command}' (pid: #{@pid}) not accepting input")
|
48
73
|
end
|
49
74
|
|
50
|
-
def
|
51
|
-
|
75
|
+
def on(regexp = nil, &callback)
|
76
|
+
# return listender to user so he can close it after use
|
77
|
+
listener do |message|
|
78
|
+
next if regexp and message !~ regexp
|
79
|
+
callback.call(message)
|
80
|
+
end
|
52
81
|
end
|
53
82
|
|
54
|
-
def each(options = {})
|
55
|
-
return enum_for(:each, options) unless
|
56
|
-
|
57
|
-
|
58
|
-
|
83
|
+
def each(options = {}, &block)
|
84
|
+
return enum_for(:each, options) unless block
|
85
|
+
listener = listener(&block)
|
86
|
+
begin
|
87
|
+
timeout(options[:timeout]) do
|
88
|
+
true while not listener.closed? and poll
|
59
89
|
end
|
90
|
+
self
|
91
|
+
ensure
|
92
|
+
# make sure we close the listener when each exits
|
93
|
+
listener.close
|
60
94
|
end
|
61
|
-
self
|
62
95
|
end
|
63
96
|
|
64
97
|
def each_until(pattern, options = {})
|
@@ -84,17 +117,25 @@ class TTYProcessCtl
|
|
84
117
|
end
|
85
118
|
|
86
119
|
def wait_exit(options = {})
|
87
|
-
|
120
|
+
poll!(options)
|
88
121
|
@thread.join
|
89
122
|
self
|
90
123
|
end
|
91
124
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
125
|
+
def poll(options = {})
|
126
|
+
timeout(options[:timeout]) do
|
127
|
+
return process_message
|
95
128
|
end
|
96
|
-
|
97
|
-
|
129
|
+
end
|
130
|
+
|
131
|
+
def poll!(options = {})
|
132
|
+
timeout(options[:timeout]) do
|
133
|
+
true while process_message
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def flush
|
138
|
+
true while process_message_no_block
|
98
139
|
self
|
99
140
|
end
|
100
141
|
|
@@ -108,17 +149,34 @@ class TTYProcessCtl
|
|
108
149
|
end
|
109
150
|
end
|
110
151
|
|
111
|
-
def
|
152
|
+
def listener(&block)
|
153
|
+
listener = Listener.new(&block).on_close do |listener|
|
154
|
+
@listeners.delete(listener)
|
155
|
+
end
|
156
|
+
@listeners << listener
|
157
|
+
listener
|
158
|
+
end
|
159
|
+
|
160
|
+
def process_message_no_block
|
161
|
+
process_message(true)
|
162
|
+
rescue ThreadError
|
163
|
+
nil
|
164
|
+
end
|
165
|
+
|
166
|
+
def process_message(no_block = false)
|
167
|
+
return nil if not alive? and @out_queue.empty?
|
112
168
|
message = @out_queue.pop(no_block)
|
113
169
|
return nil unless message
|
114
|
-
|
115
|
-
@
|
170
|
+
message.freeze
|
171
|
+
@listeners.each do |listener|
|
172
|
+
listener.call(message)
|
173
|
+
end
|
116
174
|
message
|
117
175
|
end
|
118
176
|
|
119
177
|
def enqueue_message(message)
|
120
178
|
@out_queue << message
|
121
|
-
@out_queue.pop while @out_queue.length > @
|
179
|
+
@out_queue.pop while @out_queue.length > @backlog_size
|
122
180
|
end
|
123
181
|
|
124
182
|
def enqueue_end
|
@@ -5,31 +5,45 @@ describe TTYProcessCtl do
|
|
5
5
|
TTYProcessCtl.new('spec/stub')
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
subject
|
10
|
-
|
11
|
-
|
8
|
+
after :each do
|
9
|
+
subject.send_command 'stop' if subject.alive?
|
10
|
+
subject.wait_exit
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be Enumerable' do
|
14
|
+
subject.should respond_to :take
|
15
|
+
subject.take(2).should == ["151 recipes", "16 achievements"]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should skip oldest messages if backlog queue is full' do
|
19
|
+
subject = TTYProcessCtl.new('spec/stub', backlog_size: 2)
|
12
20
|
|
21
|
+
subject.each_until(/Done/).to_a
|
22
|
+
subject.send_command 'help'
|
23
|
+
subject.send_command 'stop'
|
24
|
+
|
25
|
+
# fait for backlog to overflow
|
26
|
+
sleep 0.2
|
27
|
+
|
28
|
+
subject.each.to_a.should == [
|
29
|
+
"2011-09-19 22:12:00 [INFO] Saving chunks",
|
30
|
+
"2011-09-19 22:12:00 [INFO] Saving chunks"
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'process output enumeration' do
|
13
35
|
it 'should allow iterating the output lines' do
|
36
|
+
subject.send_command 'stop'
|
14
37
|
lines_count = 0
|
15
38
|
subject.each do |line|
|
16
39
|
lines_count += 1
|
17
40
|
end
|
18
|
-
lines_count.should ==
|
41
|
+
lines_count.should == 23
|
19
42
|
end
|
20
43
|
|
21
44
|
it 'should allow iterating the output lines with enumerator' do
|
22
|
-
subject.
|
23
|
-
|
24
|
-
|
25
|
-
it 'should be Enumerable' do
|
26
|
-
subject.should respond_to :take
|
27
|
-
subject.take(2).should == ["151 recipes", "16 achievements"]
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should return nothing if iterating on dead process' do
|
31
|
-
subject.each.to_a.length.should == 20
|
32
|
-
subject.each.to_a.should be_empty
|
45
|
+
subject.send_command 'stop'
|
46
|
+
subject.each.to_a.length.should == 23
|
33
47
|
end
|
34
48
|
|
35
49
|
it 'should allow iteration until pattern is found in message' do
|
@@ -42,8 +56,132 @@ describe TTYProcessCtl do
|
|
42
56
|
|
43
57
|
it 'should allow waiting for message matching pattern' do
|
44
58
|
subject.wait_until(/NOT ENOUGH RAM/)
|
59
|
+
subject.send_command 'stop'
|
45
60
|
subject.each.to_a.first.should == "2011-09-10 12:58:55 [WARNING] To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""
|
46
61
|
end
|
62
|
+
|
63
|
+
it 'should return nothing if iterating on dead process' do
|
64
|
+
subject.send_command 'stop'
|
65
|
+
subject.each.to_a.length.should == 23
|
66
|
+
subject.should_not be_alive
|
67
|
+
subject.each.to_a.should be_empty
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should allow flushing backlog messages' do
|
71
|
+
subject.each_until(/SERVER IS RUNNING/).to_a
|
72
|
+
sleep 0.2
|
73
|
+
|
74
|
+
subject.flush
|
75
|
+
|
76
|
+
subject.send_command 'list'
|
77
|
+
subject.each_until(/Connected players/).to_a.should == ["2011-09-20 14:42:04 [INFO] Connected players: kazuya"]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'on message callbacks' do
|
82
|
+
describe 'when enumerating' do
|
83
|
+
it 'should call on message callback' do
|
84
|
+
messages = []
|
85
|
+
subject.on do |message|
|
86
|
+
messages << message
|
87
|
+
end
|
88
|
+
|
89
|
+
subject.wait_until(/NOT ENOUGH RAM/)
|
90
|
+
messages.should == [
|
91
|
+
"151 recipes",
|
92
|
+
"16 achievements",
|
93
|
+
"2011-09-10 12:58:55 [INFO] Starting minecraft server version Beta 1.7.3",
|
94
|
+
"2011-09-10 12:58:55 [WARNING] **** NOT ENOUGH RAM!"
|
95
|
+
]
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should call on message callback if given regexp matches the message' do
|
99
|
+
messages = []
|
100
|
+
subject.on(/recipes|achievements/) do |message|
|
101
|
+
messages << message
|
102
|
+
end
|
103
|
+
|
104
|
+
subject.wait_until(/NOT ENOUGH RAM/)
|
105
|
+
messages.should == [
|
106
|
+
"151 recipes",
|
107
|
+
"16 achievements"
|
108
|
+
]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'when polling' do
|
113
|
+
it 'should call on message callback' do
|
114
|
+
messages = []
|
115
|
+
subject.on do |message|
|
116
|
+
messages << message
|
117
|
+
end
|
118
|
+
|
119
|
+
subject.send_command 'stop'
|
120
|
+
subject.poll!(timeout: 1.0)
|
121
|
+
|
122
|
+
messages.length.should == 23
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should call on message callback if given regexp matches the message' do
|
126
|
+
messages = []
|
127
|
+
subject.on(/recipes|achievements/) do |message|
|
128
|
+
messages << message
|
129
|
+
end
|
130
|
+
|
131
|
+
subject.send_command 'stop'
|
132
|
+
subject.poll!(timeout: 1.0)
|
133
|
+
|
134
|
+
messages.should == [
|
135
|
+
"151 recipes",
|
136
|
+
"16 achievements"
|
137
|
+
]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'when flushing' do
|
142
|
+
it 'should call on message callback if given regexp matches the message' do
|
143
|
+
messages = []
|
144
|
+
subject.on(/recipes|achievements/) do |message|
|
145
|
+
messages << message
|
146
|
+
end
|
147
|
+
|
148
|
+
sleep 1.0
|
149
|
+
subject.flush
|
150
|
+
|
151
|
+
messages.should == [
|
152
|
+
"151 recipes",
|
153
|
+
"16 achievements"
|
154
|
+
]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe 'closing' do
|
159
|
+
it 'with close method on listener' do
|
160
|
+
counter = 0
|
161
|
+
listener = subject.on do
|
162
|
+
counter += 1
|
163
|
+
end
|
164
|
+
|
165
|
+
subject.poll
|
166
|
+
listener.close
|
167
|
+
subject.poll
|
168
|
+
|
169
|
+
counter.should == 1
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'with break' do
|
173
|
+
counter = 0
|
174
|
+
subject.on do
|
175
|
+
counter += 1
|
176
|
+
break
|
177
|
+
end
|
178
|
+
|
179
|
+
subject.poll
|
180
|
+
subject.poll
|
181
|
+
|
182
|
+
counter.should == 1
|
183
|
+
end
|
184
|
+
end
|
47
185
|
end
|
48
186
|
|
49
187
|
describe 'sending commands' do
|
@@ -76,35 +214,6 @@ describe TTYProcessCtl do
|
|
76
214
|
end
|
77
215
|
end
|
78
216
|
|
79
|
-
describe 'messages' do
|
80
|
-
subject do
|
81
|
-
TTYProcessCtl.new('spec/stub --exit')
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'should allow access to previously outputed messages' do
|
85
|
-
subject.each.to_a
|
86
|
-
subject.messages.length.should == 20
|
87
|
-
end
|
88
|
-
|
89
|
-
describe 'flushing' do
|
90
|
-
subject do
|
91
|
-
TTYProcessCtl.new('spec/stub')
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'should allow flushing queued messages before iteration' do
|
95
|
-
subject.each_until(/SERVER IS RUNNING/).to_a
|
96
|
-
sleep 0.2
|
97
|
-
|
98
|
-
subject.flush
|
99
|
-
|
100
|
-
subject.send_command 'list'
|
101
|
-
subject.each_until(/Connected players/).to_a.should == ["2011-09-20 14:42:04 [INFO] Connected players: kazuya"]
|
102
|
-
|
103
|
-
subject.send_command 'stop'
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
217
|
describe 'process status query' do
|
109
218
|
it 'should allow querying if process is alive' do
|
110
219
|
subject.should be_alive
|
@@ -130,60 +239,34 @@ describe TTYProcessCtl do
|
|
130
239
|
end
|
131
240
|
end
|
132
241
|
|
133
|
-
describe 'limiting' do
|
134
|
-
it 'should allow defining maximum number of messages that can be queued' do
|
135
|
-
subject = TTYProcessCtl.new('spec/stub', max_queue_length: 2)
|
136
|
-
|
137
|
-
subject.each_until(/Done/).to_a
|
138
|
-
subject.send_command 'help'
|
139
|
-
subject.send_command 'stop'
|
140
|
-
|
141
|
-
sleep 0.2
|
142
|
-
subject.each.to_a.length.should == 2
|
143
|
-
subject.wait_exit
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'should allow defining maximum number of messages that can be remembered' do
|
147
|
-
subject = TTYProcessCtl.new('spec/stub', max_messages: 2)
|
148
|
-
|
149
|
-
subject.each_until(/Done/).to_a
|
150
|
-
subject.send_command 'help'
|
151
|
-
subject.flush
|
152
|
-
subject.send_command 'stop'
|
153
|
-
subject.wait_exit
|
154
|
-
|
155
|
-
subject.messages.length.should == 2
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
242
|
describe 'timeout' do
|
160
|
-
|
161
|
-
|
162
|
-
|
243
|
+
subject do
|
244
|
+
# wait for process to be ready and delay each message printout by 0.1 second
|
245
|
+
TTYProcessCtl.new('spec/stub --delay 0.01').wait_until(/151 recipes/, timeout: 1)
|
163
246
|
end
|
164
247
|
|
165
248
|
describe 'each calls with block' do
|
166
249
|
it 'should raise TTYProcessCtl::Timeout on timieout' do
|
167
250
|
expect {
|
168
|
-
subject.each(timeout: 0.1)
|
251
|
+
subject.each(timeout: 0.1){}
|
169
252
|
}.to raise_error TTYProcessCtl::Timeout
|
170
253
|
|
171
254
|
expect {
|
172
|
-
subject.each_until(/bogous/, timeout: 0.1)
|
255
|
+
subject.each_until(/bogous/, timeout: 0.1){}
|
173
256
|
}.to raise_error TTYProcessCtl::Timeout
|
174
257
|
|
175
258
|
expect {
|
176
|
-
subject.each_until_exclude(/bogous/, timeout: 0.1)
|
259
|
+
subject.each_until_exclude(/bogous/, timeout: 0.1){}
|
177
260
|
}.to raise_error TTYProcessCtl::Timeout
|
178
261
|
end
|
179
262
|
|
180
263
|
it 'should not raise error if they return before timeout' do
|
181
264
|
expect {
|
182
|
-
subject.each_until(/
|
265
|
+
subject.each_until(/achievements/, timeout: 1){}
|
183
266
|
}.to_not raise_error TTYProcessCtl::Timeout
|
184
267
|
|
185
268
|
expect {
|
186
|
-
subject.each_until_exclude(/
|
269
|
+
subject.each_until_exclude(/NOT ENOUGH RAM/, timeout: 1){}
|
187
270
|
}.to_not raise_error TTYProcessCtl::Timeout
|
188
271
|
|
189
272
|
expect {
|
@@ -209,11 +292,11 @@ describe TTYProcessCtl do
|
|
209
292
|
|
210
293
|
it 'should not raise error if they return before timeout' do
|
211
294
|
expect {
|
212
|
-
subject.each_until(/
|
295
|
+
subject.each_until(/achievements/, timeout: 1).to_a
|
213
296
|
}.to_not raise_error TTYProcessCtl::Timeout
|
214
297
|
|
215
298
|
expect {
|
216
|
-
subject.each_until_exclude(/
|
299
|
+
subject.each_until_exclude(/NOT ENOUGH RAM/, timeout: 1).to_a
|
217
300
|
}.to_not raise_error TTYProcessCtl::Timeout
|
218
301
|
|
219
302
|
expect {
|
@@ -248,17 +331,15 @@ describe TTYProcessCtl do
|
|
248
331
|
end
|
249
332
|
|
250
333
|
describe 'chaining' do
|
251
|
-
subject do
|
252
|
-
TTYProcessCtl.new('spec/stub --exit')
|
253
|
-
end
|
254
|
-
|
255
334
|
it 'should work with each methods' do
|
335
|
+
subject.send_command 'stop'
|
256
336
|
subject.each_until(/recipes/){}.should == subject
|
257
337
|
subject.each_until_exclude(/achievements/){}.should == subject
|
258
338
|
subject.each{}.should == subject
|
259
339
|
end
|
260
340
|
|
261
341
|
it 'should work with wait methods' do
|
342
|
+
subject.send_command 'stop'
|
262
343
|
subject.wait_until(/Done/){}.should == subject
|
263
344
|
subject.wait_exit{}.should == subject
|
264
345
|
end
|
data/tty-process-ctl.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "tty-process-ctl"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jakub Pastuszek"]
|
12
|
-
s.date = "2012-11-
|
12
|
+
s.date = "2012-11-24"
|
13
13
|
s.description = "This gem was created to enable control of interactive terminal applications. It is using pseudo tty to communicate with the process via simple API."
|
14
14
|
s.email = "jpastuszek@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -44,6 +44,7 @@ Gem::Specification.new do |s|
|
|
44
44
|
s.specification_version = 3
|
45
45
|
|
46
46
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_development_dependency(%q<rake>, ["~> 0.9"])
|
47
48
|
s.add_development_dependency(%q<rspec>, ["~> 2.8"])
|
48
49
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
49
50
|
s.add_development_dependency(%q<bundler>, ["~> 1.1"])
|
@@ -51,6 +52,7 @@ Gem::Specification.new do |s|
|
|
51
52
|
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
52
53
|
s.add_development_dependency(%q<cli>, ["~> 1.0"])
|
53
54
|
else
|
55
|
+
s.add_dependency(%q<rake>, ["~> 0.9"])
|
54
56
|
s.add_dependency(%q<rspec>, ["~> 2.8"])
|
55
57
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
56
58
|
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
@@ -59,6 +61,7 @@ Gem::Specification.new do |s|
|
|
59
61
|
s.add_dependency(%q<cli>, ["~> 1.0"])
|
60
62
|
end
|
61
63
|
else
|
64
|
+
s.add_dependency(%q<rake>, ["~> 0.9"])
|
62
65
|
s.add_dependency(%q<rspec>, ["~> 2.8"])
|
63
66
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
64
67
|
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-process-ctl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70125546618580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.9'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70125546618580
|
14
25
|
- !ruby/object:Gem::Dependency
|
15
26
|
name: rspec
|
16
|
-
requirement: &
|
27
|
+
requirement: &70125546616420 !ruby/object:Gem::Requirement
|
17
28
|
none: false
|
18
29
|
requirements:
|
19
30
|
- - ~>
|
@@ -21,10 +32,10 @@ dependencies:
|
|
21
32
|
version: '2.8'
|
22
33
|
type: :development
|
23
34
|
prerelease: false
|
24
|
-
version_requirements: *
|
35
|
+
version_requirements: *70125546616420
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: rdoc
|
27
|
-
requirement: &
|
38
|
+
requirement: &70125546629980 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
40
|
requirements:
|
30
41
|
- - ~>
|
@@ -32,10 +43,10 @@ dependencies:
|
|
32
43
|
version: '3.12'
|
33
44
|
type: :development
|
34
45
|
prerelease: false
|
35
|
-
version_requirements: *
|
46
|
+
version_requirements: *70125546629980
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: bundler
|
38
|
-
requirement: &
|
49
|
+
requirement: &70125546627680 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ~>
|
@@ -43,10 +54,10 @@ dependencies:
|
|
43
54
|
version: '1.1'
|
44
55
|
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *70125546627680
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: jeweler
|
49
|
-
requirement: &
|
60
|
+
requirement: &70125546623080 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ~>
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: '1.8'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *70125546623080
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: simplecov
|
60
|
-
requirement: &
|
71
|
+
requirement: &70125546577740 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,10 +76,10 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *70125546577740
|
69
80
|
- !ruby/object:Gem::Dependency
|
70
81
|
name: cli
|
71
|
-
requirement: &
|
82
|
+
requirement: &70125546572940 !ruby/object:Gem::Requirement
|
72
83
|
none: false
|
73
84
|
requirements:
|
74
85
|
- - ~>
|
@@ -76,7 +87,7 @@ dependencies:
|
|
76
87
|
version: '1.0'
|
77
88
|
type: :development
|
78
89
|
prerelease: false
|
79
|
-
version_requirements: *
|
90
|
+
version_requirements: *70125546572940
|
80
91
|
description: This gem was created to enable control of interactive terminal applications.
|
81
92
|
It is using pseudo tty to communicate with the process via simple API.
|
82
93
|
email: jpastuszek@gmail.com
|
@@ -117,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
128
|
version: '0'
|
118
129
|
segments:
|
119
130
|
- 0
|
120
|
-
hash:
|
131
|
+
hash: -3155130806959499412
|
121
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
133
|
none: false
|
123
134
|
requirements:
|