em-systemcommand 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/em-systemcommand/pipe.rb +68 -7
- data/lib/em-systemcommand/version.rb +1 -1
- data/spec/em-systemcommand/pipe_spec.rb +21 -0
- metadata +3 -3
@@ -1,18 +1,23 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
module EventMachine
|
2
3
|
class SystemCommand
|
3
4
|
class Pipe < EM::Connection
|
4
5
|
|
5
|
-
def initialize
|
6
|
+
def initialize master, name
|
6
7
|
@master = master
|
7
8
|
@name = name
|
8
9
|
@master.pipes[name] = self
|
9
10
|
begin
|
10
|
-
@outputbuffer = StringIO.new
|
11
|
+
@outputbuffer = StringIO.new
|
11
12
|
rescue Exception => e
|
12
13
|
puts "Uninitialized constant StringIO. This may happen when you forgot to use bundler. Use `bundle exec`."
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
17
|
+
##
|
18
|
+
# The content of the output buffer as string.
|
19
|
+
#
|
20
|
+
# @return [String] The connections output
|
16
21
|
def output
|
17
22
|
@outputbuffer.string
|
18
23
|
end
|
@@ -20,6 +25,10 @@ module EventMachine
|
|
20
25
|
##
|
21
26
|
# Convenience method to create a callback that matches a regular
|
22
27
|
# expression
|
28
|
+
#
|
29
|
+
# @param [Regexp] regexp The regular expression that should be matched
|
30
|
+
# @option opt [Symbol] :in Match either in `:line` or `:output`
|
31
|
+
# @option opt [Symbol] :match Match either `:first` or `:last`
|
23
32
|
def match regexp, opt = {}, &block
|
24
33
|
opt = { in: :line, match: :first }.merge opt
|
25
34
|
(opt[:in] == :output ? receive_update_callbacks : receive_line_callbacks) << lambda do |data|
|
@@ -35,68 +44,115 @@ module EventMachine
|
|
35
44
|
end
|
36
45
|
end
|
37
46
|
|
47
|
+
##
|
38
48
|
# Invoked when line was received
|
49
|
+
#
|
50
|
+
# @param [String] line The line that´s received
|
39
51
|
def receive_line line
|
40
52
|
receive_line_callbacks.each do |callback|
|
41
53
|
callback.call line.dup
|
42
54
|
end
|
43
55
|
end
|
44
56
|
|
57
|
+
##
|
45
58
|
# Adds a callback for `receive_line` events.
|
59
|
+
#
|
60
|
+
# @yield The callback that should be added to callback array for line events
|
61
|
+
# @yieldparam [String] line The line that has been received
|
46
62
|
def line &block
|
47
63
|
receive_line_callbacks << block
|
48
64
|
end
|
49
65
|
|
66
|
+
##
|
50
67
|
# Invoked when a line was written, but `\r` was received without
|
51
68
|
# a line-break in the end.
|
69
|
+
#
|
70
|
+
# @param [String] buffer The complete buffer content of this connection
|
52
71
|
def receive_update buffer
|
53
72
|
receive_update_callbacks.each do |callback|
|
54
73
|
callback.call buffer.dup
|
55
74
|
end
|
56
75
|
end
|
57
76
|
|
77
|
+
##
|
58
78
|
# Adds a callback for `receive_update` events.
|
79
|
+
#
|
80
|
+
# @yield The callback that should be added to callback array for update events
|
81
|
+
# @yieldparam [String] buffer The complete buffer content of this connection
|
59
82
|
def update &block
|
60
83
|
receive_update_callbacks << block
|
61
84
|
end
|
62
85
|
|
86
|
+
##
|
63
87
|
# Invoked when data was received.
|
88
|
+
#
|
89
|
+
# @param [String] data The received data
|
64
90
|
def receive_data data, recursive = false
|
91
|
+
# if recursive is true we already invoked the receive data callbacks!
|
65
92
|
unless recursive
|
66
93
|
receive_data_callbacks.each do |callback|
|
67
94
|
callback.call data.dup
|
68
95
|
end
|
69
96
|
end
|
70
97
|
@linebuffer ||= []
|
71
|
-
@
|
98
|
+
@lf_offset ||= 0
|
72
99
|
|
73
100
|
parse_crlf data
|
74
101
|
|
75
102
|
receive_update @outputbuffer.string unless recursive
|
76
103
|
end
|
77
104
|
|
105
|
+
##
|
106
|
+
# Parses carriage return when data is received.
|
107
|
+
#
|
108
|
+
# @param [String] data The received data
|
109
|
+
# @param [Integer] ix The index of the carriage return
|
78
110
|
def parse_cr data, ix
|
79
111
|
ln = (@linebuffer << data[0...ix]).join
|
80
112
|
@linebuffer.clear
|
113
|
+
|
81
114
|
receive_line ln
|
82
115
|
@outputbuffer.print ln
|
83
|
-
|
84
|
-
|
116
|
+
|
117
|
+
# jump back to the last line feed
|
118
|
+
@outputbuffer.pos = @lf_offset
|
119
|
+
|
120
|
+
# parse rest of the data
|
121
|
+
parse_crlf data[(ix+1)..-1]
|
85
122
|
end
|
86
123
|
|
124
|
+
##
|
125
|
+
# Parses line feed when data is received.
|
126
|
+
#
|
127
|
+
# @param [String] data The received data
|
128
|
+
# @param [Integer] ix The index of the line feed
|
87
129
|
def parse_lf data, ix
|
88
130
|
ln = (@linebuffer << data[0...ix]).join
|
89
131
|
@linebuffer.clear
|
90
132
|
ln.chomp!
|
133
|
+
|
91
134
|
receive_line ln
|
92
135
|
@outputbuffer.print ln
|
136
|
+
|
137
|
+
# jump to the end of the buffer to keep the characters, that
|
138
|
+
# may already have been written
|
93
139
|
@outputbuffer.pos = @outputbuffer.length
|
140
|
+
# print the line feed
|
94
141
|
@outputbuffer.puts
|
95
|
-
|
96
|
-
|
142
|
+
# set last line feed to the current cursor position, so we
|
143
|
+
# know where we have to jump back, when a carriage return occurs
|
144
|
+
@lf_offset = @outputbuffer.pos
|
145
|
+
|
146
|
+
# parse rest of the data
|
147
|
+
parse_crlf data[(ix+1)..-1]
|
97
148
|
end
|
98
149
|
|
150
|
+
##
|
151
|
+
# Parse received data for line feeds or carriage returns.
|
152
|
+
#
|
153
|
+
# @param [String] data The received data
|
99
154
|
def parse_crlf data
|
155
|
+
return if data == ''
|
100
156
|
if ilf = data.index("\n")
|
101
157
|
# if we find a LF and that LF is after a CR we first handle
|
102
158
|
# the CR
|
@@ -115,11 +171,16 @@ module EventMachine
|
|
115
171
|
end
|
116
172
|
end
|
117
173
|
|
174
|
+
##
|
118
175
|
# Adds a callback for `receive_data` events.
|
176
|
+
#
|
177
|
+
# @yield The callback that´s to be added to the data callback array
|
178
|
+
# @yieldparam [String] data The data that´s received
|
119
179
|
def data &block
|
120
180
|
receive_data_callbacks << block
|
121
181
|
end
|
122
182
|
|
183
|
+
##
|
123
184
|
# Close the attached IO object.
|
124
185
|
def close
|
125
186
|
begin
|
@@ -2,6 +2,27 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'Pipe' do
|
4
4
|
|
5
|
+
context 'parsing' do
|
6
|
+
|
7
|
+
it 'should handle carriage returns' do
|
8
|
+
cmd = EM::SystemCommand.new 'exit 0;'
|
9
|
+
pipe = EM::SystemCommand::Pipe.new(nil, cmd, :stdout)
|
10
|
+
pipe.receive_data "test\n"
|
11
|
+
pipe.receive_data " 32768 0% 0.00kB/s 0:00:00\r"
|
12
|
+
pipe.receive_data " 131235840 12% 125.12MB/s 0:00:06\r"
|
13
|
+
pipe.receive_data " 261619712 25% 124.80MB/s 0:00:05\r"
|
14
|
+
pipe.receive_data " 391544832 38% 124.54MB/s 0:00:04\r"
|
15
|
+
pipe.receive_data " 522616832 51% 124.69MB/s 0:00:03\r"
|
16
|
+
pipe.receive_data " 652738560 63% 124.43MB/s 0:00:02\r"
|
17
|
+
pipe.receive_data " 783056896 76% 124.41MB/s 0:00:01\r"
|
18
|
+
pipe.receive_data " 906657792 88% 122.90MB/s 0:00:00\r"
|
19
|
+
pipe.receive_data " 1024000000 100% 123.67MB/s 0:00:07 (xfer#1, to-check=0/1)\n"
|
20
|
+
pipe.receive_data "\n"
|
21
|
+
pipe.receive_data "sent 1024125065 bytes received 31 bytes 120485305.41 bytes/sec\ntotal size is 1024000000 speedup is 1.00\n"
|
22
|
+
pipe.output.should == "test\n 1024000000 100% 123.67MB/s 0:00:07 (xfer#1, to-check=0/1)\n\nsent 1024125065 bytes received 31 bytes 120485305.41 bytes/sec\ntotal size is 1024000000 speedup is 1.00\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
5
26
|
context '#receive_data' do
|
6
27
|
it 'should correctly do a carriage return in the output buffer' do
|
7
28
|
EM.run do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-systemcommand
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -163,7 +163,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
163
|
version: '0'
|
164
164
|
segments:
|
165
165
|
- 0
|
166
|
-
hash:
|
166
|
+
hash: -2179568276682517415
|
167
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
168
|
none: false
|
169
169
|
requirements:
|
@@ -172,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
172
|
version: '0'
|
173
173
|
segments:
|
174
174
|
- 0
|
175
|
-
hash:
|
175
|
+
hash: -2179568276682517415
|
176
176
|
requirements: []
|
177
177
|
rubyforge_project:
|
178
178
|
rubygems_version: 1.8.24
|