childprocess 0.8.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.document +6 -6
  3. data/.gitignore +28 -28
  4. data/.rspec +1 -1
  5. data/.travis.yml +42 -36
  6. data/CHANGELOG.md +67 -44
  7. data/Gemfile +18 -15
  8. data/LICENSE +20 -20
  9. data/README.md +216 -192
  10. data/Rakefile +61 -61
  11. data/appveyor.yml +42 -43
  12. data/childprocess.gemspec +32 -30
  13. data/ext/mkrf_conf.rb +24 -0
  14. data/lib/childprocess/abstract_io.rb +36 -36
  15. data/lib/childprocess/abstract_process.rb +192 -192
  16. data/lib/childprocess/errors.rb +37 -26
  17. data/lib/childprocess/jruby/io.rb +16 -16
  18. data/lib/childprocess/jruby/process.rb +184 -159
  19. data/lib/childprocess/jruby/pump.rb +53 -53
  20. data/lib/childprocess/jruby.rb +56 -56
  21. data/lib/childprocess/tools/generator.rb +145 -145
  22. data/lib/childprocess/unix/fork_exec_process.rb +78 -70
  23. data/lib/childprocess/unix/io.rb +21 -21
  24. data/lib/childprocess/unix/lib.rb +186 -186
  25. data/lib/childprocess/unix/platform/i386-linux.rb +12 -12
  26. data/lib/childprocess/unix/platform/i386-solaris.rb +11 -11
  27. data/lib/childprocess/unix/platform/x86_64-linux.rb +12 -12
  28. data/lib/childprocess/unix/platform/x86_64-macosx.rb +11 -11
  29. data/lib/childprocess/unix/posix_spawn_process.rb +134 -134
  30. data/lib/childprocess/unix/process.rb +90 -89
  31. data/lib/childprocess/unix.rb +9 -9
  32. data/lib/childprocess/version.rb +3 -3
  33. data/lib/childprocess/windows/handle.rb +91 -91
  34. data/lib/childprocess/windows/io.rb +25 -25
  35. data/lib/childprocess/windows/lib.rb +416 -416
  36. data/lib/childprocess/windows/process.rb +130 -130
  37. data/lib/childprocess/windows/process_builder.rb +178 -175
  38. data/lib/childprocess/windows/structs.rb +148 -148
  39. data/lib/childprocess/windows.rb +33 -33
  40. data/lib/childprocess.rb +210 -205
  41. data/spec/abstract_io_spec.rb +12 -12
  42. data/spec/childprocess_spec.rb +447 -391
  43. data/spec/get_env.ps1 +13 -0
  44. data/spec/io_spec.rb +228 -228
  45. data/spec/jruby_spec.rb +24 -24
  46. data/spec/pid_behavior.rb +12 -12
  47. data/spec/platform_detection_spec.rb +86 -86
  48. data/spec/spec_helper.rb +270 -261
  49. data/spec/unix_spec.rb +57 -57
  50. data/spec/windows_spec.rb +23 -23
  51. metadata +18 -33
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/io_spec.rb CHANGED
@@ -1,228 +1,228 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe ChildProcess do
4
- it "can run even when $stdout is a StringIO" do
5
- begin
6
- stdout = $stdout
7
- $stdout = StringIO.new
8
- expect { sleeping_ruby.start }.to_not raise_error
9
- ensure
10
- $stdout = stdout
11
- end
12
- end
13
-
14
- it "can redirect stdout, stderr" do
15
- process = ruby(<<-CODE)
16
- [STDOUT, STDERR].each_with_index do |io, idx|
17
- io.sync = true
18
- io.puts idx
19
- end
20
- CODE
21
-
22
- out = Tempfile.new("stdout-spec")
23
- err = Tempfile.new("stderr-spec")
24
-
25
- begin
26
- process.io.stdout = out
27
- process.io.stderr = err
28
-
29
- process.start
30
- expect(process.io.stdin).to be_nil
31
- process.wait
32
-
33
- expect(rewind_and_read(out)).to eq "0\n"
34
- expect(rewind_and_read(err)).to eq "1\n"
35
- ensure
36
- out.close
37
- err.close
38
- end
39
- end
40
-
41
- it "can redirect stdout only" do
42
- process = ruby(<<-CODE)
43
- [STDOUT, STDERR].each_with_index do |io, idx|
44
- io.sync = true
45
- io.puts idx
46
- end
47
- CODE
48
-
49
- out = Tempfile.new("stdout-spec")
50
-
51
- begin
52
- process.io.stdout = out
53
-
54
- process.start
55
- process.wait
56
-
57
- expect(rewind_and_read(out)).to eq "0\n"
58
- ensure
59
- out.close
60
- end
61
- end
62
-
63
- it "pumps all output" do
64
- process = echo
65
-
66
- out = Tempfile.new("pump")
67
-
68
- begin
69
- process.io.stdout = out
70
-
71
- process.start
72
- process.wait
73
-
74
- expect(rewind_and_read(out)).to eq "hello\n"
75
- ensure
76
- out.close
77
- end
78
- end
79
-
80
- it "can write to stdin if duplex = true" do
81
- process = cat
82
-
83
- out = Tempfile.new("duplex")
84
- out.sync = true
85
-
86
- begin
87
- process.io.stdout = out
88
- process.io.stderr = out
89
- process.duplex = true
90
-
91
- process.start
92
- process.io.stdin.puts "hello world"
93
- process.io.stdin.close
94
-
95
- process.poll_for_exit(exit_timeout)
96
-
97
- expect(rewind_and_read(out)).to eq "hello world\n"
98
- ensure
99
- out.close
100
- end
101
- end
102
-
103
- it "can write to stdin interactively if duplex = true" do
104
- process = cat
105
-
106
- out = Tempfile.new("duplex")
107
- out.sync = true
108
-
109
- out_receiver = File.open(out.path, "rb")
110
- begin
111
- process.io.stdout = out
112
- process.io.stderr = out
113
- process.duplex = true
114
-
115
- process.start
116
-
117
- stdin = process.io.stdin
118
-
119
- stdin.puts "hello"
120
- stdin.flush
121
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\n\z/m) }
122
-
123
- stdin.putc "n"
124
- stdin.flush
125
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nn\z/m) }
126
-
127
- stdin.print "e"
128
- stdin.flush
129
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nne\z/m) }
130
-
131
- stdin.printf "w"
132
- stdin.flush
133
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\z/m) }
134
-
135
- stdin.write "\nworld\n"
136
- stdin.flush
137
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\r?\nworld\r?\n\z/m) }
138
-
139
- stdin.close
140
- process.poll_for_exit(exit_timeout)
141
- ensure
142
- out_receiver.close
143
- out.close
144
- end
145
- end
146
-
147
- #
148
- # this works on JRuby 1.6.5 on my Mac, but for some reason
149
- # hangs on Travis (running 1.6.5.1 + OpenJDK).
150
- #
151
- # http://travis-ci.org/#!/enkessler/childprocess/jobs/487331
152
- #
153
-
154
- it "works with pipes", :process_builder => false do
155
- process = ruby(<<-CODE)
156
- STDOUT.print "stdout"
157
- STDERR.print "stderr"
158
- CODE
159
-
160
- stdout, stdout_w = IO.pipe
161
- stderr, stderr_w = IO.pipe
162
-
163
- process.io.stdout = stdout_w
164
- process.io.stderr = stderr_w
165
-
166
- process.duplex = true
167
-
168
- process.start
169
- process.wait
170
-
171
- # write streams are closed *after* the process
172
- # has exited - otherwise it won't work on JRuby
173
- # with the current Process implementation
174
-
175
- stdout_w.close
176
- stderr_w.close
177
-
178
- out = stdout.read
179
- err = stderr.read
180
-
181
- expect([out, err]).to eq %w[stdout stderr]
182
- end
183
-
184
- it "can set close-on-exec when IO is inherited" do
185
- port = random_free_port
186
- server = TCPServer.new("127.0.0.1", port)
187
- ChildProcess.close_on_exec server
188
-
189
- process = sleeping_ruby
190
- process.io.inherit!
191
-
192
- process.start
193
- server.close
194
-
195
- wait_until { can_bind? "127.0.0.1", port }
196
- end
197
-
198
- it "handles long output" do
199
- process = ruby <<-CODE
200
- print 'a'*3000
201
- CODE
202
-
203
- out = Tempfile.new("long-output")
204
- out.sync = true
205
-
206
- begin
207
- process.io.stdout = out
208
-
209
- process.start
210
- process.wait
211
-
212
- expect(rewind_and_read(out).size).to eq 3000
213
- ensure
214
- out.close
215
- end
216
- end
217
-
218
- it 'should not inherit stdout and stderr by default' do
219
- cap = capture_std do
220
- process = echo
221
- process.start
222
- process.wait
223
- end
224
-
225
- expect(cap.stdout).to eq ''
226
- expect(cap.stderr).to eq ''
227
- end
228
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe ChildProcess do
4
+ it "can run even when $stdout is a StringIO" do
5
+ begin
6
+ stdout = $stdout
7
+ $stdout = StringIO.new
8
+ expect { sleeping_ruby.start }.to_not raise_error
9
+ ensure
10
+ $stdout = stdout
11
+ end
12
+ end
13
+
14
+ it "can redirect stdout, stderr" do
15
+ process = ruby(<<-CODE)
16
+ [STDOUT, STDERR].each_with_index do |io, idx|
17
+ io.sync = true
18
+ io.puts idx
19
+ end
20
+ CODE
21
+
22
+ out = Tempfile.new("stdout-spec")
23
+ err = Tempfile.new("stderr-spec")
24
+
25
+ begin
26
+ process.io.stdout = out
27
+ process.io.stderr = err
28
+
29
+ process.start
30
+ expect(process.io.stdin).to be_nil
31
+ process.wait
32
+
33
+ expect(rewind_and_read(out)).to eq "0\n"
34
+ expect(rewind_and_read(err)).to eq "1\n"
35
+ ensure
36
+ out.close
37
+ err.close
38
+ end
39
+ end
40
+
41
+ it "can redirect stdout only" do
42
+ process = ruby(<<-CODE)
43
+ [STDOUT, STDERR].each_with_index do |io, idx|
44
+ io.sync = true
45
+ io.puts idx
46
+ end
47
+ CODE
48
+
49
+ out = Tempfile.new("stdout-spec")
50
+
51
+ begin
52
+ process.io.stdout = out
53
+
54
+ process.start
55
+ process.wait
56
+
57
+ expect(rewind_and_read(out)).to eq "0\n"
58
+ ensure
59
+ out.close
60
+ end
61
+ end
62
+
63
+ it "pumps all output" do
64
+ process = echo
65
+
66
+ out = Tempfile.new("pump")
67
+
68
+ begin
69
+ process.io.stdout = out
70
+
71
+ process.start
72
+ process.wait
73
+
74
+ expect(rewind_and_read(out)).to eq "hello\n"
75
+ ensure
76
+ out.close
77
+ end
78
+ end
79
+
80
+ it "can write to stdin if duplex = true" do
81
+ process = cat
82
+
83
+ out = Tempfile.new("duplex")
84
+ out.sync = true
85
+
86
+ begin
87
+ process.io.stdout = out
88
+ process.io.stderr = out
89
+ process.duplex = true
90
+
91
+ process.start
92
+ process.io.stdin.puts "hello world"
93
+ process.io.stdin.close
94
+
95
+ process.poll_for_exit(exit_timeout)
96
+
97
+ expect(rewind_and_read(out)).to eq "hello world\n"
98
+ ensure
99
+ out.close
100
+ end
101
+ end
102
+
103
+ it "can write to stdin interactively if duplex = true" do
104
+ process = cat
105
+
106
+ out = Tempfile.new("duplex")
107
+ out.sync = true
108
+
109
+ out_receiver = File.open(out.path, "rb")
110
+ begin
111
+ process.io.stdout = out
112
+ process.io.stderr = out
113
+ process.duplex = true
114
+
115
+ process.start
116
+
117
+ stdin = process.io.stdin
118
+
119
+ stdin.puts "hello"
120
+ stdin.flush
121
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\n\z/m) }
122
+
123
+ stdin.putc "n"
124
+ stdin.flush
125
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nn\z/m) }
126
+
127
+ stdin.print "e"
128
+ stdin.flush
129
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nne\z/m) }
130
+
131
+ stdin.printf "w"
132
+ stdin.flush
133
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\z/m) }
134
+
135
+ stdin.write "\nworld\n"
136
+ stdin.flush
137
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\r?\nworld\r?\n\z/m) }
138
+
139
+ stdin.close
140
+ process.poll_for_exit(exit_timeout)
141
+ ensure
142
+ out_receiver.close
143
+ out.close
144
+ end
145
+ end
146
+
147
+ #
148
+ # this works on JRuby 1.6.5 on my Mac, but for some reason
149
+ # hangs on Travis (running 1.6.5.1 + OpenJDK).
150
+ #
151
+ # http://travis-ci.org/#!/enkessler/childprocess/jobs/487331
152
+ #
153
+
154
+ it "works with pipes", :process_builder => false do
155
+ process = ruby(<<-CODE)
156
+ STDOUT.print "stdout"
157
+ STDERR.print "stderr"
158
+ CODE
159
+
160
+ stdout, stdout_w = IO.pipe
161
+ stderr, stderr_w = IO.pipe
162
+
163
+ process.io.stdout = stdout_w
164
+ process.io.stderr = stderr_w
165
+
166
+ process.duplex = true
167
+
168
+ process.start
169
+ process.wait
170
+
171
+ # write streams are closed *after* the process
172
+ # has exited - otherwise it won't work on JRuby
173
+ # with the current Process implementation
174
+
175
+ stdout_w.close
176
+ stderr_w.close
177
+
178
+ out = stdout.read
179
+ err = stderr.read
180
+
181
+ expect([out, err]).to eq %w[stdout stderr]
182
+ end
183
+
184
+ it "can set close-on-exec when IO is inherited" do
185
+ port = random_free_port
186
+ server = TCPServer.new("127.0.0.1", port)
187
+ ChildProcess.close_on_exec server
188
+
189
+ process = sleeping_ruby
190
+ process.io.inherit!
191
+
192
+ process.start
193
+ server.close
194
+
195
+ wait_until { can_bind? "127.0.0.1", port }
196
+ end
197
+
198
+ it "handles long output" do
199
+ process = ruby <<-CODE
200
+ print 'a'*3000
201
+ CODE
202
+
203
+ out = Tempfile.new("long-output")
204
+ out.sync = true
205
+
206
+ begin
207
+ process.io.stdout = out
208
+
209
+ process.start
210
+ process.wait
211
+
212
+ expect(rewind_and_read(out).size).to eq 3000
213
+ ensure
214
+ out.close
215
+ end
216
+ end
217
+
218
+ it 'should not inherit stdout and stderr by default' do
219
+ cap = capture_std do
220
+ process = echo
221
+ process.start
222
+ process.wait
223
+ end
224
+
225
+ expect(cap.stdout).to eq ''
226
+ expect(cap.stderr).to eq ''
227
+ end
228
+ end
data/spec/jruby_spec.rb CHANGED
@@ -1,24 +1,24 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
- require "pid_behavior"
3
-
4
- if ChildProcess.jruby? && !ChildProcess.windows?
5
- describe ChildProcess::JRuby::IO do
6
- let(:io) { ChildProcess::JRuby::IO.new }
7
-
8
- it "raises an ArgumentError if given IO does not respond to :to_outputstream" do
9
- expect { io.stdout = nil }.to raise_error(ArgumentError)
10
- end
11
- end
12
-
13
- describe ChildProcess::JRuby::Process do
14
- if ChildProcess.unix?
15
- it_behaves_like "a platform that provides the child's pid"
16
- else
17
- it "raises an error when trying to access the child's pid" do
18
- process = exit_with(0)
19
- process.start
20
- expect { process.pid }.to raise_error(NotImplementedError)
21
- end
22
- end
23
- end
24
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require "pid_behavior"
3
+
4
+ if ChildProcess.jruby? && !ChildProcess.windows?
5
+ describe ChildProcess::JRuby::IO do
6
+ let(:io) { ChildProcess::JRuby::IO.new }
7
+
8
+ it "raises an ArgumentError if given IO does not respond to :to_outputstream" do
9
+ expect { io.stdout = nil }.to raise_error(ArgumentError)
10
+ end
11
+ end
12
+
13
+ describe ChildProcess::JRuby::Process do
14
+ if ChildProcess.unix?
15
+ it_behaves_like "a platform that provides the child's pid"
16
+ else
17
+ it "raises an error when trying to access the child's pid" do
18
+ process = exit_with(0)
19
+ process.start
20
+ expect { process.pid }.to raise_error(NotImplementedError)
21
+ end
22
+ end
23
+ end
24
+ end
data/spec/pid_behavior.rb CHANGED
@@ -1,12 +1,12 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- shared_examples_for "a platform that provides the child's pid" do
4
- it "knows the child's pid" do
5
- Tempfile.open("pid-spec") do |file|
6
- process = write_pid(file.path).start
7
- process.wait
8
-
9
- expect(process.pid).to eq rewind_and_read(file).chomp.to_i
10
- end
11
- end
12
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ shared_examples_for "a platform that provides the child's pid" do
4
+ it "knows the child's pid" do
5
+ Tempfile.open("pid-spec") do |file|
6
+ process = write_pid(file.path).start
7
+ process.wait
8
+
9
+ expect(process.pid).to eq rewind_and_read(file).chomp.to_i
10
+ end
11
+ end
12
+ end