childprocess 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.document +6 -0
  3. data/.gitignore +28 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +36 -0
  6. data/CHANGELOG.md +44 -0
  7. data/Gemfile +15 -0
  8. data/LICENSE +20 -0
  9. data/README.md +192 -0
  10. data/Rakefile +61 -0
  11. data/appveyor.yml +43 -0
  12. data/childprocess.gemspec +30 -0
  13. data/lib/childprocess.rb +205 -0
  14. data/lib/childprocess/abstract_io.rb +36 -0
  15. data/lib/childprocess/abstract_process.rb +192 -0
  16. data/lib/childprocess/errors.rb +26 -0
  17. data/lib/childprocess/jruby.rb +56 -0
  18. data/lib/childprocess/jruby/io.rb +16 -0
  19. data/lib/childprocess/jruby/process.rb +159 -0
  20. data/lib/childprocess/jruby/pump.rb +53 -0
  21. data/lib/childprocess/tools/generator.rb +146 -0
  22. data/lib/childprocess/unix.rb +9 -0
  23. data/lib/childprocess/unix/fork_exec_process.rb +70 -0
  24. data/lib/childprocess/unix/io.rb +21 -0
  25. data/lib/childprocess/unix/lib.rb +186 -0
  26. data/lib/childprocess/unix/platform/i386-linux.rb +12 -0
  27. data/lib/childprocess/unix/platform/i386-solaris.rb +11 -0
  28. data/lib/childprocess/unix/platform/x86_64-linux.rb +12 -0
  29. data/lib/childprocess/unix/platform/x86_64-macosx.rb +11 -0
  30. data/lib/childprocess/unix/posix_spawn_process.rb +134 -0
  31. data/lib/childprocess/unix/process.rb +89 -0
  32. data/lib/childprocess/version.rb +3 -0
  33. data/lib/childprocess/windows.rb +33 -0
  34. data/lib/childprocess/windows/handle.rb +91 -0
  35. data/lib/childprocess/windows/io.rb +25 -0
  36. data/lib/childprocess/windows/lib.rb +416 -0
  37. data/lib/childprocess/windows/process.rb +130 -0
  38. data/lib/childprocess/windows/process_builder.rb +175 -0
  39. data/lib/childprocess/windows/structs.rb +149 -0
  40. data/spec/abstract_io_spec.rb +12 -0
  41. data/spec/childprocess_spec.rb +391 -0
  42. data/spec/io_spec.rb +228 -0
  43. data/spec/jruby_spec.rb +24 -0
  44. data/spec/pid_behavior.rb +12 -0
  45. data/spec/platform_detection_spec.rb +86 -0
  46. data/spec/spec_helper.rb +261 -0
  47. data/spec/unix_spec.rb +57 -0
  48. data/spec/windows_spec.rb +23 -0
  49. metadata +179 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc6ebd5fca28a63f0cc66f1694f31961aa8dbd59
