17
17
require 'json'
18
18
require 'timeout'
19
19
require 'yaml'
20
- require 'open3'
21
20
require 'rbconfig'
22
21
require 'pathname'
23
22
@@ -288,22 +287,24 @@ def diff(expected, actual)
288
287
`diff -u #{ expected } #{ actual } `
289
288
end
290
289
291
- def system_timeout ( timeout , *args )
292
- begin
293
- pid = Process . spawn ( *args )
294
- rescue SystemCallError
295
- return nil
296
- end
290
+ def raw_sh_failed_status
291
+ `false`
292
+ $?
293
+ end
297
294
298
- begin
299
- Timeout . timeout timeout do
300
- Process . waitpid pid
301
- $?. success?
295
+ def raw_sh_with_timeout ( timeout , pid )
296
+ if !timeout
297
+ yield
298
+ else
299
+ begin
300
+ Timeout . timeout ( timeout ) do
301
+ yield
302
+ end
303
+ rescue Timeout ::Error
304
+ Process . kill ( 'TERM' , pid )
305
+ yield # Wait and read the pipe if capture: true
306
+ :timeout
302
307
end
303
- rescue Timeout ::Error
304
- Process . kill ( 'TERM' , pid )
305
- Process . waitpid pid
306
- nil
307
308
end
308
309
end
309
310
@@ -318,43 +319,49 @@ def raw_sh(*args)
318
319
STDERR . puts "$ #{ printable_cmd ( args ) } "
319
320
end
320
321
321
- if use_exec
322
- result = exec ( *args )
323
- elsif timeout
324
- result = system_timeout ( timeout , *args )
325
- elsif capture
326
- if options . delete ( :err ) == :out
327
- out , status = Open3 . capture2e ( *args )
328
- else
329
- out = IO . popen ( args ) { |io | io . read }
330
- status = $?
331
- end
332
- result = status . success?
322
+ exec ( *args ) if use_exec
323
+
324
+ if capture
325
+ raise ":capture can only be combined with :err => :out" if options . include? ( :out )
326
+ pipe_r , pipe_w = IO . pipe
327
+ options [ :out ] = pipe_w
328
+ options [ :err ] = pipe_w if options [ :err ] == :out
329
+ end
330
+
331
+ status = nil
332
+ out = nil
333
+ begin
334
+ pid = Process . spawn ( *args )
335
+ rescue Errno ::ENOENT # No such executable
336
+ status = raw_sh_failed_status
333
337
else
334
- result = system ( *args )
338
+ pipe_w . close if capture
339
+
340
+ result = raw_sh_with_timeout ( timeout , pid ) do
341
+ out = pipe_r . read if capture
342
+ _ , status = Process . waitpid2 ( pid )
343
+ end
344
+ if result == :timeout
345
+ status = raw_sh_failed_status
346
+ end
347
+ end
348
+
349
+ result = status . success?
350
+
351
+ if capture
352
+ pipe_r . close
335
353
end
336
354
337
- if result
355
+ if status . success? || continue_on_failure
338
356
if capture
339
357
out
340
358
else
341
- true
359
+ status . success?
342
360
end
343
- elsif continue_on_failure
344
- false
345
361
else
346
- status = $? unless capture
347
362
$stderr. puts "FAILED (#{ status } ): #{ printable_cmd ( args ) } "
348
-
349
- if capture
350
- $stderr. puts out
351
- end
352
-
353
- if status && status . exitstatus
354
- exit status . exitstatus
355
- else
356
- exit 1
357
- end
363
+ $stderr. puts out if capture
364
+ exit status . to_i
358
365
end
359
366
end
360
367
0 commit comments