aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2012-11-08 18:10:54 -0800
committerCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2012-11-08 18:10:54 -0800
commitb67a03cf0b58d311b915af2d4b36012b5f394fea (patch)
treeb51b5c35153edcb64d172fe25cbc869c654beff1 /activesupport
parent72f5085404965f4762ecc67839bb5c93db73c8aa (diff)
parent346ccf376c13bef58e575474a2f717b78dfa583d (diff)
downloadrails-b67a03cf0b58d311b915af2d4b36012b5f394fea.tar.gz
rails-b67a03cf0b58d311b915af2d4b36012b5f394fea.tar.bz2
rails-b67a03cf0b58d311b915af2d4b36012b5f394fea.zip
Merge pull request #7763 from route/full-capture
Kernel#capture replaced by version which can catch output from subprocesses
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md1
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/reporting.rb37
-rw-r--r--activesupport/test/core_ext/kernel_test.rb2
3 files changed, 29 insertions, 11 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 0781abb6ed..61d85543d1 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,4 +1,5 @@
## Rails 4.0.0 (unreleased) ##
+* Kernel#capture can catch output from subprocesses *Dmitry Vorotilin*
* `to_xml` conversions now use builder's `tag!` method instead of explicit invocation of `method_missing`.
diff --git a/activesupport/lib/active_support/core_ext/kernel/reporting.rb b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
index bc97da6ef2..7b518821c8 100644
--- a/activesupport/lib/active_support/core_ext/kernel/reporting.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
@@ -1,4 +1,5 @@
require 'rbconfig'
+require 'tempfile'
module Kernel
# Sets $VERBOSE to nil for the duration of the block and back to its original
@@ -66,19 +67,33 @@ module Kernel
# Captures the given stream and returns it:
#
- # stream = capture(:stdout) { puts 'Cool' }
- # stream # => "Cool\n"
+ # stream = capture(:stdout) { puts 'notice' }
+ # stream # => "notice\n"
+ #
+ # stream = capture(:stderr) { warn 'error' }
+ # stream # => "error\n"
+ #
+ # even for subprocesses:
+ #
+ # stream = capture(:stdout) { system('echo notice') }
+ # stream # => "notice\n"
+ #
+ # stream = capture(:stderr) { system('echo error 1>&2') }
+ # stream # => "error\n"
def capture(stream)
- begin
- stream = stream.to_s
- eval "$#{stream} = StringIO.new"
- yield
- result = eval("$#{stream}").string
- ensure
- eval("$#{stream} = #{stream.upcase}")
- end
+ stream = stream.to_s
+ captured_stream = Tempfile.new(stream)
+ stream_io = eval("$#{stream}")
+ origin_stream = stream_io.dup
+ stream_io.reopen(captured_stream)
+
+ yield
- result
+ stream_io.rewind
+ return captured_stream.read
+ ensure
+ captured_stream.unlink
+ stream_io.reopen(origin_stream)
end
alias :silence :capture
diff --git a/activesupport/test/core_ext/kernel_test.rb b/activesupport/test/core_ext/kernel_test.rb
index 439bc87323..1583c1fa32 100644
--- a/activesupport/test/core_ext/kernel_test.rb
+++ b/activesupport/test/core_ext/kernel_test.rb
@@ -51,6 +51,8 @@ class KernelTest < ActiveSupport::TestCase
def test_capture
assert_equal 'STDERR', capture(:stderr) { $stderr.print 'STDERR' }
assert_equal 'STDOUT', capture(:stdout) { print 'STDOUT' }
+ assert_equal "STDERR\n", capture(:stderr) { system('echo STDERR 1>&2') }
+ assert_equal "STDOUT\n", capture(:stdout) { system('echo STDOUT') }
end
end