4
+ data.tar.gz: 0a3a042ae2fa14dc9b70446553f296cedd4990f4
5
+ SHA512:
6
+ metadata.gz: 721fae3f6625d89823fcc87fbc2188d611cb4b0f120b26a7bd4ddc2c421d4791dc608dbfe90275a312a920d3620ec377e463d01a6b118bb3f2cf938230cd4f65
7
+ data.tar.gz: 1a1f9e46433a97dc71e2937c6270f775d0c82db387daea194011eb83befde3e96912b83adbb472efbe03a381b7ac8a41e9009546c7157083f93c78738eeab6d6
@@ -0,0 +1,6 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ -
6
+ LICENSE
@@ -0,0 +1,28 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## RubyMine
17
+ .idea/*
18
+
19
+ ## PROJECT::GENERAL
20
+ coverage
21
+ rdoc
22
+ pkg
23
+ .rbx
24
+ Gemfile.lock
25
+ .ruby-version
26
+ .bundle
27
+
28
+ ## PROJECT::SPECIFIC
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,36 @@
1
+ os:
2
+ - linux
3
+ - osx
4
+
5
+ rvm:
6
+ - 1.9.3
7
+ - jruby-9.1.9.0
8
+ - rbx-3
9
+ - 2.0.0
10
+ - 2.1
11
+ - 2.2
12
+ - 2.3.5
13
+ - 2.4.0
14
+ - ruby-head
15
+
16
+ sudo: true # Necessary to fix JRuby
17
+
18
+ cache: bundler
19
+
20
+ before_install:
21
+ - "echo 'gem: --no-document' > ~/.gemrc"
22
+ - gem update --system
23
+ - gem install bundler # Necessary to fix 1.9.3
24
+
25
+ env:
26
+ global:
27
+ matrix:
28
+ - CHILDPROCESS_POSIX_SPAWN=true CHILDPROCESS_UNSET=should-be-unset
29
+ - CHILDPROCESS_POSIX_SPAWN=false CHILDPROCESS_UNSET=should-be-unset
30
+
31
+ matrix:
32
+ allow_failures:
33
+ - rvm: rbx-3
34
+ - rvm: jruby-9.1.9.0
35
+ - rvm: ruby-head
36
+ - env: "CHILDPROCESS_POSIX_SPAWN=true"
@@ -0,0 +1,44 @@
1
+ ### Version 0.8.0 / 2017-09-23
2
+
3
+ * Added a method for determining whether or nto a process had been started.
4
+
5
+
6
+ ### Version 0.7.1 / 2017-06-26
7
+
8
+ * Fixed a noisy uninitialized variable warning
9
+
10
+
11
+ ### Version 0.7.0 / 2017-05-07
12
+
13
+ * Debugging information now uses a Logger, which can be configured.
14
+
15
+
16
+ ### Version 0.6.3 / 2017-03-24
17
+
18
+ See beta release notes.
19
+
20
+
21
+ ### Version 0.6.3.beta.1 / 2017-03-10
22
+
23
+ * Bug fix: Fixed child process creation problems on Windows 7 when a child was declared as a leader.
24
+
25
+
26
+ ### Version 0.6.2 / 2017-02-25
27
+
28
+ * Bug fix: Fixed a potentially broken edge case that could occur on older 32-bit OSX systems.
29
+
30
+
31
+ ### Version 0.6.1 / 2017-01-22
32
+
33
+ * Bug fix: Fixed a dependency that was accidentally declared as a runtime
34
+ dependency instead of a development dependency.
35
+
36
+
37
+ ### Version 0.6.0 / 2017-01-22
38
+
39
+ * Support for Ruby 2.4 added
40
+
41
+
42
+ ### Version 0.5.9 / 2016-01-06
43
+
44
+ * The Great Before Times...
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in child_process.gemspec
4
+ gemspec
5
+
6
+
7
+ if RUBY_VERSION =~ /^1\./
8
+ gem 'tins', '< 1.7' # The 'tins' gem requires Ruby 2.x on/after this version
9
+ gem 'json', '< 2.0' # The 'json' gem drops pre-Ruby 2.x support on/after this version
10
+ gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version
11
+
12
+ if RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
13
+ gem 'ffi', '< 1.9.15' # The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
14
+ end
15
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2015 Jari Bakken
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
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,192 @@
1
+ # childprocess
2
+
3
+ This gem aims at being a simple and reliable solution for controlling
4
+ external programs running in the background on any Ruby / OS combination.
5
+
6
+ The code originated in the [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver) gem, but should prove useful as
7
+ a standalone library.
8
+
9
+ [![Build Status](https://secure.travis-ci.org/enkessler/childprocess.svg)](http://travis-ci.org/enkessler/childprocess)
10
+ [![Build status](https://ci.appveyor.com/api/projects/status/fn2snbcd7kku5myk/branch/dev?svg=true)](https://ci.appveyor.com/project/enkessler/childprocess/branch/dev)
11
+ [![Gem Version](https://badge.fury.io/rb/childprocess.svg)](http://badge.fury.io/rb/childprocess)
12
+ [![Code Climate](https://codeclimate.com/github/enkessler/childprocess.svg)](https://codeclimate.com/github/enkessler/childprocess)
13
+ [![Coverage Status](https://coveralls.io/repos/enkessler/childprocess/badge.svg?branch=master)](https://coveralls.io/r/enkessler/childprocess?branch=master)
14
+
15
+ # Usage
16
+
17
+ The object returned from `ChildProcess.build` will implement `ChildProcess::AbstractProcess`.
18
+
19
+ ### Basic examples
20
+
21
+ ```ruby
22
+ process = ChildProcess.build("ruby", "-e", "sleep")
23
+
24
+ # inherit stdout/stderr from parent...
25
+ process.io.inherit!
26
+
27
+ # ...or pass an IO
28
+ process.io.stdout = Tempfile.new("child-output")
29
+
30
+ # modify the environment for the child
31
+ process.environment["a"] = "b"
32
+ process.environment["c"] = nil
33
+
34
+ # set the child's working directory
35
+ process.cwd = '/some/path'
36
+
37
+ # start the process
38
+ process.start
39
+
40
+ # check process status
41
+ process.alive? #=> true
42
+ process.exited? #=> false
43
+
44
+ # wait indefinitely for process to exit...
45
+ process.wait
46
+ process.exited? #=> true
47
+
48
+ # get the exit code
49
+ process.exit_code #=> 0
50
+
51
+ # ...or poll for exit + force quit
52
+ begin
53
+ process.poll_for_exit(10)
54
+ rescue ChildProcess::TimeoutError
55
+ process.stop # tries increasingly harsher methods to kill the process.
56
+ end
57
+ ```
58
+
59
+ ### Advanced examples
60
+
61
+ #### Output to pipe
62
+
63
+ ```ruby
64
+ r, w = IO.pipe
65
+
66
+ proc = ChildProcess.build("echo", "foo")
67
+ proc.io.stdout = proc.io.stderr = w
68
+ proc.start
69
+ w.close
70
+
71
+ begin
72
+ loop { print r.readpartial(8192) }
73
+ rescue EOFError
74
+ end
75
+
76
+ proc.wait
77
+ ```
78
+
79
+ Note that if you just want to get the output of a command, the backtick method on Kernel may be a better fit.
80
+
81
+ #### Write to stdin
82
+
83
+ ```ruby
84
+ process = ChildProcess.build("cat")
85
+
86
+ out = Tempfile.new("duplex")
87
+ out.sync = true
88
+
89
+ process.io.stdout = process.io.stderr = out
90
+ process.duplex = true # sets up pipe so process.io.stdin will be available after .start
91
+
92
+ process.start
93
+ process.io.stdin.puts "hello world"
94
+ process.io.stdin.close
95
+
96
+ process.poll_for_exit(exit_timeout_in_seconds)
97
+
98
+ out.rewind
99
+ out.read #=> "hello world\n"
100
+ ```
101
+
102
+ #### Pipe output to another ChildProcess
103
+
104
+ ```ruby
105
+ search = ChildProcess.build("grep", '-E', %w(redis memcached).join('|'))
106
+ search.duplex = true # sets up pipe so search.io.stdin will be available after .start
107
+ search.io.stdout = $stdout
108
+ search.start
109
+
110
+ listing = ChildProcess.build("ps", "aux")
111
+ listing.io.stdout = search.io.stdin
112
+ listing.start
113
+ listing.wait
114
+
115
+ search.io.stdin.close
116
+ search.wait
117
+ ```
118
+
119
+ #### Prefer posix_spawn on *nix
120
+
121
+ If the parent process is using a lot of memory, `fork+exec` can be very expensive. The `posix_spawn()` API removes this overhead.
122
+
123
+ ```ruby
124
+ ChildProcess.posix_spawn = true
125
+ process = ChildProcess.build(*args)
126
+ ```
127
+
128
+ ### Ensure entire process tree dies
129
+
130
+ By default, the child process does not create a new process group. This means there's no guarantee that the entire process tree will die when the child process is killed. To solve this:
131
+
132
+ ```ruby
133
+ process = ChildProcess.build(*args)
134
+ process.leader = true
135
+ process.start
136
+ ```
137
+
138
+ #### Detach from parent
139
+
140
+ ```ruby
141
+ process = ChildProcess.build("sleep", "10")
142
+ process.detach = true
143
+ process.start
144
+ ```
145
+
146
+ #### Invoking a shell
147
+
148
+ As opposed to `Kernel#system`, `Kernel#exec` et al., ChildProcess will not automatically execute your command in a shell (like `/bin/sh` or `cmd.exe`) depending on the arguments.
149
+ This means that if you try to execute e.g. gem executables (like `bundle` or `gem`) or Windows executables (with `.com` or `.bat` extensions) you may see a `ChildProcess::LaunchError`.
150
+ You can work around this by being explicit about what interpreter to invoke:
151
+
152
+ ```ruby
153
+ ChildProcess.build("cmd.exe", "/c", "bundle")
154
+ ChildProcess.build("ruby", "-S", "bundle")
155
+ ```
156
+
157
+ #### Log to file
158
+
159
+ Errors and debugging information are logged to `$stderr` by default but a custom logger can be used instead.
160
+
161
+ ```ruby
162
+ logger = Logger.new('logfile.log')
163
+ logger.level = Logger::DEBUG
164
+ ChildProcess.logger = logger
165
+ ```
166
+
167
+ ## Caveats
168
+
169
+ * With JRuby on Unix, modifying `ENV["PATH"]` before using childprocess could lead to 'Command not found' errors, since JRuby is unable to modify the environemnt used for PATH searches in `java.lang.ProcessBuilder`. This can be avoided by setting `ChildProcess.posix_spawn = true`.
170
+
171
+ # Implementation
172
+
173
+ How the process is launched and killed depends on the platform:
174
+
175
+ * Unix : `fork + exec` (or `posix_spawn` if enabled)
176
+ * Windows : `CreateProcess()` and friends
177
+ * JRuby : `java.lang.{Process,ProcessBuilder}`
178
+
179
+ # Note on Patches/Pull Requests
180
+
181
+ 1. Fork it
182
+ 2. Create your feature branch (off of the development branch)
183
+ `git checkout -b my-new-feature dev`
184
+ 3. Commit your changes
185
+ `git commit -am 'Add some feature'`
186
+ 4. Push to the branch
187
+ `git push origin my-new-feature`
188
+ 5. Create new Pull Request
189
+
190
+ # Copyright
191
+
192
+ Copyright (c) 2010-2015 Jari Bakken. See LICENSE for details.
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'tmpdir'
4
+
5
+ require 'bundler'
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ include Rake::DSL if defined?(::Rake::DSL)
9
+
10
+ require 'rspec/core/rake_task'
11
+ RSpec::Core::RakeTask.new(:spec) do |spec|
12
+ spec.ruby_opts = "-I lib:spec -w"
13
+ spec.pattern = 'spec/**/*_spec.rb'
14
+ end
15
+
16
+ desc 'Run specs for rcov'
17
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
18
+ spec.ruby_opts = "-I lib:spec"
19
+ spec.pattern = 'spec/**/*_spec.rb'
20
+ spec.rcov = true
21
+ spec.rcov_opts = %w[--exclude spec,ruby-debug,/Library/Ruby,.gem --include lib/childprocess]
22
+ end
23
+
24
+ task :default => :spec
25
+
26
+ begin
27
+ require 'yard'
28
+ YARD::Rake::YardocTask.new
29
+ rescue LoadError
30
+ task :yardoc do
31
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
32
+ end
33
+ end
34
+
35
+ task :clean do
36
+ rm_rf "pkg"
37
+ rm_rf "childprocess.jar"
38
+ end
39
+
40
+ desc 'Create jar to bundle in selenium-webdriver'
41
+ task :jar => [:clean, :build] do
42
+ tmpdir = Dir.mktmpdir("childprocess-jar")
43
+ gem_to_package = Dir['pkg/*.gem'].first
44
+ gem_name = File.basename(gem_to_package, ".gem")
45
+ p :gem_to_package => gem_to_package, :gem_name => gem_name
46
+
47
+ sh "gem install -i #{tmpdir} #{gem_to_package} --ignore-dependencies --no-rdoc --no-ri"
48
+ sh "jar cf childprocess.jar -C #{tmpdir}/gems/#{gem_name}/lib ."
49
+ sh "jar tf childprocess.jar"
50
+ end
51
+
52
+ task :env do
53
+ $:.unshift File.expand_path("../lib", __FILE__)
54
+ require 'childprocess'
55
+ end
56
+
57
+ desc 'Calculate size of posix_spawn structs for the current platform'
58
+ task :generate => :env do
59
+ require 'childprocess/tools/generator'
60
+ ChildProcess::Tools::Generator.generate
61
+ end
@@ -0,0 +1,43 @@
1
+ version: '1.0.{build}'
2
+
3
+ environment:
4
+ matrix:
5
+ - CHILDPROCESS_POSIX_SPAWN: true
6
+ CHILDPROCESS_UNSET: should-be-unset
7
+ RUBY_VERSION: 193-x64
8
+ - CHILDPROCESS_POSIX_SPAWN: false
9
+ CHILDPROCESS_UNSET: should-be-unset
10
+ RUBY_VERSION: 193-x64
11
+ - CHILDPROCESS_POSIX_SPAWN: true
12
+ CHILDPROCESS_UNSET: should-be-unset
13
+ RUBY_VERSION: 200-x64
14
+ - CHILDPROCESS_POSIX_SPAWN: false
15
+ CHILDPROCESS_UNSET: should-be-unset
16
+ RUBY_VERSION: 200-x64
17
+ - CHILDPROCESS_POSIX_SPAWN: true
18
+ CHILDPROCESS_UNSET: should-be-unset
19
+ RUBY_VERSION: 21-x64
20
+ - CHILDPROCESS_POSIX_SPAWN: false
21
+ CHILDPROCESS_UNSET: should-be-unset
22
+ RUBY_VERSION: 21-x64
23
+ - CHILDPROCESS_POSIX_SPAWN: true
24
+ CHILDPROCESS_UNSET: should-be-unset
25
+ RUBY_VERSION: 22-x64
26
+ - CHILDPROCESS_POSIX_SPAWN: false
27
+ CHILDPROCESS_UNSET: should-be-unset
28
+ RUBY_VERSION: 22-x64
29
+
30
+
31
+ install:
32
+ - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
33
+ - bundle install
34
+
35
+ build: off
36
+
37
+ before_test:
38
+ - ruby -v
39
+ - gem -v
40
+ - bundle -v
41
+
42
+ test_script:
43
+ - bundle exec rake