right_popen 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 RightScale, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,119 @@
1
+ = RightPopen
2
+
3
+ == DESCRIPTION
4
+
5
+ === Synopsis
6
+
7
+ RightPopen allows running external processes aynchronously while still
8
+ capturing their standard and error outputs. It relies on EventMachine for most
9
+ of its internal mechanisms. The Linux implementation is valid for any Linux
10
+ platform but there is also a native implementation for Windows platforms.
11
+
12
+ Refer to the wiki (https://github.com/rightscale/right_popen/wikis) for up-to-date
13
+ documentation.
14
+
15
+ Also use the built-in issues tracker (https://github.com/rightscale/right_popen/issues)
16
+ to report issues.
17
+
18
+
19
+ == USAGE
20
+
21
+ === Simple Example
22
+
23
+ require 'rubygems'
24
+ require 'right_popen'
25
+
26
+ @stdout_text = ""
27
+ @stderr_text = ""
28
+ @exit_status = nil
29
+
30
+ def on_read_stdout(data)
31
+ @stdout_text << data
32
+ end
33
+
34
+ def on_read_stderr(data)
35
+ @stderr_text << data
36
+ end
37
+
38
+ def on_exit(status)
39
+ @exit_status = status
40
+ end
41
+
42
+ EM.run do
43
+ EM.next_tick do
44
+ cmd = "ruby -e \"puts 'some stdout text'; $stderr.puts 'some stderr text'\; exit 99\""
45
+ RightScale.popen3(cmd, self, :on_read_stdout, :on_read_stderr, :on_exit)
46
+ end
47
+ timer = EM::PeriodicTimer.new(0.1) do
48
+ if @exit_status
49
+ timer.cancel
50
+ EM.stop
51
+ end
52
+ end
53
+ end
54
+
55
+ puts "@stdout_text = #{@stdout_text}"
56
+ puts "@stderr_text = #{@stderr_text}"
57
+ puts "@exit_status.exitstatus = #{@exit_status.exitstatus}"
58
+
59
+
60
+ == INSTALLATION
61
+
62
+ RightPopen can be installed by entering the following at the command prompt:
63
+
64
+ gem install right_popen
65
+
66
+
67
+ == BUILDING
68
+
69
+ Install the following RubyGems required for building:
70
+ * rake
71
+
72
+ The Windows implementation relies on a native C module which must currently be
73
+ built using the MSVC 6.0 compiler due to a dependency on the standard libraries
74
+ FILE struct provided by the "msvcrt.dll".
75
+
76
+ The gem can be built on Linux or Windows platforms and will produce separate gem
77
+ files depending on current platform. Run the following command from the
78
+ directory containing the "Rakefile":
79
+
80
+ rake build_binary_gem
81
+
82
+
83
+ == TESTING
84
+
85
+ Install the following RubyGems required for testing:
86
+ * rspec
87
+
88
+ The build can be tested using the RSpec gem. Create a link to the installed
89
+ "spec" in your Ruby/bin directory (or ensure the bin directory is on the PATH
90
+ under Windows) and run the following command from the gem directory to execute
91
+ the RightPopen tests:
92
+
93
+ spec spec/right_popen_spec.rb
94
+
95
+
96
+ == LICENSE
97
+
98
+ <b>RightPopen</b>
99
+
100
+ Copyright:: Copyright (c) 2010 RightScale, Inc.
101
+
102
+ Permission is hereby granted, free of charge, to any person obtaining
103
+ a copy of this software and associated documentation files (the
104
+ 'Software'), to deal in the Software without restriction, including
105
+ without limitation the rights to use, copy, modify, merge, publish,
106
+ distribute, sublicense, and/or sell copies of the Software, and to
107
+ permit persons to whom the Software is furnished to do so, subject to
108
+ the following conditions:
109
+
110
+ The above copyright notice and this permission notice shall be
111
+ included in all copies or substantial portions of the Software.
112
+
113
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
114
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
115
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
116
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
117
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
118
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
119
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'fileutils'
3
+ require 'rake'
4
+ require 'rake/clean'
5
+ require 'rake/testtask'
6
+ require 'rbconfig'
7
+
8
+ include Config
9
+
10
+ desc "Clean any build files for right_popen"
11
+ task :clean do
12
+ if File.exists?('ext/Makefile')
13
+ Dir.chdir('ext') do
14
+ sh 'nmake distclean'
15
+ end
16
+ end
17
+ rm 'lib/win32/right_popen.so' if File.file?('lib/win32/right_popen.so')
18
+ end
19
+
20
+ desc "Build right_popen (but don't install it)"
21
+ task :build => [:clean] do
22
+ if RUBY_PLATFORM =~ /mswin/
23
+ Dir.chdir('ext') do
24
+ ruby 'extconf.rb'
25
+ sh 'nmake'
26
+ end
27
+ FileUtils::mkdir_p 'lib/win32'
28
+ mv 'ext/right_popen.so', 'lib/win32'
29
+ end
30
+ end
31
+
32
+ desc "Build a binary gem"
33
+ task :build_binary_gem => [:build] do
34
+ Dir["*.gem"].each { |gem| rm gem }
35
+ ruby 'right_popen.gemspec'
36
+ end
37
+
38
+ desc 'Install the right_popen library as a gem'
39
+ task :install_gem => [:build_binary_gem] do
40
+ file = Dir["*.gem"].first
41
+ sh "gem install #{file}"
42
+ end
43
+
44
+ desc 'Uninstalls and reinstalls the right_popen library as a gem'
45
+ task :reinstall_gem do
46
+ sh "gem uninstall right_popen"
47
+ sh "rake install_gem"
48
+ end
@@ -0,0 +1,139 @@
1
+ #
2
+ # Copyright (c) 2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ # RightScale.popen3 allows running external processes aynchronously
25
+ # while still capturing their standard and error outputs.
26
+ # It relies on EventMachine for most of its internal mechanisms.
27
+
28
+ require 'rubygems'
29
+ gem 'eventmachine', '=0.12.8' # has only been tested with 0.12.8
30
+ require 'eventmachine'
31
+
32
+ module RightScale
33
+
34
+ # Provides an eventmachine callback handler for the stdout stream.
35
+ module StdOutHandler
36
+
37
+ # === Parameters
38
+ # target(Object):: Object defining handler methods to be called.
39
+ #
40
+ # stdout_handler(String):: Token for stdout handler method name.
41
+ #
42
+ # exit_handler(String):: Token for exit handler method name.
43
+ #
44
+ # stderr_eventable(Connector):: EM object representing stderr handler.
45
+ #
46
+ # read_fd(IO):: Standard output read file descriptor.
47
+ #
48
+ # write_fd(IO):: Standard output write file descriptor.
49
+ def initialize(target, stdout_handler, exit_handler, stderr_eventable, read_fd, write_fd)
50
+ @target = target
51
+ @stdout_handler = stdout_handler
52
+ @exit_handler = exit_handler
53
+ @stderr_eventable = stderr_eventable
54
+ # Just so they don't get GCed before the process goes away
55
+ @read_fd = read_fd
56
+ @write_fd = write_fd
57
+ end
58
+
59
+ # Callback from EM to receive data.
60
+ def receive_data(data)
61
+ @target.method(@stdout_handler).call(data) if @stdout_handler
62
+ end
63
+
64
+ # Callback from EM to unbind.
65
+ def unbind
66
+ # We force the attached stderr handler to go away so that
67
+ # we don't end up with a broken pipe
68
+ @stderr_eventable.force_detach if @stderr_eventable
69
+ @target.method(@exit_handler).call(get_status) if @exit_handler
70
+ end
71
+ end
72
+
73
+ module StdErrHandler
74
+
75
+ # === Parameters
76
+ # target(Object):: Object defining handler methods to be called.
77
+ #
78
+ # stderr_handler(String):: Token for stderr handler method name.
79
+ def initialize(target, stderr_handler)
80
+ @target = target
81
+ @stderr_handler = stderr_handler
82
+ @unbound = false
83
+ end
84
+
85
+ # Callback from EM to receive data.
86
+ def receive_data(data)
87
+ @target.method(@stderr_handler).call(data)
88
+ end
89
+
90
+ # Callback from EM to unbind.
91
+ def unbind
92
+ @unbound = true
93
+ end
94
+
95
+ # Forces detachment of the stderr handler on EM's next tick.
96
+ def force_detach
97
+ # Use next tick to prevent issue in EM where descriptors list
98
+ # gets out-of-sync when calling detach in an unbind callback
99
+ EM.next_tick { detach unless @unbound }
100
+ end
101
+ end
102
+
103
+ # Forks process to run given command asynchronously, hooking all three
104
+ # standard streams of the child process.
105
+ #
106
+ # Streams the command's stdout and stderr to the given handlers. Time-
107
+ # ordering of bytes sent to stdout and stderr is not preserved.
108
+ #
109
+ # Calls given exit handler upon command process termination, passing in the
110
+ # resulting Process::Status.
111
+ #
112
+ # All handlers must be methods exposed by the given target.
113
+ #
114
+ # === Parameters
115
+ # cmd(String):: command to execute, including any arguments.
116
+ #
117
+ # target(Object):: object defining handler methods to be called.
118
+ #
119
+ # stdout_handler(String):: token for stdout handler method name.
120
+ #
121
+ # stderr_handler(String):: token for stderr handler method name.
122
+ #
123
+ # exit_handler(String):: token for exit handler method name.
124
+ def self.popen3(cmd, target, stdout_handler = nil, stderr_handler = nil, exit_handler = nil)
125
+ raise "EventMachine reactor must be started" unless EM.reactor_running?
126
+ EM.next_tick do
127
+ saved_stderr = $stderr.dup
128
+ r, w = Socket::pair(Socket::AF_LOCAL, Socket::SOCK_STREAM, 0)#IO::pipe
129
+
130
+ $stderr.reopen w
131
+ c = EM.attach(r, StdErrHandler, target, stderr_handler) if stderr_handler
132
+ EM.popen(cmd, StdOutHandler, target, stdout_handler, exit_handler, c, r, w)
133
+ # Do not close 'w', strange things happen otherwise
134
+ # (command protocol socket gets closed during decommission)
135
+ $stderr.reopen saved_stderr
136
+ end
137
+ end
138
+
139
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ # Copyright (c) 2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ # RightScale.popen3 allows running external processes aynchronously
25
+ # while still capturing their standard and error outputs.
26
+ # It relies on EventMachine for most of its internal mechanisms.
27
+
28
+ if RUBY_PLATFORM =~ /mswin/
29
+ require File.expand_path(File.join(File.dirname(__FILE__), 'win32', 'right_popen'))
30
+ else
31
+ require File.expand_path(File.join(File.dirname(__FILE__), 'linux', 'right_popen'))
32
+ end
@@ -0,0 +1,59 @@
1
+ require 'rubygems'
2
+
3
+ spec = Gem::Specification.new do |spec|
4
+ is_windows = RUBY_PLATFORM =~ /mswin/
5
+
6
+ spec.name = 'right_popen'
7
+ spec.version = '1.0.1'
8
+ spec.authors = ['Scott Messier', 'Raphael Simon']
9
+ spec.email = 'scott@rightscale.com'
10
+ spec.homepage = 'https://github.com/rightscale/right_popen'
11
+ if is_windows
12
+ spec.platform = 'x86-mswin32-60'
13
+ else
14
+ spec.platform = Gem::Platform::RUBY
15
+ end
16
+ spec.summary = 'Provides a platform-independent popen implementation'
17
+ spec.has_rdoc = true
18
+ spec.rdoc_options = ["--main", "README.rdoc", "--title", "RightPopen"]
19
+ spec.extra_rdoc_files = ["README.rdoc"]
20
+ spec.required_ruby_version = '>= 1.8.6'
21
+ spec.rubyforge_project = %q{right_popen}
22
+
23
+ spec.description = <<-EOF
24
+ RightPopen allows running external processes aynchronously while still
25
+ capturing their standard and error outputs. It relies on EventMachine for most
26
+ of its internal mechanisms. The Linux implementation is valid for any Linux
27
+ platform but there is also a native implementation for Windows platforms.
28
+ EOF
29
+
30
+ if is_windows
31
+ extension_dir = "ext,"
32
+ else
33
+ extension_dir = ""
34
+ end
35
+ candidates = Dir.glob("{#{extension_dir}lib,spec}/**/*") +
36
+ ["LICENSE", "README.rdoc", "Rakefile", "right_popen.gemspec"]
37
+ candidates = candidates.delete_if do |item|
38
+ item.include?("Makefile") || item.include?(".obj") || item.include?(".pdb") || item.include?(".def") || item.include?(".exp") || item.include?(".lib")
39
+ end
40
+ candidates = candidates.delete_if do |item|
41
+ if is_windows
42
+ item.include?("/linux/")
43
+ else
44
+ item.include?("/win32/")
45
+ end
46
+ end
47
+ spec.files = candidates.sort!
48
+
49
+ # Current implementation doesn't support > 0.12.8, but support any patched 0.12.8.x versions.
50
+ spec.add_runtime_dependency(%q<eventmachine>, [">= 0.12.8", "< 0.12.9"])
51
+ if is_windows
52
+ spec.add_runtime_dependency(%q<win32-process>, [">= 0.6.1"])
53
+ end
54
+ end
55
+
56
+ if $PROGRAM_NAME == __FILE__
57
+ Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
58
+ Gem::Builder.new(spec).build
59
+ end
@@ -0,0 +1,8 @@
1
+ count = ARGV[0] ? ARGV[0].to_i : 1
2
+
3
+ count.times do |i|
4
+ $stderr.puts "stderr #{i}" if 0 == i % 10
5
+ $stdout.puts "stdout #{i}"
6
+ end
7
+
8
+ exit 99
@@ -0,0 +1,2 @@
1
+ $stdout.puts ARGV[0]
2
+ $stderr.puts ARGV[1]
@@ -0,0 +1 @@
1
+ exit ARGV[0].to_i
@@ -0,0 +1,5 @@
1
+ count = ARGV[0] ? ARGV[0].to_i : 1
2
+
3
+ count.times do |i|
4
+ $stderr.puts "stderr #{i}"
5
+ end
@@ -0,0 +1,5 @@
1
+ count = ARGV[0] ? ARGV[0].to_i : 1
2
+
3
+ count.times do |i|
4
+ $stdout.puts "stdout #{i}"
5
+ end
@@ -0,0 +1,125 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'right_popen'
3
+
4
+ RUBY_CMD = 'ruby'
5
+ STANDARD_MESSAGE = 'Standard message'
6
+ ERROR_MESSAGE = 'Error message'
7
+ EXIT_STATUS = 146
8
+
9
+ # manually bump count up for more aggressive multi-processor testing, lessen
10
+ # for a quick smoke test
11
+ LARGE_OUTPUT_COUNTER = 1000
12
+
13
+ describe 'RightScale::popen3' do
14
+
15
+ module RightPopenSpec
16
+
17
+ class Runner
18
+ def initialize
19
+ @done = false
20
+ @output_text = ''
21
+ @error_text = ''
22
+ @status = nil
23
+ end
24
+
25
+ attr_reader :output_text, :error_text, :status
26
+
27
+ def run_right_popen(command)
28
+ EM.next_tick do
29
+ RightScale.popen3(command, self, :on_read_stdout, :on_read_stderr, :on_exit)
30
+ end
31
+ EM.run do
32
+ timer = EM::PeriodicTimer.new(0.1) do
33
+ if @done
34
+ timer.cancel
35
+ EM.stop
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def on_read_stdout(data)
42
+ @output_text << data
43
+ end
44
+
45
+ def on_read_stderr(data)
46
+ @error_text << data
47
+ end
48
+
49
+ def on_exit(status)
50
+ @status = status
51
+ @done = true
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ it 'should redirect output' do
58
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
59
+ runner = RightPopenSpec::Runner.new
60
+ runner.run_right_popen(command)
61
+ runner.status.exitstatus.should == 0
62
+ runner.output_text.should == STANDARD_MESSAGE + "\n"
63
+ runner.error_text.should == ERROR_MESSAGE + "\n"
64
+ end
65
+
66
+ it 'should return the right status' do
67
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb'))}\" #{EXIT_STATUS}"
68
+ runner = RightPopenSpec::Runner.new
69
+ runner.run_right_popen(command)
70
+ runner.status.exitstatus.should == EXIT_STATUS
71
+ runner.output_text.should == ''
72
+ runner.error_text.should == ''
73
+ end
74
+
75
+ it 'should preserve the integrity of stdout when stderr is unavailable' do
76
+ count = LARGE_OUTPUT_COUNTER
77
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stdout_only.rb'))}\" #{count}"
78
+ runner = RightPopenSpec::Runner.new
79
+ runner.run_right_popen(command)
80
+ runner.status.exitstatus.should == 0
81
+
82
+ results = ''
83
+ count.times do |i|
84
+ results << "stdout #{i}\n"
85
+ end
86
+ runner.output_text.should == results
87
+ runner.error_text.should == ''
88
+ end
89
+
90
+ it 'should preserve the integrity of stderr when stdout is unavailable' do
91
+ count = LARGE_OUTPUT_COUNTER
92
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stderr_only.rb'))}\" #{count}"
93
+ runner = RightPopenSpec::Runner.new
94
+ runner.run_right_popen(command)
95
+ runner.status.exitstatus.should == 0
96
+
97
+ results = ''
98
+ count.times do |i|
99
+ results << "stderr #{i}\n"
100
+ end
101
+ runner.error_text.should == results
102
+ runner.output_text.should == ''
103
+ end
104
+
105
+ it 'should preserve the integrity of stdout and stderr despite interleaving' do
106
+ count = LARGE_OUTPUT_COUNTER
107
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{count}"
108
+ runner = RightPopenSpec::Runner.new
109
+ runner.run_right_popen(command)
110
+ runner.status.exitstatus.should == 99
111
+
112
+ results = ''
113
+ count.times do |i|
114
+ results << "stdout #{i}\n"
115
+ end
116
+ runner.output_text.should == results
117
+
118
+ results = ''
119
+ count.times do |i|
120
+ (results << "stderr #{i}\n") if 0 == i % 10
121
+ end
122
+ runner.error_text.should == results
123
+ end
124
+
125
+ end
@@ -0,0 +1,2 @@
1
+ require 'rubygems'
2
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: right_popen
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Scott Messier
8
+ - Raphael Simon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-01-27 00:00:00 -08:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: eventmachine
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.12.8
25
+ - - <
26
+ - !ruby/object:Gem::Version
27
+ version: 0.12.9
28
+ version:
29
+ description: |
30
+ RightPopen allows running external processes aynchronously while still
31
+ capturing their standard and error outputs. It relies on EventMachine for most
32
+ of its internal mechanisms. The Linux implementation is valid for any Linux
33
+ platform but there is also a native implementation for Windows platforms.
34
+
35
+ email: scott@rightscale.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - README.rdoc
42
+ files:
43
+ - LICENSE
44
+ - README.rdoc
45
+ - Rakefile
46
+ - lib/linux/right_popen.rb
47
+ - lib/right_popen.rb
48
+ - right_popen.gemspec
49
+ - spec/produce_mixed_output.rb
50
+ - spec/produce_output.rb
51
+ - spec/produce_status.rb
52
+ - spec/produce_stderr_only.rb
53
+ - spec/produce_stdout_only.rb
54
+ - spec/right_popen_spec.rb
55
+ - spec/spec_helper.rb
56
+ has_rdoc: true
57
+ homepage: https://github.com/rightscale/right_popen
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options:
62
+ - --main
63
+ - README.rdoc
64
+ - --title
65
+ - RightPopen
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.8.6
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project: right_popen
83
+ rubygems_version: 1.3.2
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Provides a platform-independent popen implementation
87
+ test_files: []
88
+