dolzenko 0.0.13 → 0.0.14
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/lib/dolzenko/error_print.rb +4 -0
- data/lib/dolzenko/shell_out.rb +74 -43
- metadata +2 -2
data/lib/dolzenko/error_print.rb
CHANGED
data/lib/dolzenko/shell_out.rb
CHANGED
@@ -95,7 +95,26 @@ module ShellOut
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def command(*args)
|
98
|
-
|
98
|
+
stripped_command = args.dup
|
99
|
+
stripped_command.pop if stripped_command[-1].is_a?(Hash) # remove options
|
100
|
+
stripped_command.shift if stripped_command[0].is_a?(Hash) # remove env
|
101
|
+
stripped_command.join(" ")
|
102
|
+
end
|
103
|
+
|
104
|
+
def with_env(*args)
|
105
|
+
yield unless (env = args[0]).is_a?(Hash)
|
106
|
+
stored_env = {}
|
107
|
+
for name, value in env
|
108
|
+
stored_env[name] = ENV[name]
|
109
|
+
value == nil ? ENV.delete(name) : ENV[name] = value
|
110
|
+
end
|
111
|
+
begin
|
112
|
+
yield
|
113
|
+
ensure
|
114
|
+
for name, value in stored_env
|
115
|
+
ENV[name] = value
|
116
|
+
end
|
117
|
+
end
|
99
118
|
end
|
100
119
|
|
101
120
|
def getopt(opt, default, *args)
|
@@ -115,56 +134,62 @@ module ShellOut
|
|
115
134
|
|
116
135
|
def shell_out_with_pty(*args)
|
117
136
|
old_state = `stty -g`
|
137
|
+
|
118
138
|
return SUCCESS_EXIT_STATUS unless ShellOut::before(*args)
|
119
139
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
140
|
+
begin
|
141
|
+
# stolen from ruby/ext/pty/script.rb
|
142
|
+
# disable echoing and enable raw (not having to press enter)
|
143
|
+
system "stty -echo raw lnext ^_"
|
144
|
+
|
145
|
+
in_stream = ShellOut.getopt(:in, STDIN, *args)
|
146
|
+
out_stream = ShellOut.getopt(:out, STDOUT, *args)
|
147
|
+
writer = nil
|
148
|
+
ShellOut.with_env(*args) do
|
149
|
+
PTY.spawn(ShellOut.command(*args)) do |r_pty, w_pty, pid|
|
150
|
+
reader = Thread.current
|
151
|
+
writer = Thread.new do
|
152
|
+
while true
|
153
|
+
break if (ch = in_stream.getc).nil?
|
154
|
+
ch = ch.chr
|
155
|
+
if ch == ShellOut::CTRL_C_CODE
|
156
|
+
reader.raise Interrupt, "Interrupted by user"
|
157
|
+
else
|
158
|
+
w_pty.print ch
|
159
|
+
w_pty.flush
|
160
|
+
end
|
161
|
+
end
|
138
162
|
end
|
139
|
-
|
140
|
-
end
|
141
|
-
writer.abort_on_exception = true
|
163
|
+
writer.abort_on_exception = true
|
142
164
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
165
|
+
loop do
|
166
|
+
c = begin
|
167
|
+
r_pty.sysread(512)
|
168
|
+
rescue Errno::EIO, EOFError
|
169
|
+
nil
|
170
|
+
end
|
171
|
+
break if c.nil?
|
150
172
|
|
151
|
-
|
152
|
-
|
153
|
-
|
173
|
+
out_stream.print c
|
174
|
+
out_stream.flush
|
175
|
+
end
|
154
176
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
177
|
+
begin
|
178
|
+
# try to invoke waitpid() before the signal handler does it
|
179
|
+
return ShellOut::after(Process::waitpid2(pid)[1].exitstatus, out_stream, *args)
|
180
|
+
rescue Errno::ECHILD
|
181
|
+
# the signal handler managed to call waitpid() first;
|
182
|
+
# PTY::ChildExited will be delivered pretty soon, so just wait for it
|
183
|
+
sleep 1
|
184
|
+
end
|
185
|
+
end
|
162
186
|
end
|
187
|
+
rescue PTY::ChildExited => e
|
188
|
+
return ShellOut::after(e.status.exitstatus, out_stream, *args)
|
189
|
+
ensure
|
190
|
+
writer && writer.kill
|
191
|
+
system "stty #{ old_state }"
|
163
192
|
end
|
164
|
-
rescue PTY::ChildExited => e
|
165
|
-
return ShellOut::after(e.status.exitstatus, out_stream, *args)
|
166
|
-
ensure
|
167
|
-
system "stty #{ old_state }"
|
168
193
|
end
|
169
194
|
|
170
195
|
def shell_out_with_system(*args)
|
@@ -251,6 +276,12 @@ if $PROGRAM_NAME == __FILE__
|
|
251
276
|
end
|
252
277
|
end
|
253
278
|
|
279
|
+
it "alters command environment when first argument is a Hash" do
|
280
|
+
ShellOut({ "ENV_VAR" => "42" },
|
281
|
+
"ruby -e 'puts ENV.inspect'",
|
282
|
+
:out => :return).should include('"ENV_VAR"=>"42"')
|
283
|
+
end
|
284
|
+
|
254
285
|
describe ":raise_exceptions option" do
|
255
286
|
it "raises exception for non-zero exit codes" do
|
256
287
|
lambda do
|