process_executer 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 86a47c55d9ddea5ca45bd4126af5e2e09a50348e44d65ef089e6f4eab69eb302
4
+ data.tar.gz: 06b0a7ea4a9a134b5554b4dd673ecc087cf21d255e57dd18aca164644e4df644
5
+ SHA512:
6
+ metadata.gz: 5625c64aee302c872b097ffd4cf88ddaf3b28ebcfd5d1cfc52dacd53ab9ef4cbb323b7d6b985db3038ce2f86eb2891deb6245d7b047bd219e35d09415fa15fa0
7
+ data.tar.gz: 970147ff7974931dacaa0701ca32f5abcc540ade99ed8ca2b1b70b73cfa215bb09540931fc182fb67db13cbc920e17e3b55c9d07180fea98ed6bc0571aed6568
data/.markdownlint.yml ADDED
@@ -0,0 +1,25 @@
1
+ default: true
2
+
3
+ # Unordered list indentation
4
+ MD007: { indent: 4 }
5
+
6
+ # Line length
7
+ MD013: { line_length: 90, tables: false, code_blocks: false }
8
+
9
+ # Heading duplication is allowed for non-sibling headings
10
+ MD024: { siblings_only: true }
11
+
12
+ # Do not allow the specified trailing punctuation in a header
13
+ MD026: { punctuation: '.,;:' }
14
+
15
+ # Order list items must have a prefix that increases in numerical order
16
+ MD029: { style: 'ordered' }
17
+
18
+ # Lists do not need to be surrounded by blank lines
19
+ MD032: false
20
+
21
+ # Allow raw HTML in Markdown
22
+ MD033: false
23
+
24
+ # Allow emphasis to be used instead of a heading
25
+ MD036: false
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,20 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ # Output extra information for each offense to make it easier to diagnose:
4
+ DisplayCopNames: true
5
+ DisplayStyleGuide: true
6
+ ExtraDetails: true
7
+ SuggestExtensions: false
8
+ # RuboCop enforces rules depending on the oldest version of Ruby which
9
+ # your project supports:
10
+ TargetRubyVersion: 2.7
11
+
12
+ # The default max line length is 80 characters
13
+ Layout/LineLength:
14
+ Max: 120
15
+
16
+ # The DSL for RSpec and the gemspec file make it very hard to limit block length:
17
+ Metrics/BlockLength:
18
+ Exclude:
19
+ - "spec/**/*_spec.rb"
20
+ - "*.gemspec"
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --no-private
2
+ --hide-void-return
3
+ --markup-provider=redcarpet
4
+ --markup markdown
5
+ - LICENSE.md
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## v0.2.0 (2022-11-16)
2
+
3
+ [Full Changelog](https://github.com/main-branch/process_executer/compare/v0.1.0...v0.2.0)
4
+
5
+ * 8b70ac0 Use the create_github_release gem to make the release PR (#2)
6
+ * 4b2700e Add ProcessExecuter#execute to execute a command and return the result (#1)
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in process_executer.gemspec
6
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 James Couball
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # The ProcessExecuter Gem
2
+
3
+ An API for executing commands in a subprocess
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ ```shell
10
+ bundle add process_executer
11
+ ```
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ ```shell
16
+ gem install process_executer
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ See the examples in the project's YARD documentation.
22
+
23
+ ## Development
24
+
25
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
26
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
27
+ prompt that will allow you to experiment.
28
+
29
+ To install this gem onto your local machine, run `bundle exec rake install`. To
30
+ release a new version, update the version number in `version.rb`, and then run
31
+ `bundle exec rake release`, which will create a git tag for the version, push git
32
+ commits and the created tag, and push the `.gem` file to
33
+ [rubygems.org](https://rubygems.org).
34
+
35
+ ## Contributing
36
+
37
+ Bug reports and pull requests are welcome on our
38
+ [GitHub issue tracker](https://github.com/main-branch/process_executer)
39
+
40
+ ## Feature Checklist
41
+
42
+ Here is the 1.0 feature checklist:
43
+
44
+ * [x] Run a command
45
+ * [x] Collect the command's stdout/stderr to a string
46
+ * [x] Passthru the command's stdout/stderr to this process's stdout/stderr
47
+ * [ ] Command execution timeout
48
+ * [ ] Redirect stdout/stderr to a named file
49
+ * [ ] Redirect stdout/stderr to a named file with open mode
50
+ * [ ] Redirect stdout/stderr to a named file with open mode and permissions
51
+ * [ ] Redirect stdout/stderr to an open File object
52
+ * [ ] Merge stdout & stderr
53
+ * [ ] Redirect a file to stdin
54
+ * [ ] Redirect from a butter to stdin
55
+ * [ ] Binary vs. text mode for stdin/stdout/stderr
56
+ * [ ] Environment isolation like Process.spawn
57
+ * [ ] Pass options to Process.spawn (chdir, umask, pgroup, etc.)
58
+ * [ ] Don't allow optionis to Process.spawn that would break the functionality
59
+ (:in, :out, :err, integer, #fileno, :close_others)
60
+
61
+ ## License
62
+
63
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The default task
4
+
5
+ desc 'Run the same tasks that the CI build will run'
6
+ task default: %w[spec rubocop yard yard:audit yard:coverage bundle:audit build]
7
+
8
+ # Bundler Audit
9
+
10
+ require 'bundler/audit/task'
11
+ Bundler::Audit::Task.new
12
+
13
+ # Bundler Gem Build
14
+
15
+ require 'bundler'
16
+ require 'bundler/gem_tasks'
17
+
18
+ begin
19
+ Bundler.setup(:default, :development)
20
+ rescue Bundler::BundlerError => e
21
+ warn e.message
22
+ warn 'Run `bundle install` to install missing gems'
23
+ exit e.status_code
24
+ end
25
+
26
+ CLEAN << 'pkg'
27
+ CLOBBER << 'Gemfile.lock'
28
+
29
+ # Bump
30
+
31
+ require 'bump/tasks'
32
+
33
+ # RSpec
34
+
35
+ require 'rspec/core/rake_task'
36
+
37
+ RSpec::Core::RakeTask.new
38
+
39
+ CLEAN << 'coverage'
40
+ CLEAN << '.rspec_status'
41
+ CLEAN << 'rspec-report.xml'
42
+
43
+ # Rubocop
44
+
45
+ require 'rubocop/rake_task'
46
+
47
+ RuboCop::RakeTask.new do |t|
48
+ t.options = %w[
49
+ --format progress
50
+ --format json --out rubocop-report.json
51
+ ]
52
+ end
53
+
54
+ CLEAN << 'rubocop-report.json'
55
+
56
+ # YARD
57
+
58
+ require 'yard'
59
+ YARD::Rake::YardocTask.new do |t|
60
+ t.files = %w[lib/**/*.rb examples/**/*]
61
+ end
62
+
63
+ CLEAN << '.yardoc'
64
+ CLEAN << 'doc'
65
+
66
+ # Yardstick
67
+
68
+ desc 'Run yardstick to show missing YARD doc elements'
69
+ task :'yard:audit' do
70
+ sh "yardstick 'lib/**/*.rb'"
71
+ end
72
+
73
+ # Yardstick coverage
74
+
75
+ require 'yardstick/rake/verify'
76
+
77
+ Yardstick::Rake::Verify.new(:'yard:coverage') do |verify|
78
+ verify.threshold = 100
79
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ProcessExecuter
4
+ # The result of executing a command
5
+ #
6
+ # @api public
7
+ #
8
+ class Result
9
+ # The status of the command process
10
+ #
11
+ # @example
12
+ # status # => #<Process::Status: pid 86235 exit 0>
13
+ # out = 'hello'
14
+ # err = 'ERROR'
15
+ # command = ProcessExecuter.new(status, out, err)
16
+ # command.status # => #<Process::Status: pid 86235 exit 0>
17
+ #
18
+ # @return [Process::Status]
19
+ #
20
+ attr_reader :status
21
+
22
+ # The command's stdout (if collected)
23
+ #
24
+ # @example
25
+ # status # => #<Process::Status: pid 86235 exit 0>
26
+ # out = 'hello'
27
+ # err = 'ERROR'
28
+ # command = ProcessExecuter.new(status, out, err)
29
+ # command.out # => "hello\n"
30
+ #
31
+ # @return [String, nil]
32
+ #
33
+ attr_reader :out
34
+
35
+ # The command's stderr (if collected)
36
+ #
37
+ # @example
38
+ # status # => #<Process::Status: pid 86235 exit 0>
39
+ # out = 'hello'
40
+ # err = 'ERROR'
41
+ # command = ProcessExecuter.new(status, out, err)
42
+ # command.out # => "ERROR\n"
43
+ #
44
+ # @return [String, nil]
45
+ #
46
+ attr_reader :err
47
+
48
+ # Create a new Result object
49
+ #
50
+ # @example
51
+ # status # => #<Process::Status: pid 86235 exit 0>
52
+ # out = 'hello'
53
+ # err = 'ERROR'
54
+ # command = ProcessExecuter.new(status, out, err)
55
+ #
56
+ # @param status [Process::Status] the status of the command process
57
+ # @param out [String, nil] the command's stdout (if collected)
58
+ # @param err [String, nil] the command's stderr (if collected)
59
+ #
60
+ # @return [ProcessExecuter::Result] the result object
61
+ #
62
+ def initialize(status, out, err)
63
+ @status = status
64
+ @out = out
65
+ @err = err
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ProcessExecuter
4
+ VERSION = '0.2.0'
5
+ end
@@ -0,0 +1,225 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/SingleLineMethods
4
+
5
+ require 'process_executer/result'
6
+ # require 'nio'
7
+
8
+ # Execute a process and capture the output to a string, a file, and/or
9
+ # pass the output through to this process's stdout/stderr.
10
+ #
11
+ # @api public
12
+ #
13
+ class ProcessExecuter
14
+ # stdout collected from the command
15
+ #
16
+ # @example
17
+ # command = ProcessExecuter.new
18
+ # command.execute('echo hello')
19
+ # command.out # => "hello\n"
20
+ #
21
+ # @return [String, nil] nil if collect_out? is false
22
+ #
23
+ attr_reader :out
24
+
25
+ # stderr collected from the command
26
+ #
27
+ # @example
28
+ # command = ProcessExecuter.new
29
+ # command.execute('echo hello 1>&2')
30
+ # command.err # => "hello\n"
31
+ #
32
+ # @return [String, nil] nil if collect_err? is false
33
+ #
34
+ attr_reader :err
35
+
36
+ # The status of the command process
37
+ #
38
+ # Will be `nil` if the command has not completed execution.
39
+ #
40
+ # @example
41
+ # command = ProcessExecuter.new
42
+ # command.execute('echo hello')
43
+ # command.status # => #<Process::Status: pid 86235 exit 0>
44
+ #
45
+ # @return [Process::Status, nil]
46
+ #
47
+ attr_reader :status
48
+
49
+ # Show the command's stdout on this process's stdout
50
+ #
51
+ # @example
52
+ # command = ProcessExecuter.new(passthru_out: true)
53
+ # command.passthru_out? # => true
54
+ #
55
+ # @return [Boolean]
56
+ #
57
+ def passthru_out?; !!@passthru_out; end
58
+
59
+ # Show the command's stderr on this process's stderr
60
+ #
61
+ # @example
62
+ # command = ProcessExecuter.new(passthru_err: true)
63
+ # command.passthru_err? # => true
64
+ #
65
+ # @return [Boolean]
66
+ #
67
+ def passthru_err?; !!@passthru_err; end
68
+
69
+ # Collect the command's stdout the :out string (default is true)
70
+ #
71
+ # @example
72
+ # command = ProcessExecuter.new(collect_out: false)
73
+ # command.collect_out? # => false
74
+ #
75
+ # @return [Boolean]
76
+ #
77
+ def collect_out?; !!@collect_out; end
78
+
79
+ # Collect the command's stderr the :err string (default is true)
80
+ #
81
+ # @example
82
+ # command = ProcessExecuter.new(collect_err: false)
83
+ # command.collect_err? # => false
84
+ #
85
+ # @return [Boolean]
86
+ #
87
+ def collect_err?; !!@collect_err; end
88
+
89
+ # Create a new ProcessExecuter
90
+ #
91
+ # @example
92
+ # command = ProcessExecuter.new(passthru_out: false, passthru_err: false)
93
+ #
94
+ # @param passthru_out [Boolean] show the command's stdout on this process's stdout
95
+ # @param passthru_err [Boolean] show the command's stderr on this process's stderr
96
+ # @param collect_out [Boolean] collect the command's stdout the :out string
97
+ # @param collect_err [Boolean] collect the command's stderr the :err string
98
+ #
99
+ def initialize(passthru_out: false, passthru_err: false, collect_out: true, collect_err: true)
100
+ @passthru_out = passthru_out
101
+ @passthru_err = passthru_err
102
+ @collect_out = collect_out
103
+ @collect_err = collect_err
104
+ end
105
+
106
+ # rubocop:disable Metrics/AbcSize
107
+ # rubocop:disable Metrics/MethodLength
108
+
109
+ # Execute the given command in a subprocess
110
+ #
111
+ # See Process.spawn for acceptable values for command and options.
112
+ #
113
+ # Do no specify the following options: :in, :out, :err, integer, #fileno, :close_others.
114
+ #
115
+ # @example Execute a command as a single string
116
+ # result = ProcessExecuter.new.execute('echo hello')
117
+ #
118
+ # @example Execute a command as with each argument as a separate string
119
+ # result = ProcessExecuter.new.execute('echo', 'hello')
120
+ #
121
+ # @example Execute a command in a specific directory
122
+ # result = ProcessExecuter.new.execute('pwd', chdir: '/tmp')
123
+ # result.out # => "/tmp\n"
124
+ #
125
+ # @example Execute a command with specific environment variables
126
+ # result = ProcessExecuter.new.execute({ 'FOO' => 'bar' }, 'echo $FOO' )
127
+ # result.out # => "bar\n"
128
+ #
129
+ # @param command [String, Array<String>] the command to pass to Process.spawn
130
+ # @param options [Hash] options to pass to Process.spawn
131
+ #
132
+ # @return [ProcessExecuter::Result] the result of the command execution
133
+ #
134
+ def execute(*command, **options)
135
+ @status = nil
136
+ @out = (collect_out? ? '' : nil)
137
+ @err = (collect_err? ? '' : nil)
138
+
139
+ out_reader, out_writer = IO.pipe
140
+ err_reader, err_writer = IO.pipe
141
+
142
+ options[:out] = out_writer
143
+ options[:err] = err_writer
144
+
145
+ pid = Process.spawn(*command, options)
146
+
147
+ loop do
148
+ read_command_output(out_reader, err_reader)
149
+
150
+ _pid, @status = Process.wait2(pid, Process::WNOHANG)
151
+ break if @status
152
+
153
+ # puts "finished_pid: #{finished_pid}"
154
+ # puts "status: #{status}"
155
+
156
+ # puts 'starting select'
157
+ # readers, writers, exceptions = IO.select([stdout_reader, stderr_reader], nil, nil, 0.1)
158
+ IO.select([out_reader, err_reader], nil, nil, 0.05)
159
+
160
+ # puts "readers: #{readers}"
161
+ # puts "writers: #{writers}"
162
+ # puts "exceptions: #{exceptions}"
163
+
164
+ # break unless readers || writers || exceptions
165
+
166
+ _pid, @status = Process.wait2(pid, Process::WNOHANG)
167
+ break if @status
168
+
169
+ # puts "finished_pid: #{finished_pid}"
170
+ # puts "status: #{status}"
171
+ end
172
+
173
+ out_writer.close
174
+ err_writer.close
175
+
176
+ # Read whatever is left over after the process terminates
177
+ read_command_output(out_reader, err_reader)
178
+ ProcessExecuter::Result.new(@status, @out, @err)
179
+ end
180
+
181
+ # rubocop:enable Metrics/AbcSize
182
+ # rubocop:enable Metrics/MethodLength
183
+
184
+ private
185
+
186
+ # Read output from the given readers
187
+ # @return [void]
188
+ # @api private
189
+ def read_command_output(out_reader, err_reader)
190
+ loop do
191
+ # Keep reading until there is nothing left to read
192
+ break unless read_out(out_reader) || read_err(err_reader)
193
+ end
194
+ end
195
+
196
+ # Read stdout from the given reader
197
+ # @return [void]
198
+ # @api private
199
+ def read_out(reader)
200
+ new_data = reader.read_nonblock(1024)
201
+ # puts "new_stdout: '#{new_data}'"
202
+ @out += new_data if new_data && collect_out?
203
+ puts new_data if new_data && passthru_out?
204
+ true
205
+ rescue EOFError, IO::EAGAINWaitReadable
206
+ # Nothing to read at this time
207
+ false
208
+ end
209
+
210
+ # Read stderr from the given reader
211
+ # @return [void]
212
+ # @api private
213
+ def read_err(reader)
214
+ new_data = reader.read_nonblock(1024)
215
+ # puts "new_stderr: '#{new_data}'"
216
+ @err += new_data if new_data && collect_err?
217
+ warn new_data if new_data && passthru_err?
218
+ true
219
+ rescue EOFError, IO::EAGAINWaitReadable
220
+ # Nothing to read at this time
221
+ false
222
+ end
223
+ end
224
+
225
+ # rubocop:enable Style/SingleLineMethods
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/process_executer/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'process_executer'
7
+ spec.version = ProcessExecuter::VERSION
8
+ spec.authors = ['James Couball']
9
+ spec.email = ['jcouball@yahoo.com']
10
+
11
+ spec.summary = 'An API for executing commands in a subprocess'
12
+ spec.description = 'An API for executing commands in a subprocess'
13
+ spec.homepage = 'https://github.com/main_branch/process_executer'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 2.7.0'
16
+
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/main_branch/process_executer'
21
+ spec.metadata['changelog_uri'] = 'https://github.com/main_branch/process_executer'
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(__dir__) do
26
+ `git ls-files -z`.split("\x0").reject do |f|
27
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
28
+ end
29
+ end
30
+ spec.bindir = 'exe'
31
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ['lib']
33
+
34
+ # Uncomment to register a new dependency of your gem
35
+ # spec.add_dependency "example-gem", "~> 1.0"
36
+ spec.add_development_dependency 'bump', '~> 0.10'
37
+ spec.add_development_dependency 'bundler-audit', '~> 0.9'
38
+ spec.add_development_dependency 'create_github_release', '~> 0.2'
39
+ spec.add_development_dependency 'rake', '~> 13.0'
40
+ spec.add_development_dependency 'redcarpet', '~> 3.5'
41
+ spec.add_development_dependency 'rspec', '~> 3.10'
42
+ spec.add_development_dependency 'rubocop', '~> 1.36'
43
+ spec.add_development_dependency 'simplecov', '~> 0.21'
44
+ spec.add_development_dependency 'solargraph', '~> 0.47'
45
+ spec.add_development_dependency 'yard', '~> 0.9'
46
+ spec.add_development_dependency 'yardstick', '~> 0.9'
47
+
48
+ # For more information and examples about making a new gem, check out our
49
+ # guide at: https://bundler.io/guides/creating_gem.html
50
+ spec.metadata['rubygems_mfa_required'] = 'true'
51
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: process_executer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - James Couball
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bump
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler-audit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: create_github_release
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redcarpet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.10'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.10'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.36'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.36'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.21'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.21'
125
+ - !ruby/object:Gem::Dependency
126
+ name: solargraph
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.47'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.47'
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.9'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.9'
153
+ - !ruby/object:Gem::Dependency
154
+ name: yardstick
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.9'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.9'
167
+ description: An API for executing commands in a subprocess
168
+ email:
169
+ - jcouball@yahoo.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".markdownlint.yml"
175
+ - ".rspec"
176
+ - ".rubocop.yml"
177
+ - ".yardopts"
178
+ - CHANGELOG.md
179
+ - Gemfile
180
+ - LICENSE.md
181
+ - README.md
182
+ - Rakefile
183
+ - lib/process_executer.rb
184
+ - lib/process_executer/result.rb
185
+ - lib/process_executer/version.rb
186
+ - process_executer.gemspec
187
+ homepage: https://github.com/main_branch/process_executer
188
+ licenses:
189
+ - MIT
190
+ metadata:
191
+ allowed_push_host: https://rubygems.org
192
+ homepage_uri: https://github.com/main_branch/process_executer
193
+ source_code_uri: https://github.com/main_branch/process_executer
194
+ changelog_uri: https://github.com/main_branch/process_executer
195
+ rubygems_mfa_required: 'true'
196
+ post_install_message:
197
+ rdoc_options: []
198
+ require_paths:
199
+ - lib
200
+ required_ruby_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: 2.7.0
205
+ required_rubygems_version: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ requirements: []
211
+ rubygems_version: 3.3.7
212
+ signing_key:
213
+ specification_version: 4
214
+ summary: An API for executing commands in a subprocess
215
+ test_files: []