awesome_spawn 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of awesome_spawn might be problematic. Click here for more details.

@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
@@ -0,0 +1 @@
1
+ --markup markdown
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in awesome_spawn.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Red Hat, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # AwesomeSpawn
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/awesome_spawn.png)](http://badge.fury.io/rb/awesome_spawn)
4
+ [![Build Status](https://travis-ci.org/ManageIQ/awesome_spawn.png)](https://travis-ci.org/ManageIQ/awesome_spawn)
5
+ [![Code Climate](https://codeclimate.com/github/ManageIQ/awesome_spawn.png)](https://codeclimate.com/github/ManageIQ/awesome_spawn)
6
+ [![Coverage Status](https://coveralls.io/repos/ManageIQ/awesome_spawn/badge.png?branch=master)](https://coveralls.io/r/ManageIQ/awesome_spawn)
7
+ [![Dependency Status](https://gemnasium.com/ManageIQ/awesome_spawn.png)](https://gemnasium.com/ManageIQ/awesome_spawn)
8
+
9
+ AwesomeSpawn is a module that provides some useful features over Ruby's Kernel.spawn.
10
+
11
+ Some additional features include...
12
+
13
+ - Parameter passing as a Hash or associative Array sanitizing them to prevent command line injection.
14
+ - Results returned as an object giving access to the output stream, error stream, and exit status.
15
+ - Optionally raising an exception when exit status is not 0.
16
+
17
+ ## Usage
18
+
19
+ See the [YARD documentation](http://rubydoc.info/gems/awesome_spawn)
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ gem 'awesome_spawn'
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install awesome_spawn
34
+
35
+ ## Contributing
36
+
37
+ 1. Fork it
38
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
39
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
40
+ 4. Push to the branch (`git push origin my-new-feature`)
41
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :test => :spec
6
+ task :default => :spec
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'awesome_spawn/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ authors = {
8
+ "Jason Frey" => "jfrey@redhat.com",
9
+ "Brandon Dunne" => "bdunne@redhat.com",
10
+ "Joe Rafaniello" => "jrafanie@redhat.com",
11
+ "Mo Morsi" => "mmorsi@redhat.com"
12
+ }
13
+
14
+ spec.name = "awesome_spawn"
15
+ spec.version = AwesomeSpawn::VERSION
16
+ spec.authors = authors.keys
17
+ spec.email = authors.values
18
+ spec.description = %q{AwesomeSpawn is a module that provides some useful features over Ruby's Kernel.spawn.}
19
+ spec.summary = spec.description
20
+ spec.homepage = "https://github.com/ManageIQ/awesome_spawn"
21
+ spec.license = "MIT"
22
+
23
+ spec.files = `git ls-files`.split($/)
24
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.3"
29
+ spec.add_development_dependency "rake"
30
+ spec.add_development_dependency "rspec"
31
+ spec.add_development_dependency "coveralls"
32
+ spec.add_development_dependency "yard"
33
+ spec.add_development_dependency "redcarpet"
34
+ end
@@ -0,0 +1,174 @@
1
+ require "awesome_spawn/version"
2
+ require "awesome_spawn/command_result"
3
+ require "awesome_spawn/command_result_error"
4
+ require "awesome_spawn/no_such_file_error"
5
+
6
+ require "shellwords"
7
+
8
+ module AwesomeSpawn
9
+ extend self
10
+
11
+ # Execute `command` synchronously via Kernel.spawn and gather the output
12
+ # stream, error stream, and exit status in a {CommandResult}.
13
+ #
14
+ # @example With normal output
15
+ # result = AwesomeSpawn.run('echo Hi')
16
+ # # => #<AwesomeSpawn::CommandResult:0x007f9d1d197320 @exit_status=0>
17
+ # result.output # => "Hi\n"
18
+ # result.error # => ""
19
+ # result.exit_status # => 0
20
+ #
21
+ # @example With error output as well
22
+ # result = AwesomeSpawn.run('echo Hi; echo "Hi2" 1>&2')
23
+ # # => <AwesomeSpawn::CommandResult:0x007ff64b98d930 @exit_status=0>
24
+ # result.output # => "Hi\n"
25
+ # result.error # => "Hi2\n"
26
+ # result.exit_status # => 0
27
+ #
28
+ # @example With exit status that is not 0
29
+ # result = AwesomeSpawn.run('false')
30
+ # #<AwesomeSpawn::CommandResult:0x007ff64b971410 @exit_status=1>
31
+ # result.exit_status # => 1
32
+ #
33
+ # @example With parameters sanitized
34
+ # result = AwesomeSpawn.run('echo', :params => {"--out" => "; rm /some/file"})
35
+ # # => #<AwesomeSpawn::CommandResult:0x007ff64baa6650 @exit_status=0>
36
+ # result.command_line
37
+ # # => "echo --out \\;\\ rm\\ /some/file"
38
+ #
39
+ # @param [String] command The command to run
40
+ # @param [Hash] options The options for running the command
41
+ # @option options [Hash,Array] :params The command line parameters. See
42
+ # {#build_command_line} for how to specify params. Alternate key
43
+ # `:parameters`.
44
+ # @option options [String] :chdir see the `:chdir` parameter for Kernel.spawn
45
+ #
46
+ # @raise [NoSuchFileError] if the `command` is not found
47
+ # @return [CommandResult] the output stream, error stream, and exit status
48
+ # @see http://ruby-doc.org/core/Kernel.html#method-i-spawn Kernel.spawn
49
+ def run(command, options = {})
50
+ params = options[:params] || options[:parameters]
51
+
52
+ launch_params = {}
53
+ launch_params[:chdir] = options[:chdir] if options[:chdir]
54
+
55
+ output = ""
56
+ error = ""
57
+ status = nil
58
+ command_line = build_command_line(command, params)
59
+
60
+ begin
61
+ output, error = launch(command_line, launch_params)
62
+ status = exitstatus
63
+ ensure
64
+ output ||= ""
65
+ error ||= ""
66
+ self.exitstatus = nil
67
+ end
68
+ rescue Errno::ENOENT => err
69
+ raise NoSuchFileError.new(err.message) if NoSuchFileError.detected?(err.message)
70
+ raise
71
+ else
72
+ CommandResult.new(command_line, output, error, status)
73
+ end
74
+
75
+ # Same as {#run}, additionally raising a {CommandResultError} if the exit
76
+ # status is not 0.
77
+ #
78
+ # @example With exit status that is not 0
79
+ # error = AwesomeSpawn.run!('false') rescue $!
80
+ # # => #<AwesomeSpawn::CommandResultError: false exit code: 1>
81
+ # error.message # => false exit code: 1
82
+ # error.result # => #<AwesomeSpawn::CommandResult:0x007ff64ba08018 @exit_status=1>
83
+ #
84
+ # @raise [CommandResultError] if the exit status is not 0.
85
+ # @return (see #run)
86
+ def run!(command, options = {})
87
+ command_result = run(command, options)
88
+
89
+ if command_result.exit_status != 0
90
+ message = "#{command} exit code: #{command_result.exit_status}"
91
+ raise CommandResultError.new(message, command_result)
92
+ end
93
+
94
+ command_result
95
+ end
96
+
97
+ # Build the full command line.
98
+ #
99
+ # @param [String] command The command to run
100
+ # @param [Hash,Array] params Optional command line parameters. They can
101
+ # be passed as a Hash or associative Array. The values are sanitized to
102
+ # prevent command line injection.
103
+ #
104
+ # - `{"--key" => "value"}` generates `--key value`
105
+ # - `{"--key=" => "value"}` generates `--key=value`
106
+ # - `{"--key" => nil}` generates `--key`
107
+ # - `{"-f" => ["file1", "file2"]}` generates `-f file1 file2`
108
+ # - `{nil => ["file1", "file2"]}` generates `file1 file2`
109
+ #
110
+ # @return [String] The full command line
111
+ def build_command_line(command, params = nil)
112
+ return command.to_s if params.nil? || params.empty?
113
+ "#{command} #{assemble_params(sanitize(params))}"
114
+ end
115
+
116
+ private
117
+
118
+ def sanitize(params)
119
+ return [] if params.nil? || params.empty?
120
+ params.collect do |k, v|
121
+ v = case v
122
+ when Array; v.collect {|i| i.to_s.shellescape}
123
+ when NilClass; v
124
+ else v.to_s.shellescape
125
+ end
126
+ [k, v]
127
+ end
128
+ end
129
+
130
+ def assemble_params(sanitized_params)
131
+ sanitized_params.collect do |pair|
132
+ pair_joiner = pair.first.to_s.end_with?("=") ? "" : " "
133
+ pair.flatten.compact.join(pair_joiner)
134
+ end.join(" ")
135
+ end
136
+
137
+ # IO pipes have a maximum size of 64k before blocking,
138
+ # so we need to read and write synchronously.
139
+ # http://stackoverflow.com/questions/13829830/ruby-process-spawn-stdout-pipe-buffer-size-limit/13846146#13846146
140
+ THREAD_SYNC_KEY = "#{self.name}-exitstatus"
141
+
142
+ def launch(command, spawn_options = {})
143
+ out_r, out_w = IO.pipe
144
+ err_r, err_w = IO.pipe
145
+ pid = Kernel.spawn(command, {:err => err_w, :out => out_w}.merge(spawn_options))
146
+ wait_for_process(pid, out_w, err_w)
147
+ wait_for_pipes(out_r, err_r)
148
+ end
149
+
150
+ def wait_for_process(pid, out_w, err_w)
151
+ self.exitstatus = :not_done
152
+ Thread.new(Thread.current) do |parent_thread|
153
+ _, status = Process.wait2(pid)
154
+ out_w.close
155
+ err_w.close
156
+ parent_thread[THREAD_SYNC_KEY] = status.exitstatus
157
+ end
158
+ end
159
+
160
+ def wait_for_pipes(out_r, err_r)
161
+ out = out_r.read
162
+ err = err_r.read
163
+ sleep(0.1) while exitstatus == :not_done
164
+ return out, err
165
+ end
166
+
167
+ def exitstatus
168
+ Thread.current[THREAD_SYNC_KEY]
169
+ end
170
+
171
+ def exitstatus=(value)
172
+ Thread.current[THREAD_SYNC_KEY] = value
173
+ end
174
+ end
@@ -0,0 +1,16 @@
1
+ module AwesomeSpawn
2
+ class CommandResult
3
+ attr_reader :command_line, :output, :error, :exit_status
4
+
5
+ def initialize(command_line, output, error, exit_status)
6
+ @command_line = command_line
7
+ @output = output
8
+ @error = error
9
+ @exit_status = exit_status
10
+ end
11
+
12
+ def inspect
13
+ "#{to_s.chop} @exit_status=#{@exit_status}>"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module AwesomeSpawn
2
+ class CommandResultError < StandardError
3
+ # @return [CommandResult] The command that caused the error
4
+ attr_reader :result
5
+
6
+ def initialize(message, result)
7
+ super(message)
8
+ @result = result
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module AwesomeSpawn
2
+ class NoSuchFileError < Errno::ENOENT
3
+ def initialize(message)
4
+ super(message.split("No such file or directory -").last.split(" ").first)
5
+ end
6
+
7
+ def self.detected?(message)
8
+ message.start_with?("No such file or directory -")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module AwesomeSpawn
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,159 @@
1
+ require 'spec_helper'
2
+ require 'pathname' # For Pathname specific specs
3
+
4
+ describe AwesomeSpawn do
5
+ subject { described_class }
6
+
7
+ let(:params) do
8
+ {
9
+ "--user" => "bob",
10
+ "--pass" => "P@$sw0^& |<>/-+*d%",
11
+ "--db" => nil,
12
+ "--desc=" => "Some Description",
13
+ nil => ["pkg1", "some pkg"]
14
+ }
15
+ end
16
+
17
+ let (:modified_params) do
18
+ params.to_a + [123, 456].collect {|pool| ["--pool", pool]}
19
+ end
20
+
21
+ shared_examples_for "run" do
22
+ context "parameters" do
23
+ before do
24
+ subject.stub(:exitstatus => 0)
25
+ end
26
+
27
+ it "won't modify caller params" do
28
+ orig_params = params.dup
29
+ subject.stub(:launch)
30
+ subject.send(run_method, "true", :params => params)
31
+ expect(orig_params).to eq(params)
32
+ end
33
+
34
+ it "supports spawn's chdir option" do
35
+ subject.should_receive(:launch).once.with("true", {:chdir => ".."})
36
+ subject.send(run_method, "true", :chdir => "..")
37
+ end
38
+ end
39
+
40
+ context "with real execution" do
41
+ before do
42
+ # Re-enable actual spawning just for these specs.
43
+ Kernel.stub(:spawn).and_call_original
44
+ end
45
+
46
+ it "command ok exit ok" do
47
+ expect(subject.send(run_method, "true")).to be_kind_of AwesomeSpawn::CommandResult
48
+ end
49
+
50
+ it "command ok exit bad" do
51
+ if run_method == "run!"
52
+ error = nil
53
+
54
+ # raise_error with do/end block notation is broken in rspec-expectations 2.14.x
55
+ # and has been fixed in master but not yet released.
56
+ # See: https://github.com/rspec/rspec-expectations/commit/b0df827f4c12870aa4df2f20a817a8b01721a6af
57
+ expect { subject.send(run_method, "false") }.to raise_error {|e| error = e }
58
+ expect(error).to be_kind_of AwesomeSpawn::CommandResultError
59
+ expect(error.result).to be_kind_of AwesomeSpawn::CommandResult
60
+ else
61
+ expect { subject.send(run_method, "false") }.to_not raise_error
62
+ end
63
+ end
64
+
65
+ it "command bad" do
66
+ expect { subject.send(run_method, "XXXXX --user=bob") }.to raise_error(Errno::ENOENT, "No such file or directory - XXXXX")
67
+ end
68
+
69
+ context "#exit_status" do
70
+ it "command ok exit ok" do
71
+ expect(subject.send(run_method, "true").exit_status).to eq(0)
72
+ end
73
+
74
+ it "command ok exit bad" do
75
+ expect(subject.send(run_method, "false").exit_status).to eq(1) if run_method == "run"
76
+ end
77
+ end
78
+
79
+ context "#output" do
80
+ it "command ok exit ok" do
81
+ expect(subject.send(run_method, "echo \"Hello World\"").output).to eq("Hello World\n")
82
+ end
83
+
84
+ it "command ok exit bad" do
85
+ expect(subject.send(run_method, "echo 'bad' && false").output).to eq("bad\n") if run_method == "run"
86
+ end
87
+ end
88
+
89
+ context "#error" do
90
+ it "command ok exit ok" do
91
+ expect(subject.send(run_method, "echo \"Hello World\" >&2").error).to eq("Hello World\n")
92
+ end
93
+
94
+ it "command ok exit bad" do
95
+ expect(subject.send(run_method, "echo 'bad' >&2 && false").error).to eq("bad\n") if run_method == "run"
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ context ".run" do
102
+ include_examples "run" do
103
+ let(:run_method) {"run"}
104
+ end
105
+ end
106
+
107
+ context ".run!" do
108
+ include_examples "run" do
109
+ let(:run_method) {"run!"}
110
+ end
111
+ end
112
+
113
+ context ".build_command_line" do
114
+ it "sanitizes crazy params" do
115
+ cl = subject.build_command_line("true", modified_params)
116
+ expect(cl).to eq "true --user bob --pass P@\\$sw0\\^\\&\\ \\|\\<\\>/-\\+\\*d\\% --db --desc=Some\\ Description pkg1 some\\ pkg --pool 123 --pool 456"
117
+ end
118
+
119
+ it "sanitizes Fixnum array param value" do
120
+ cl = subject.build_command_line("true", nil => [1])
121
+ expect(cl).to eq "true 1"
122
+ end
123
+
124
+ it "sanitizes Pathname param value" do
125
+ cl = subject.build_command_line("true", nil => [Pathname.new("/usr/bin/ruby")])
126
+ expect(cl).to eq "true /usr/bin/ruby"
127
+ end
128
+
129
+ it "sanitizes Pathname param key" do
130
+ cl = subject.build_command_line("true", Pathname.new("/usr/bin/ruby") => nil)
131
+ expect(cl).to eq "true /usr/bin/ruby"
132
+ end
133
+
134
+ it "with params as empty Hash" do
135
+ cl = subject.build_command_line("true", {})
136
+ expect(cl).to eq "true"
137
+ end
138
+
139
+ it "with params as nil" do
140
+ cl = subject.build_command_line("true", nil)
141
+ expect(cl).to eq "true"
142
+ end
143
+
144
+ it "without params" do
145
+ cl = subject.build_command_line("true")
146
+ expect(cl).to eq "true"
147
+ end
148
+
149
+ it "with Pathname command" do
150
+ cl = subject.build_command_line(Pathname.new("/usr/bin/ruby"))
151
+ expect(cl).to eq "/usr/bin/ruby"
152
+ end
153
+
154
+ it "with Pathname command and params" do
155
+ cl = subject.build_command_line(Pathname.new("/usr/bin/ruby"), "-v" => nil)
156
+ expect(cl).to eq "/usr/bin/ruby -v"
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe AwesomeSpawn::CommandResult do
4
+ context "#inspect" do
5
+ it "will not display sensitive information" do
6
+ str = described_class.new("aaa", "bbb", "ccc", 0).inspect
7
+
8
+ expect(str.include?("aaa")).to be_false
9
+ expect(str.include?("bbb")).to be_false
10
+ expect(str.include?("ccc")).to be_false
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+
18
+ config.before do
19
+ Kernel.stub(:spawn).and_raise("Spawning is not permitted in specs. Please change your spec to use expectations/stubs.")
20
+ end
21
+ end
22
+
23
+ require 'coveralls'
24
+ Coveralls.wear!
25
+
26
+ require 'awesome_spawn'
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awesome_spawn
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jason Frey
9
+ - Brandon Dunne
10
+ - Joe Rafaniello
11
+ - Mo Morsi
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+ date: 2014-01-04 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: bundler
19
+ requirement: !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: '1.3'
25
+ type: :development
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '1.3'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ requirement: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ - !ruby/object:Gem::Dependency
66
+ name: coveralls
67
+ requirement: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: yard
83
+ requirement: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: redcarpet
99
+ requirement: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ description: AwesomeSpawn is a module that provides some useful features over Ruby's
114
+ Kernel.spawn.
115
+ email:
116
+ - jfrey@redhat.com
117
+ - bdunne@redhat.com
118
+ - jrafanie@redhat.com
119
+ - mmorsi@redhat.com
120
+ executables: []
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - .gitignore
125
+ - .rspec
126
+ - .travis.yml
127
+ - .yardopts
128
+ - Gemfile
129
+ - LICENSE.txt
130
+ - README.md
131
+ - Rakefile
132
+ - awesome_spawn.gemspec
133
+ - lib/awesome_spawn.rb
134
+ - lib/awesome_spawn/command_result.rb
135
+ - lib/awesome_spawn/command_result_error.rb
136
+ - lib/awesome_spawn/no_such_file_error.rb
137
+ - lib/awesome_spawn/version.rb
138
+ - spec/awesome_spawn_spec.rb
139
+ - spec/command_result_spec.rb
140
+ - spec/spec_helper.rb
141
+ homepage: https://github.com/ManageIQ/awesome_spawn
142
+ licenses:
143
+ - MIT
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ segments:
155
+ - 0
156
+ hash: -1223152174146401530
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ segments:
164
+ - 0
165
+ hash: -1223152174146401530
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 1.8.23
169
+ signing_key:
170
+ specification_version: 3
171
+ summary: AwesomeSpawn is a module that provides some useful features over Ruby's Kernel.spawn.
172
+ test_files:
173
+ - spec/awesome_spawn_spec.rb
174
+ - spec/command_result_spec.rb
175
+ - spec/spec_helper.rb
176
+ has_rdoc: