childprocess 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +21 -5
- data/CHANGELOG.md +14 -2
- data/Gemfile +8 -5
- data/README.md +9 -1
- data/appveyor.yml +18 -1
- data/childprocess.gemspec +3 -4
- data/ext/mkrf_conf.rb +24 -0
- data/lib/childprocess/errors.rb +11 -0
- data/lib/childprocess/jruby/process.rb +41 -16
- data/lib/childprocess/unix/posix_spawn_process.rb +3 -3
- data/lib/childprocess/version.rb +1 -1
- data/lib/childprocess/windows/lib.rb +2 -2
- data/lib/childprocess/windows/process_builder.rb +11 -8
- data/lib/childprocess.rb +7 -2
- data/spec/childprocess_spec.rb +56 -0
- data/spec/get_env.ps1 +13 -0
- data/spec/spec_helper.rb +16 -7
- metadata +8 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0f88536969a207dced9e122e8adfbf38e7e4bea75bb0fdb6dc83838db75718b2
|
4
|
+
data.tar.gz: 711c4d76098b6f0d7487428cc7af99331f9b95e2b978bd7b1435a5cd65ae7a38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 958c7579affa791c7c61e0dbe5f7f17118b57805b24f497876fb5a4bf0a35ff113dd69d52e2aaf3e0b3c1f9ae8a5e61104ac8cf17b88744280e94dbc4e1d5817
|
7
|
+
data.tar.gz: 7b65d73e847fe42c200cb2e42f8b89303358126d5a2490778f7523db38fd9bd63b209966c6e7eb4f2dbd123400a568f5c23e55e5948bcdb0a8edb949813e005b
|
data/.travis.yml
CHANGED
@@ -9,18 +9,23 @@ rvm:
|
|
9
9
|
- 2.0.0
|
10
10
|
- 2.1
|
11
11
|
- 2.2
|
12
|
-
- 2.3
|
13
|
-
- 2.4
|
12
|
+
- 2.3
|
13
|
+
- 2.4
|
14
|
+
- 2.5
|
14
15
|
- ruby-head
|
15
16
|
|
16
|
-
sudo:
|
17
|
+
sudo: false
|
17
18
|
|
18
19
|
cache: bundler
|
19
20
|
|
20
21
|
before_install:
|
21
22
|
- "echo 'gem: --no-document' > ~/.gemrc"
|
22
|
-
|
23
|
-
- gem
|
23
|
+
# RubyGems update is supported for Ruby 2.3 and later
|
24
|
+
- ruby -e "system('gem update --system') if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3')"
|
25
|
+
- gem install bundler --version '~> 1.17'
|
26
|
+
|
27
|
+
before_script:
|
28
|
+
- 'export JAVA_OPTS="${JAVA_OPTS_FOR_SPECS}"'
|
24
29
|
|
25
30
|
env:
|
26
31
|
global:
|
@@ -34,3 +39,14 @@ matrix:
|
|
34
39
|
- rvm: jruby-9.1.9.0
|
35
40
|
- rvm: ruby-head
|
36
41
|
- env: "CHILDPROCESS_POSIX_SPAWN=true"
|
42
|
+
include:
|
43
|
+
- rvm: jruby-9.2.5.0
|
44
|
+
jdk: openjdk11
|
45
|
+
env: "JAVA_OPTS_FOR_SPECS='--add-opens java.base/java.io=org.jruby.dist --add-opens java.base/sun.nio.ch=org.jruby.dist'"
|
46
|
+
exclude:
|
47
|
+
# Travis does not provide 1.9.3 on OSX
|
48
|
+
- rvm: 1.9.3
|
49
|
+
os: osx
|
50
|
+
# Travis does not provide 2.0.0 on it latest version of OSX
|
51
|
+
- rvm: 2.0.0
|
52
|
+
os: osx
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
+
### Version 1.0.0 / 2019-01-28
|
2
|
+
|
3
|
+
* [#134](https://github.com/enkessler/childprocess/pull/134): Add support for non-ASCII characters on Windows
|
4
|
+
* [#132](https://github.com/enkessler/childprocess/pull/132): Install `ffi` gem requirement on Windows only
|
5
|
+
* [#128](https://github.com/enkessler/childprocess/issues/128): Convert environment variable values to strings when `posix_spawn` enabled
|
6
|
+
* [#141](https://github.com/enkessler/childprocess/pull/141): Support JRuby on Java >= 9
|
7
|
+
|
8
|
+
### Version 0.9.0 / 2018-03-10
|
9
|
+
|
10
|
+
* Added support for DragonFly BSD.
|
11
|
+
|
12
|
+
|
1
13
|
### Version 0.8.0 / 2017-09-23
|
2
14
|
|
3
|
-
* Added a method for determining whether or
|
15
|
+
* Added a method for determining whether or not a process had been started.
|
4
16
|
|
5
17
|
|
6
18
|
### Version 0.7.1 / 2017-06-26
|
@@ -30,7 +42,7 @@ See beta release notes.
|
|
30
42
|
|
31
43
|
### Version 0.6.1 / 2017-01-22
|
32
44
|
|
33
|
-
* Bug fix: Fixed a dependency that was accidentally declared as a runtime
|
45
|
+
* Bug fix: Fixed a dependency that was accidentally declared as a runtime
|
34
46
|
dependency instead of a development dependency.
|
35
47
|
|
36
48
|
|
data/Gemfile
CHANGED
@@ -1,15 +1,18 @@
|
|
1
|
-
source
|
1
|
+
source 'http://rubygems.org'
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in child_process.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
6
|
if RUBY_VERSION =~ /^1\./
|
8
7
|
gem 'tins', '< 1.7' # The 'tins' gem requires Ruby 2.x on/after this version
|
9
8
|
gem 'json', '< 2.0' # The 'json' gem drops pre-Ruby 2.x support on/after this version
|
10
9
|
gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# ffi gem for Windows requires Ruby 2.x on/after this version
|
12
|
+
gem 'ffi', '< 1.9.15' if ENV['CHILDPROCESS_POSIX_SPAWN'] == 'true' || Gem.win_platform?
|
13
|
+
elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2')
|
14
|
+
# Ruby 2.0/2.1 support only ffi before 1.10
|
15
|
+
gem 'ffi', '~> 1.9.0' if ENV['CHILDPROCESS_POSIX_SPAWN'] == 'true' || Gem.win_platform?
|
16
|
+
else
|
17
|
+
gem 'ffi' if ENV['CHILDPROCESS_POSIX_SPAWN'] == 'true' || Gem.win_platform?
|
15
18
|
end
|
data/README.md
CHANGED
@@ -12,6 +12,10 @@ a standalone library.
|
|
12
12
|
[![Code Climate](https://codeclimate.com/github/enkessler/childprocess.svg)](https://codeclimate.com/github/enkessler/childprocess)
|
13
13
|
[![Coverage Status](https://coveralls.io/repos/enkessler/childprocess/badge.svg?branch=master)](https://coveralls.io/r/enkessler/childprocess?branch=master)
|
14
14
|
|
15
|
+
***
|
16
|
+
**This project currently needs a new maintainer. If anyone is interested, please contact me, [enkessler](https://github.com/enkessler).**
|
17
|
+
***
|
18
|
+
|
15
19
|
# Usage
|
16
20
|
|
17
21
|
The object returned from `ChildProcess.build` will implement `ChildProcess::AbstractProcess`.
|
@@ -125,6 +129,8 @@ ChildProcess.posix_spawn = true
|
|
125
129
|
process = ChildProcess.build(*args)
|
126
130
|
```
|
127
131
|
|
132
|
+
To be able to use this, please make sure that you have the `ffi` gem installed.
|
133
|
+
|
128
134
|
### Ensure entire process tree dies
|
129
135
|
|
130
136
|
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:
|
@@ -166,7 +172,9 @@ ChildProcess.logger = logger
|
|
166
172
|
|
167
173
|
## Caveats
|
168
174
|
|
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
|
175
|
+
* With JRuby on Unix, modifying `ENV["PATH"]` before using childprocess could lead to 'Command not found' errors, since JRuby is unable to modify the environment used for PATH searches in `java.lang.ProcessBuilder`. This can be avoided by setting `ChildProcess.posix_spawn = true`.
|
176
|
+
* With JRuby on Java >= 9, the JVM may need to be configured to allow JRuby to access neccessary implementations; this can be done by adding `--add-opens java.base/java.io=org.jruby.dist` and `--add-opens java.base/sun.nio.ch=org.jruby.dist` to the `JAVA_OPTS` environment variable that is used by JRuby when launching the JVM.
|
177
|
+
|
170
178
|
|
171
179
|
# Implementation
|
172
180
|
|
data/appveyor.yml
CHANGED
@@ -26,7 +26,24 @@ environment:
|
|
26
26
|
- CHILDPROCESS_POSIX_SPAWN: false
|
27
27
|
CHILDPROCESS_UNSET: should-be-unset
|
28
28
|
RUBY_VERSION: 22-x64
|
29
|
-
|
29
|
+
- CHILDPROCESS_POSIX_SPAWN: true
|
30
|
+
CHILDPROCESS_UNSET: should-be-unset
|
31
|
+
RUBY_VERSION: 23-x64
|
32
|
+
- CHILDPROCESS_POSIX_SPAWN: false
|
33
|
+
CHILDPROCESS_UNSET: should-be-unset
|
34
|
+
RUBY_VERSION: 23-x64
|
35
|
+
- CHILDPROCESS_POSIX_SPAWN: true
|
36
|
+
CHILDPROCESS_UNSET: should-be-unset
|
37
|
+
RUBY_VERSION: 24-x64
|
38
|
+
- CHILDPROCESS_POSIX_SPAWN: false
|
39
|
+
CHILDPROCESS_UNSET: should-be-unset
|
40
|
+
RUBY_VERSION: 24-x64
|
41
|
+
- CHILDPROCESS_POSIX_SPAWN: true
|
42
|
+
CHILDPROCESS_UNSET: should-be-unset
|
43
|
+
RUBY_VERSION: 25-x64
|
44
|
+
- CHILDPROCESS_POSIX_SPAWN: false
|
45
|
+
CHILDPROCESS_UNSET: should-be-unset
|
46
|
+
RUBY_VERSION: 25-x64
|
30
47
|
|
31
48
|
install:
|
32
49
|
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
data/childprocess.gemspec
CHANGED
@@ -19,12 +19,11 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_runtime_dependency "ffi", "~> 1.0", ">= 1.0.11"
|
23
|
-
|
24
22
|
s.add_development_dependency "rspec", "~> 3.0"
|
25
23
|
s.add_development_dependency "yard", "~> 0.0"
|
26
24
|
s.add_development_dependency 'rake', '< 12.0'
|
27
25
|
s.add_development_dependency 'coveralls', '< 1.0'
|
28
|
-
end
|
29
|
-
|
30
26
|
|
27
|
+
# Install FFI gem if we're running on Windows
|
28
|
+
s.extensions = 'ext/mkrf_conf.rb'
|
29
|
+
end
|
data/ext/mkrf_conf.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Based on the example from https://en.wikibooks.org/wiki/Ruby_Programming/RubyGems#How_to_install_different_versions_of_gems_depending_on_which_version_of_ruby_the_installee_is_using
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/command.rb'
|
4
|
+
require 'rubygems/dependency_installer.rb'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Gem::Command.build_args = ARGV
|
8
|
+
rescue NoMethodError # rubocop:disable Lint/HandleExceptions
|
9
|
+
end
|
10
|
+
|
11
|
+
inst = Gem::DependencyInstaller.new
|
12
|
+
|
13
|
+
begin
|
14
|
+
if Gem.win_platform?
|
15
|
+
inst.install 'ffi', Gem::Requirement.new('~> 1.0', '>= 1.0.11')
|
16
|
+
end
|
17
|
+
rescue # rubocop:disable Lint/RescueWithoutErrorClass
|
18
|
+
exit(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
# create dummy rakefile to indicate success
|
22
|
+
File.open(File.join(File.dirname(__FILE__), 'Rakefile'), 'w') do |f|
|
23
|
+
f.write("task :default\n")
|
24
|
+
end
|
data/lib/childprocess/errors.rb
CHANGED
@@ -14,6 +14,17 @@ module ChildProcess
|
|
14
14
|
class LaunchError < Error
|
15
15
|
end
|
16
16
|
|
17
|
+
class MissingFFIError < Error
|
18
|
+
def initialize
|
19
|
+
message = "FFI is a required pre-requisite for posix_spawn, falling back to default implementation. " +
|
20
|
+
"Please add it to your deployment to unlock this functionality. " +
|
21
|
+
"If you believe this is an error, please file a bug at http://github.com/enkessler/childprocess/issues"
|
22
|
+
|
23
|
+
super(message)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
17
28
|
class MissingPlatformError < Error
|
18
29
|
def initialize
|
19
30
|
message = "posix_spawn is not yet supported on #{ChildProcess.platform_name} (#{RUBY_PLATFORM}), falling back to default implementation. " +
|
@@ -46,24 +46,49 @@ module ChildProcess
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
# Implementation of ChildProcess::JRuby::Process#pid depends heavily on
|
50
|
+
# what Java SDK is being used; here, we look it up once at load, then
|
51
|
+
# define the method once to avoid runtime overhead.
|
52
|
+
normalised_java_version_major = java.lang.System.get_property("java.version")
|
53
|
+
.slice(/^(1\.)?([0-9]+)/, 2)
|
54
|
+
.to_i
|
55
|
+
if normalised_java_version_major >= 9
|
56
|
+
|
57
|
+
# On modern Javas, we can simply delegate through to `Process#pid`,
|
58
|
+
# which was introduced in Java 9.
|
59
|
+
#
|
60
|
+
# @return [Integer] the pid of the process after it has started
|
61
|
+
# @raise [NotImplementedError] when trying to access pid on platform for
|
62
|
+
# which it is unsupported in Java
|
63
|
+
def pid
|
64
|
+
@process.pid
|
65
|
+
rescue java.lang.UnsupportedOperationException => e
|
66
|
+
raise NotImplementedError, "pid is not supported on this platform: #{e.message}"
|
67
|
+
end
|
68
|
+
|
69
|
+
else
|
70
|
+
|
71
|
+
# On Legacy Javas, fall back to reflection.
|
72
|
+
#
|
73
|
+
# Only supported in JRuby on a Unix operating system, thanks to limitations
|
74
|
+
# in Java's classes
|
75
|
+
#
|
76
|
+
# @return [Integer] the pid of the process after it has started
|
77
|
+
# @raise [NotImplementedError] when trying to access pid on non-Unix platform
|
78
|
+
#
|
79
|
+
def pid
|
80
|
+
if @process.getClass.getName != "java.lang.UNIXProcess"
|
81
|
+
raise NotImplementedError, "pid is only supported by JRuby child processes on Unix"
|
82
|
+
end
|
83
|
+
|
84
|
+
# About the best way we can do this is with a nasty reflection-based impl
|
85
|
+
# Thanks to Martijn Courteaux
|
86
|
+
# http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193
|
87
|
+
field = @process.getClass.getDeclaredField("pid")
|
88
|
+
field.accessible = true
|
89
|
+
field.get(@process)
|
59
90
|
end
|
60
91
|
|
61
|
-
# About the best way we can do this is with a nasty reflection-based impl
|
62
|
-
# Thanks to Martijn Courteaux
|
63
|
-
# http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193
|
64
|
-
field = @process.getClass.getDeclaredField("pid")
|
65
|
-
field.accessible = true
|
66
|
-
field.get(@process)
|
67
92
|
end
|
68
93
|
|
69
94
|
private
|
@@ -111,11 +111,11 @@ module ChildProcess
|
|
111
111
|
@ptrs = env.map do |key, val|
|
112
112
|
next if val.nil?
|
113
113
|
|
114
|
-
if key =~ /=|\0/ || val.include?("\0")
|
115
|
-
raise InvalidEnvironmentVariable, "#{key.inspect} => #{val.inspect}"
|
114
|
+
if key =~ /=|\0/ || val.to_s.include?("\0")
|
115
|
+
raise InvalidEnvironmentVariable, "#{key.inspect} => #{val.to_s.inspect}"
|
116
116
|
end
|
117
117
|
|
118
|
-
FFI::MemoryPointer.from_string("#{key}=#{val}")
|
118
|
+
FFI::MemoryPointer.from_string("#{key}=#{val.to_s}")
|
119
119
|
end.compact
|
120
120
|
|
121
121
|
@ptrs << FFI::Pointer.new(0)
|
data/lib/childprocess/version.rb
CHANGED
@@ -39,9 +39,14 @@ module ChildProcess
|
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
|
+
def to_wide_string(str)
|
43
|
+
newstr = str + "\0".encode(str.encoding)
|
44
|
+
newstr.encode!('UTF-16LE')
|
45
|
+
end
|
46
|
+
|
42
47
|
def create_command_pointer
|
43
|
-
string = @args.map { |arg| quote_if_necessary(arg.to_s) }.join
|
44
|
-
@cmd_ptr =
|
48
|
+
string = @args.map { |arg| quote_if_necessary(arg.to_s) }.join(' ')
|
49
|
+
@cmd_ptr = to_wide_string(string)
|
45
50
|
end
|
46
51
|
|
47
52
|
def create_environment_pointer
|
@@ -59,15 +64,12 @@ module ChildProcess
|
|
59
64
|
strings << "#{key}=#{val}\0"
|
60
65
|
end
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@env_ptr = FFI::MemoryPointer.new(:long, env_str.bytesize)
|
66
|
-
@env_ptr.put_bytes 0, env_str, 0, env_str.bytesize
|
67
|
+
env_str = to_wide_string(strings.join)
|
68
|
+
@env_ptr = FFI::MemoryPointer.from_string(env_str)
|
67
69
|
end
|
68
70
|
|
69
71
|
def create_cwd_pointer
|
70
|
-
@cwd_ptr = FFI::MemoryPointer.from_string(@cwd || Dir.pwd)
|
72
|
+
@cwd_ptr = FFI::MemoryPointer.from_string(to_wide_string(@cwd || Dir.pwd))
|
71
73
|
end
|
72
74
|
|
73
75
|
def create_process
|
@@ -98,6 +100,7 @@ module ChildProcess
|
|
98
100
|
end
|
99
101
|
|
100
102
|
def setup_flags
|
103
|
+
@flags |= CREATE_UNICODE_ENVIRONMENT
|
101
104
|
@flags |= DETACHED_PROCESS if @detach
|
102
105
|
@flags |= CREATE_BREAKAWAY_FROM_JOB if @leader
|
103
106
|
end
|
data/lib/childprocess.rb
CHANGED
@@ -73,7 +73,12 @@ module ChildProcess
|
|
73
73
|
enabled = @posix_spawn || %w[1 true].include?(ENV['CHILDPROCESS_POSIX_SPAWN'])
|
74
74
|
return false unless enabled
|
75
75
|
|
76
|
-
|
76
|
+
begin
|
77
|
+
require 'ffi'
|
78
|
+
rescue LoadError
|
79
|
+
raise ChildProcess::MissingFFIError
|
80
|
+
end
|
81
|
+
|
77
82
|
begin
|
78
83
|
require "childprocess/unix/platform/#{ChildProcess.platform_name}"
|
79
84
|
rescue LoadError
|
@@ -113,7 +118,7 @@ module ChildProcess
|
|
113
118
|
:cygwin
|
114
119
|
when /solaris|sunos/
|
115
120
|
:solaris
|
116
|
-
when /bsd/
|
121
|
+
when /bsd|dragonfly/
|
117
122
|
:bsd
|
118
123
|
when /aix/
|
119
124
|
:aix
|
data/spec/childprocess_spec.rb
CHANGED
@@ -83,11 +83,13 @@ describe ChildProcess do
|
|
83
83
|
|
84
84
|
it "lets child process inherit the environment of the current process" do
|
85
85
|
Tempfile.open("env-spec") do |file|
|
86
|
+
file.close
|
86
87
|
with_env('INHERITED' => 'yes') do
|
87
88
|
process = write_env(file.path).start
|
88
89
|
process.wait
|
89
90
|
end
|
90
91
|
|
92
|
+
file.open
|
91
93
|
child_env = eval rewind_and_read(file)
|
92
94
|
expect(child_env['INHERITED']).to eql 'yes'
|
93
95
|
end
|
@@ -95,6 +97,7 @@ describe ChildProcess do
|
|
95
97
|
|
96
98
|
it "can override env vars only for the current process" do
|
97
99
|
Tempfile.open("env-spec") do |file|
|
100
|
+
file.close
|
98
101
|
process = write_env(file.path)
|
99
102
|
process.environment['CHILD_ONLY'] = '1'
|
100
103
|
process.start
|
@@ -103,13 +106,30 @@ describe ChildProcess do
|
|
103
106
|
|
104
107
|
process.wait
|
105
108
|
|
109
|
+
file.open
|
106
110
|
child_env = eval rewind_and_read(file)
|
107
111
|
expect(child_env['CHILD_ONLY']).to eql '1'
|
108
112
|
end
|
109
113
|
end
|
110
114
|
|
115
|
+
it 'allows unicode characters in the environment' do
|
116
|
+
Tempfile.open("env-spec") do |file|
|
117
|
+
file.close
|
118
|
+
process = write_env(file.path)
|
119
|
+
process.environment['FOö'] = 'baör'
|
120
|
+
process.start
|
121
|
+
process.wait
|
122
|
+
|
123
|
+
file.open
|
124
|
+
child_env = eval rewind_and_read(file)
|
125
|
+
|
126
|
+
expect(child_env['FOö']).to eql 'baör'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
111
130
|
it "inherits the parent's env vars also when some are overridden" do
|
112
131
|
Tempfile.open("env-spec") do |file|
|
132
|
+
file.close
|
113
133
|
with_env('INHERITED' => 'yes', 'CHILD_ONLY' => 'no') do
|
114
134
|
process = write_env(file.path)
|
115
135
|
process.environment['CHILD_ONLY'] = 'yes'
|
@@ -117,6 +137,7 @@ describe ChildProcess do
|
|
117
137
|
process.start
|
118
138
|
process.wait
|
119
139
|
|
140
|
+
file.open
|
120
141
|
child_env = eval rewind_and_read(file)
|
121
142
|
|
122
143
|
expect(child_env['INHERITED']).to eq 'yes'
|
@@ -127,6 +148,7 @@ describe ChildProcess do
|
|
127
148
|
|
128
149
|
it "can unset env vars" do
|
129
150
|
Tempfile.open("env-spec") do |file|
|
151
|
+
file.close
|
130
152
|
ENV['CHILDPROCESS_UNSET'] = '1'
|
131
153
|
process = write_env(file.path)
|
132
154
|
process.environment['CHILDPROCESS_UNSET'] = nil
|
@@ -134,6 +156,7 @@ describe ChildProcess do
|
|
134
156
|
|
135
157
|
process.wait
|
136
158
|
|
159
|
+
file.open
|
137
160
|
child_env = eval rewind_and_read(file)
|
138
161
|
expect(child_env).to_not have_key('CHILDPROCESS_UNSET')
|
139
162
|
end
|
@@ -141,12 +164,14 @@ describe ChildProcess do
|
|
141
164
|
|
142
165
|
it 'does not see env vars unset in parent' do
|
143
166
|
Tempfile.open('env-spec') do |file|
|
167
|
+
file.close
|
144
168
|
ENV['CHILDPROCESS_UNSET'] = nil
|
145
169
|
process = write_env(file.path)
|
146
170
|
process.start
|
147
171
|
|
148
172
|
process.wait
|
149
173
|
|
174
|
+
file.open
|
150
175
|
child_env = eval rewind_and_read(file)
|
151
176
|
expect(child_env).to_not have_key('CHILDPROCESS_UNSET')
|
152
177
|
end
|
@@ -289,6 +314,37 @@ describe ChildProcess do
|
|
289
314
|
expect(proc).to be_exited
|
290
315
|
end
|
291
316
|
|
317
|
+
describe 'OS detection' do
|
318
|
+
|
319
|
+
before(:all) do
|
320
|
+
# Save off original OS so that it can be restored later
|
321
|
+
@original_host_os = RbConfig::CONFIG['host_os']
|
322
|
+
end
|
323
|
+
|
324
|
+
after(:each) do
|
325
|
+
# Restore things to the real OS instead of the fake test OS
|
326
|
+
RbConfig::CONFIG['host_os'] = @original_host_os
|
327
|
+
ChildProcess.instance_variable_set(:@os, nil)
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
# TODO: add tests for other OSs
|
332
|
+
context 'on a BSD system' do
|
333
|
+
|
334
|
+
let(:bsd_patterns) { ['bsd', 'dragonfly'] }
|
335
|
+
|
336
|
+
it 'correctly identifies BSD systems' do
|
337
|
+
bsd_patterns.each do |pattern|
|
338
|
+
RbConfig::CONFIG['host_os'] = pattern
|
339
|
+
ChildProcess.instance_variable_set(:@os, nil)
|
340
|
+
|
341
|
+
expect(ChildProcess.os).to eq(:bsd)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
292
348
|
|
293
349
|
it 'has a logger' do
|
294
350
|
expect(ChildProcess).to respond_to(:logger)
|
data/spec/get_env.ps1
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
param($p1)
|
2
|
+
$env_list = Get-ChildItem Env:
|
3
|
+
|
4
|
+
# Builds a ruby hash compatible string
|
5
|
+
$hash_string = "{"
|
6
|
+
|
7
|
+
foreach ($item in $env_list)
|
8
|
+
{
|
9
|
+
$hash_string += "`"" + $item.Name + "`" => `"" + $item.value.replace('\','\\').replace('"','\"') + "`","
|
10
|
+
}
|
11
|
+
$hash_string += "}"
|
12
|
+
|
13
|
+
$hash_string | out-File -Encoding "UTF8" $p1
|
data/spec/spec_helper.rb
CHANGED
@@ -20,6 +20,10 @@ module ChildProcessSpecHelper
|
|
20
20
|
@process = ChildProcess.build(RUBY , *args)
|
21
21
|
end
|
22
22
|
|
23
|
+
def windows_process(*args)
|
24
|
+
@process = ChildProcess.build("powershell", *args)
|
25
|
+
end
|
26
|
+
|
23
27
|
def sleeping_ruby(seconds = nil)
|
24
28
|
if seconds
|
25
29
|
ruby_process("-e", "sleep #{seconds}")
|
@@ -42,11 +46,16 @@ module ChildProcessSpecHelper
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def write_env(path)
|
45
|
-
|
46
|
-
File.
|
47
|
-
|
48
|
-
|
49
|
-
|
49
|
+
if ChildProcess.os == :windows
|
50
|
+
ps_env_file_path = File.expand_path(File.dirname(__FILE__))
|
51
|
+
args = ['-File', "#{ps_env_file_path}/get_env.ps1", path]
|
52
|
+
windows_process(*args)
|
53
|
+
else
|
54
|
+
code = <<-RUBY
|
55
|
+
File.open(#{path.inspect}, "w") { |f| f << ENV.inspect }
|
56
|
+
RUBY
|
57
|
+
ruby_process tmp_script(code)
|
58
|
+
end
|
50
59
|
end
|
51
60
|
|
52
61
|
def write_argv(path, *args)
|
@@ -102,7 +111,7 @@ module ChildProcessSpecHelper
|
|
102
111
|
ruby(<<-CODE)
|
103
112
|
STDIN.sync = STDOUT.sync = true
|
104
113
|
IO.copy_stream(STDIN, STDOUT)
|
105
|
-
|
114
|
+
CODE
|
106
115
|
else
|
107
116
|
ChildProcess.build("cat")
|
108
117
|
end
|
@@ -115,7 +124,7 @@ module ChildProcessSpecHelper
|
|
115
124
|
STDOUT.sync = true
|
116
125
|
|
117
126
|
puts "hello"
|
118
|
-
|
127
|
+
CODE
|
119
128
|
else
|
120
129
|
ChildProcess.build("echo", "hello")
|
121
130
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: childprocess
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jari Bakken
|
@@ -9,28 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-01-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: ffi
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - "~>"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '1.0'
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.0.11
|
24
|
-
type: :runtime
|
25
|
-
prerelease: false
|
26
|
-
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
requirements:
|
28
|
-
- - "~>"
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: '1.0'
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0.11
|
34
14
|
- !ruby/object:Gem::Dependency
|
35
15
|
name: rspec
|
36
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,7 +72,8 @@ description: This gem aims at being a simple and reliable solution for controlli
|
|
92
72
|
email:
|
93
73
|
- morrow748@gmail.com
|
94
74
|
executables: []
|
95
|
-
extensions:
|
75
|
+
extensions:
|
76
|
+
- ext/mkrf_conf.rb
|
96
77
|
extra_rdoc_files: []
|
97
78
|
files:
|
98
79
|
- ".document"
|
@@ -106,6 +87,7 @@ files:
|
|
106
87
|
- Rakefile
|
107
88
|
- appveyor.yml
|
108
89
|
- childprocess.gemspec
|
90
|
+
- ext/mkrf_conf.rb
|
109
91
|
- lib/childprocess.rb
|
110
92
|
- lib/childprocess/abstract_io.rb
|
111
93
|
- lib/childprocess/abstract_process.rb
|
@@ -135,6 +117,7 @@ files:
|
|
135
117
|
- lib/childprocess/windows/structs.rb
|
136
118
|
- spec/abstract_io_spec.rb
|
137
119
|
- spec/childprocess_spec.rb
|
120
|
+
- spec/get_env.ps1
|
138
121
|
- spec/io_spec.rb
|
139
122
|
- spec/jruby_spec.rb
|
140
123
|
- spec/pid_behavior.rb
|
@@ -162,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
145
|
version: '0'
|
163
146
|
requirements: []
|
164
147
|
rubyforge_project: childprocess
|
165
|
-
rubygems_version: 2.
|
148
|
+
rubygems_version: 2.7.6
|
166
149
|
signing_key:
|
167
150
|
specification_version: 4
|
168
151
|
summary: A simple and reliable solution for controlling external programs running
|
@@ -170,6 +153,7 @@ summary: A simple and reliable solution for controlling external programs runnin
|
|
170
153
|
test_files:
|
171
154
|
- spec/abstract_io_spec.rb
|
172
155
|
- spec/childprocess_spec.rb
|
156
|
+
- spec/get_env.ps1
|
173
157
|
- spec/io_spec.rb
|
174
158
|
- spec/jruby_spec.rb
|
175
159
|
- spec/pid_behavior.rb
|