about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-08-26 00:35:03 +0000
committerEric Wong <normalperson@yhbt.net>2013-08-26 00:40:52 +0000
commit6d67d9c2af57233743187a92b7e651174d6eb42b (patch)
tree2c174e81b241de8d30786180e98e6d5f9979bd60
parenta1198562c51c5374a85d74e1cfe9e6a695384a3d (diff)
downloaddtas-6d67d9c2af57233743187a92b7e651174d6eb42b.tar.gz
I forgot :err is already handled by Process.spawn, so split out
the functionality into err_str where we want to use it.

Also, add a :no_raise flag which will allow us to better handle
avprobe/soxi calls which can fail and avoid needless exceptions.
-rw-r--r--lib/dtas/process.rb16
-rw-r--r--lib/dtas/source/av.rb4
-rw-r--r--lib/dtas/source/sox.rb4
-rw-r--r--test/test_process.rb29
4 files changed, 38 insertions, 15 deletions
diff --git a/lib/dtas/process.rb b/lib/dtas/process.rb
index c19b5c5..2cf59c7 100644
--- a/lib/dtas/process.rb
+++ b/lib/dtas/process.rb
@@ -46,7 +46,8 @@ module DTAS::Process # :nodoc:
     r, w = IO.pipe
     opts = opts.merge(out: w)
     r.binmode
-    if err = opts[:err]
+    no_raise = opts.delete(:no_raise)
+    if err_str = opts.delete(:err_str)
       re, we = IO.pipe
       re.binmode
       opts[:err] = we
@@ -57,16 +58,15 @@ module DTAS::Process # :nodoc:
       retry
     end
     w.close
-    if err
+    if err_str
       we.close
       res = ""
-      want = { r => res, re => err }
+      want = { r => res, re => err_str }
       begin
         readable = IO.select(want.keys) or next
         readable[0].each do |io|
-          bytes = io.nread
           begin
-            want[io] << io.read_nonblock(bytes > 0 ? bytes : 11)
+            want[io] << io.read_nonblock(2000)
           rescue Errno::EAGAIN
             # spurious wakeup, bytes may be zero
           rescue EOFError
@@ -76,12 +76,14 @@ module DTAS::Process # :nodoc:
       end until want.empty?
       re.close
     else
-      res = r.read
+      res = r.read # read until EOF
     end
     r.close
     _, status = Process.waitpid2(pid)
     return res if status.success?
-    raise RuntimeError, "`#{Shellwords.join(cmd)}' failed: #{status.inspect}"
+    return status if no_raise
+    raise RuntimeError,
+          "`#{Shellwords.join(Array(cmd))}' failed: #{status.inspect}"
   end
 
   # XXX only for DTAS::Source::{Sox,Av}.try
diff --git a/lib/dtas/source/av.rb b/lib/dtas/source/av.rb
index 1de0a72..66ee320 100644
--- a/lib/dtas/source/av.rb
+++ b/lib/dtas/source/av.rb
@@ -25,7 +25,7 @@ class DTAS::Source::Av # :nodoc:
 
   def self.try(infile, offset = nil)
     err = ""
-    DTAS::Process.qx(%W(avprobe #{infile}), err: err)
+    DTAS::Process.qx(%W(avprobe #{infile}), err_str: err)
     return if err =~ /Unable to find a suitable output format for/
     new(infile, offset)
   rescue
@@ -44,7 +44,7 @@ class DTAS::Source::Av # :nodoc:
     @format.bits = @precision
     @comments = {}
     err = ""
-    s = qx(%W(avprobe -show_streams -show_format #@infile), err: err)
+    s = qx(%W(avprobe -show_streams -show_format #@infile), err_str: err)
     @astreams = []
     s.scan(%r{^\[STREAM\]\n(.*?)\n\[/STREAM\]\n}m) do |_|
       stream = $1
diff --git a/lib/dtas/source/sox.rb b/lib/dtas/source/sox.rb
index 086b923..30e7f18 100644
--- a/lib/dtas/source/sox.rb
+++ b/lib/dtas/source/sox.rb
@@ -19,7 +19,7 @@ class DTAS::Source::Sox # :nodoc:
 
   def self.try(infile, offset = nil)
     err = ""
-    DTAS::Process.qx(%W(soxi #{infile}), err: err)
+    DTAS::Process.qx(%W(soxi #{infile}), err_str: err)
     return if err =~ /soxi FAIL formats:/
     new(infile, offset)
   rescue
@@ -69,7 +69,7 @@ class DTAS::Source::Sox # :nodoc:
       err = ""
       cmd = %W(soxi -a #@infile)
       begin
-        qx(cmd, err: err).split(/\n/).each do |line|
+        qx(cmd, err_str: err).split(/\n/).each do |line|
           key, value = line.split(/=/, 2)
           key && value or next
           # TODO: multi-line/multi-value/repeated tags
diff --git a/test/test_process.rb b/test/test_process.rb
index a480312..012f18f 100644
--- a/test/test_process.rb
+++ b/test/test_process.rb
@@ -4,9 +4,30 @@
 require './test/helper'
 require 'dtas/process'
 class TestProcess < Minitest::Unit::TestCase
- include DTAS::Process
+  include DTAS::Process
 
- def test_qx_env
-   assert_equal "WORLD\n", qx({"HELLO" => "WORLD"}, 'echo $HELLO')
- end
+  def test_qx_env
+    assert_equal "WORLD\n", qx({"HELLO" => "WORLD"}, 'echo $HELLO')
+  end
+
+  def test_qx_err
+    err = "/dev/null"
+    assert_equal "", qx('echo HELLO >&2', err: err)
+    assert_equal "/dev/null", err
+  end
+
+  def test_qx_err_str
+    s = ""
+    assert_equal "", qx('echo HELLO >&2', err_str: s)
+    assert_equal "HELLO\n", s
+  end
+
+  def test_qx_raise
+    assert_raises(RuntimeError) { qx('false') }
+  end
+
+  def test_qx_no_raise
+    status = qx('false', no_raise: true)
+    refute status.success?, status.inspect
+  end
 end