toys-core 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/standard_mixins/exec.rb +60 -26
- data/lib/toys/standard_mixins/terminal.rb +1 -0
- data/lib/toys/utils/exec.rb +132 -71
- data/lib/toys/utils/terminal.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a85fbb6170bb1609f304cc0b1a62d4743437802b64c796372d569856bdd1e256
|
4
|
+
data.tar.gz: 8291edf5cd82f0bbbcafb83878351415a28f8d0a21e058332184534c08e29751
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 701ff10d98b0ae6f2b8c9d758c8dcb1769622a59dc3e86b85fedfae327811403c3ae514b05060eb91b701948cd275d94c86fa20973724864fc9c2b4aae355f90
|
7
|
+
data.tar.gz: b042cb80c9fb0f9d0d0132b546384179efc69873e4d060c20b7e2bc1b7c6e36721d27655e4efa4b77960cc899e726bbc47e92cbdbfd5cf2c18289dcde0b8e3cb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.4.3 / 2018-07-13
|
4
|
+
|
5
|
+
* IMPROVED: Utils::Exec methods can now spawn subprocesses in the background
|
6
|
+
* IMPROVED: Utils::Exec capture methods can now yield a controller
|
7
|
+
|
3
8
|
### 0.4.2 / 2018-07-08
|
4
9
|
|
5
10
|
* FIXED: Raise an error rather than cause unexpected behavior if a mixin is included twice.
|
data/lib/toys/core_version.rb
CHANGED
@@ -100,8 +100,8 @@ module Toys
|
|
100
100
|
# Execute a command. The command may be given as a single string to pass
|
101
101
|
# to a shell, or an array of strings indicating a posix command.
|
102
102
|
#
|
103
|
-
# If
|
104
|
-
#
|
103
|
+
# If the process is not set to run in the background, and a block is
|
104
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
105
105
|
#
|
106
106
|
# @param [String,Array<String>] cmd The command to execute.
|
107
107
|
# @param [Hash] opts The command options. All options listed in the
|
@@ -110,8 +110,9 @@ module Toys
|
|
110
110
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
|
111
111
|
# the subprocess streams.
|
112
112
|
#
|
113
|
-
# @return [Toys::Utils::Exec::Result] The
|
114
|
-
#
|
113
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
114
|
+
# subprocess controller or result, depending on whether the process
|
115
|
+
# is running in the background or foreground.
|
115
116
|
#
|
116
117
|
def exec(cmd, opts = {}, &block)
|
117
118
|
self[KEY].exec(cmd, Exec._setup_exec_opts(opts, self), &block)
|
@@ -120,8 +121,8 @@ module Toys
|
|
120
121
|
##
|
121
122
|
# Spawn a ruby process and pass the given arguments to it.
|
122
123
|
#
|
123
|
-
# If
|
124
|
-
#
|
124
|
+
# If the process is not set to run in the background, and a block is
|
125
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
125
126
|
#
|
126
127
|
# @param [String,Array<String>] args The arguments to ruby.
|
127
128
|
# @param [Hash] opts The command options. All options listed in the
|
@@ -130,8 +131,9 @@ module Toys
|
|
130
131
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
|
131
132
|
# for the subprocess streams.
|
132
133
|
#
|
133
|
-
# @return [Toys::Utils::Exec::Result] The
|
134
|
-
#
|
134
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
135
|
+
# subprocess controller or result, depending on whether the process
|
136
|
+
# is running in the background or foreground.
|
135
137
|
#
|
136
138
|
def exec_ruby(args, opts = {}, &block)
|
137
139
|
self[KEY].exec_ruby(args, Exec._setup_exec_opts(opts, self), &block)
|
@@ -141,8 +143,8 @@ module Toys
|
|
141
143
|
##
|
142
144
|
# Execute a proc in a subprocess.
|
143
145
|
#
|
144
|
-
# If
|
145
|
-
#
|
146
|
+
# If the process is not set to run in the background, and a block is
|
147
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
146
148
|
#
|
147
149
|
# @param [Proc] func The proc to call.
|
148
150
|
# @param [Hash] opts The command options. Most options listed in the
|
@@ -151,8 +153,9 @@ module Toys
|
|
151
153
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
152
154
|
# for the subprocess streams.
|
153
155
|
#
|
154
|
-
# @return [Toys::Utils::Exec::Result] The
|
155
|
-
#
|
156
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
157
|
+
# subprocess controller or result, depending on whether the process
|
158
|
+
# is running in the background or foreground.
|
156
159
|
#
|
157
160
|
def exec_proc(func, opts = {}, &block)
|
158
161
|
self[KEY].exec_proc(func, Exec._setup_exec_opts(opts, self), &block)
|
@@ -162,8 +165,8 @@ module Toys
|
|
162
165
|
# Execute a tool. The command may be given as a single string or an array
|
163
166
|
# of strings, representing the tool to run and the arguments to pass.
|
164
167
|
#
|
165
|
-
# If
|
166
|
-
#
|
168
|
+
# If the process is not set to run in the background, and a block is
|
169
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
167
170
|
#
|
168
171
|
# @param [String,Array<String>] cmd The tool to execute.
|
169
172
|
# @param [Hash] opts The command options. Most options listed in the
|
@@ -172,8 +175,9 @@ module Toys
|
|
172
175
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
173
176
|
# for the subprocess streams.
|
174
177
|
#
|
175
|
-
# @return [Toys::Utils::Exec::Result] The
|
176
|
-
#
|
178
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
179
|
+
# subprocess controller or result, depending on whether the process
|
180
|
+
# is running in the background or foreground.
|
177
181
|
#
|
178
182
|
def exec_tool(cmd, opts = {}, &block)
|
179
183
|
func = Exec._make_tool_caller(cmd)
|
@@ -185,48 +189,66 @@ module Toys
|
|
185
189
|
# to a shell, or an array of strings indicating a posix command.
|
186
190
|
#
|
187
191
|
# Captures standard out and returns it as a string.
|
192
|
+
# Cannot be run in the background.
|
193
|
+
#
|
194
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
195
|
+
# yielded to it.
|
188
196
|
#
|
189
197
|
# @param [String,Array<String>] cmd The command to execute.
|
190
198
|
# @param [Hash] opts The command options. All options listed in the
|
191
199
|
# {Toys::Utils::Exec} documentation are supported, plus the
|
192
200
|
# `exit_on_nonzero_status` option.
|
201
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
202
|
+
# for the subprocess streams.
|
193
203
|
#
|
194
204
|
# @return [String] What was written to standard out.
|
195
205
|
#
|
196
|
-
def capture(cmd, opts = {})
|
197
|
-
self[KEY].capture(cmd, Exec._setup_exec_opts(opts, self))
|
206
|
+
def capture(cmd, opts = {}, &block)
|
207
|
+
self[KEY].capture(cmd, Exec._setup_exec_opts(opts, self), &block)
|
198
208
|
end
|
199
209
|
|
200
210
|
##
|
201
211
|
# Spawn a ruby process and pass the given arguments to it.
|
202
212
|
#
|
203
213
|
# Captures standard out and returns it as a string.
|
214
|
+
# Cannot be run in the background.
|
215
|
+
#
|
216
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
217
|
+
# yielded to it.
|
204
218
|
#
|
205
219
|
# @param [String,Array<String>] args The arguments to ruby.
|
206
220
|
# @param [Hash] opts The command options. All options listed in the
|
207
221
|
# {Toys::Utils::Exec} documentation are supported, plus the
|
208
222
|
# `exit_on_nonzero_status` option.
|
223
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
224
|
+
# for the subprocess streams.
|
209
225
|
#
|
210
226
|
# @return [String] What was written to standard out.
|
211
227
|
#
|
212
|
-
def capture_ruby(args, opts = {})
|
213
|
-
self[KEY].capture_ruby(args, Exec._setup_exec_opts(opts, self))
|
228
|
+
def capture_ruby(args, opts = {}, &block)
|
229
|
+
self[KEY].capture_ruby(args, Exec._setup_exec_opts(opts, self), &block)
|
214
230
|
end
|
215
231
|
|
216
232
|
##
|
217
233
|
# Execute a proc in a subprocess.
|
218
234
|
#
|
219
235
|
# Captures standard out and returns it as a string.
|
236
|
+
# Cannot be run in the background.
|
237
|
+
#
|
238
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
239
|
+
# yielded to it.
|
220
240
|
#
|
221
241
|
# @param [Proc] func The proc to call.
|
222
242
|
# @param [Hash] opts The command options. Most options listed in the
|
223
243
|
# {Toys::Utils::Exec} documentation are supported, plus the
|
224
244
|
# `exit_on_nonzero_status` option.
|
245
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
246
|
+
# for the subprocess streams.
|
225
247
|
#
|
226
248
|
# @return [String] What was written to standard out.
|
227
249
|
#
|
228
|
-
def capture_proc(func, opts = {})
|
229
|
-
self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self))
|
250
|
+
def capture_proc(func, opts = {}, &block)
|
251
|
+
self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self), &block)
|
230
252
|
end
|
231
253
|
|
232
254
|
##
|
@@ -234,31 +256,43 @@ module Toys
|
|
234
256
|
# of strings, representing the tool to run and the arguments to pass.
|
235
257
|
#
|
236
258
|
# Captures standard out and returns it as a string.
|
259
|
+
# Cannot be run in the background.
|
260
|
+
#
|
261
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
262
|
+
# yielded to it.
|
237
263
|
#
|
238
264
|
# @param [String,Array<String>] cmd The tool to execute.
|
239
265
|
# @param [Hash] opts The command options. Most options listed in the
|
240
266
|
# {Toys::Utils::Exec} documentation are supported, plus the
|
241
267
|
# `exit_on_nonzero_status` option.
|
268
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
269
|
+
# for the subprocess streams.
|
242
270
|
#
|
243
271
|
# @return [String] What was written to standard out.
|
244
272
|
#
|
245
|
-
def capture_tool(cmd, opts = {})
|
273
|
+
def capture_tool(cmd, opts = {}, &block)
|
246
274
|
func = Exec._make_tool_caller(cmd)
|
247
|
-
self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self))
|
275
|
+
self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self), &block)
|
248
276
|
end
|
249
277
|
|
250
278
|
##
|
251
279
|
# Execute the given string in a shell. Returns the exit code.
|
280
|
+
# Cannot be run in the background.
|
281
|
+
#
|
282
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
283
|
+
# yielded to it.
|
252
284
|
#
|
253
285
|
# @param [String] cmd The shell command to execute.
|
254
286
|
# @param [Hash] opts The command options. All options listed in the
|
255
287
|
# {Toys::Utils::Exec} documentation are supported, plus the
|
256
288
|
# `exit_on_nonzero_status` option.
|
289
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
290
|
+
# for the subprocess streams.
|
257
291
|
#
|
258
292
|
# @return [Integer] The exit code
|
259
293
|
#
|
260
|
-
def sh(cmd, opts = {})
|
261
|
-
self[KEY].sh(cmd, Exec._setup_exec_opts(opts, self))
|
294
|
+
def sh(cmd, opts = {}, &block)
|
295
|
+
self[KEY].sh(cmd, Exec._setup_exec_opts(opts, self), &block)
|
262
296
|
end
|
263
297
|
|
264
298
|
##
|
data/lib/toys/utils/exec.rb
CHANGED
@@ -50,6 +50,8 @@ module Toys
|
|
50
50
|
# If not present, the command is not logged.
|
51
51
|
# * **:log_level** (Integer) Log level for logging the actual command.
|
52
52
|
# Defaults to Logger::INFO if not present.
|
53
|
+
# * **:background** (Boolean) Runs the process in the background,
|
54
|
+
# returning a controller object instead of a result object.
|
53
55
|
# * **:in** Connects the input stream of the subprocess. See the section
|
54
56
|
# on stream handling.
|
55
57
|
# * **:out** Connects the standard output stream of the subprocess. See
|
@@ -95,7 +97,11 @@ module Toys
|
|
95
97
|
# `Process#spawn`.
|
96
98
|
# * **Redirect to null:** You may redirect to a null stream by passing
|
97
99
|
# `:null` as the option value. This connects to a stream that is not
|
98
|
-
# closed but contains no data, i.e. `/dev/null` on unix systems.
|
100
|
+
# closed but contains no data, i.e. `/dev/null` on unix systems. This is
|
101
|
+
# the default if the subprocess is run in the background.
|
102
|
+
# * **Inherit parent stream:** You may inherit the corresponding stream in
|
103
|
+
# the parent process by passing `:inherit` as the option value. This is
|
104
|
+
# the default if the subprocess is *not* run in the background.
|
99
105
|
# * **Redirect to a file:** You may redirect to a file. This reads from an
|
100
106
|
# existing file when connected to `:in`, and creates or appends to a
|
101
107
|
# file when connected to `:out` or `:err`. To specify a file, use the
|
@@ -147,8 +153,8 @@ module Toys
|
|
147
153
|
# Execute a command. The command may be given as a single string to pass
|
148
154
|
# to a shell, or an array of strings indicating a posix command.
|
149
155
|
#
|
150
|
-
# If
|
151
|
-
#
|
156
|
+
# If the process is not set to run in the background, and a block is
|
157
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
152
158
|
#
|
153
159
|
# @param [String,Array<String>] cmd The command to execute.
|
154
160
|
# @param [Hash] opts The command options. See the section on
|
@@ -156,8 +162,9 @@ module Toys
|
|
156
162
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
157
163
|
# for the subprocess streams.
|
158
164
|
#
|
159
|
-
# @return [Toys::Utils::Exec::Result] The
|
160
|
-
#
|
165
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
166
|
+
# subprocess controller or result, depending on whether the process
|
167
|
+
# is running in the background or foreground.
|
161
168
|
#
|
162
169
|
def exec(cmd, opts = {}, &block)
|
163
170
|
exec_opts = Opts.new(@default_opts).add(opts)
|
@@ -171,15 +178,15 @@ module Toys
|
|
171
178
|
else
|
172
179
|
[cmd]
|
173
180
|
end
|
174
|
-
executor = Executor.new(exec_opts, spawn_cmd)
|
175
|
-
executor.execute
|
181
|
+
executor = Executor.new(exec_opts, spawn_cmd, block)
|
182
|
+
executor.execute
|
176
183
|
end
|
177
184
|
|
178
185
|
##
|
179
186
|
# Spawn a ruby process and pass the given arguments to it.
|
180
187
|
#
|
181
|
-
# If
|
182
|
-
#
|
188
|
+
# If the process is not set to run in the background, and a block is
|
189
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
183
190
|
#
|
184
191
|
# @param [String,Array<String>] args The arguments to ruby.
|
185
192
|
# @param [Hash] opts The command options. See the section on
|
@@ -187,8 +194,9 @@ module Toys
|
|
187
194
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
188
195
|
# for the subprocess streams.
|
189
196
|
#
|
190
|
-
# @return [Toys::Utils::Exec::Result] The
|
191
|
-
#
|
197
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
198
|
+
# subprocess controller or result, depending on whether the process
|
199
|
+
# is running in the background or foreground.
|
192
200
|
#
|
193
201
|
def exec_ruby(args, opts = {}, &block)
|
194
202
|
cmd = args.is_a?(::Array) ? [::RbConfig.ruby] + args : "#{::RbConfig.ruby} #{args}"
|
@@ -200,8 +208,8 @@ module Toys
|
|
200
208
|
##
|
201
209
|
# Execute a proc in a fork.
|
202
210
|
#
|
203
|
-
# If
|
204
|
-
#
|
211
|
+
# If the process is not set to run in the background, and a block is
|
212
|
+
# provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
|
205
213
|
#
|
206
214
|
# @param [Proc] func The proc to call.
|
207
215
|
# @param [Hash] opts The command options. See the section on
|
@@ -209,13 +217,14 @@ module Toys
|
|
209
217
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
210
218
|
# for the subprocess streams.
|
211
219
|
#
|
212
|
-
# @return [Toys::Utils::Exec::Result] The
|
213
|
-
#
|
220
|
+
# @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
|
221
|
+
# subprocess controller or result, depending on whether the process
|
222
|
+
# is running in the background or foreground.
|
214
223
|
#
|
215
224
|
def exec_proc(func, opts = {}, &block)
|
216
225
|
exec_opts = Opts.new(@default_opts).add(opts)
|
217
|
-
executor = Executor.new(exec_opts, func)
|
218
|
-
executor.execute
|
226
|
+
executor = Executor.new(exec_opts, func, block)
|
227
|
+
executor.execute
|
219
228
|
end
|
220
229
|
|
221
230
|
##
|
@@ -223,58 +232,79 @@ module Toys
|
|
223
232
|
# to a shell, or an array of strings indicating a posix command.
|
224
233
|
#
|
225
234
|
# Captures standard out and returns it as a string.
|
235
|
+
# Cannot be run in the background.
|
236
|
+
#
|
237
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
238
|
+
# yielded to it.
|
226
239
|
#
|
227
240
|
# @param [String,Array<String>] cmd The command to execute.
|
228
241
|
# @param [Hash] opts The command options. See the section on
|
229
242
|
# configuration options in the {Toys::Utils::Exec} module docs.
|
243
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
244
|
+
# for the subprocess streams.
|
230
245
|
#
|
231
246
|
# @return [String] What was written to standard out.
|
232
247
|
#
|
233
|
-
def capture(cmd, opts = {})
|
234
|
-
exec(cmd, opts.merge(out: :capture)).captured_out
|
248
|
+
def capture(cmd, opts = {}, &block)
|
249
|
+
exec(cmd, opts.merge(out: :capture, background: false), &block).captured_out
|
235
250
|
end
|
236
251
|
|
237
252
|
##
|
238
253
|
# Spawn a ruby process and pass the given arguments to it.
|
239
254
|
#
|
240
255
|
# Captures standard out and returns it as a string.
|
256
|
+
# Cannot be run in the background.
|
257
|
+
#
|
258
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
259
|
+
# yielded to it.
|
241
260
|
#
|
242
261
|
# @param [String,Array<String>] args The arguments to ruby.
|
243
262
|
# @param [Hash] opts The command options. See the section on
|
244
263
|
# configuration options in the {Toys::Utils::Exec} module docs.
|
264
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
265
|
+
# for the subprocess streams.
|
245
266
|
#
|
246
267
|
# @return [String] What was written to standard out.
|
247
268
|
#
|
248
|
-
def capture_ruby(args, opts = {})
|
249
|
-
ruby(args, opts.merge(out: :capture)).captured_out
|
269
|
+
def capture_ruby(args, opts = {}, &block)
|
270
|
+
ruby(args, opts.merge(out: :capture, background: false), &block).captured_out
|
250
271
|
end
|
251
272
|
|
252
273
|
##
|
253
274
|
# Execute a proc in a fork.
|
254
275
|
#
|
255
276
|
# Captures standard out and returns it as a string.
|
277
|
+
# Cannot be run in the background.
|
278
|
+
#
|
279
|
+
# If a block is provided, a {Toys::Utils::Exec::Controller} will be
|
280
|
+
# yielded to it.
|
256
281
|
#
|
257
282
|
# @param [Proc] func The proc to call.
|
258
283
|
# @param [Hash] opts The command options. See the section on
|
259
284
|
# configuration options in the {Toys::Utils::Exec} module docs.
|
285
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
286
|
+
# for the subprocess streams.
|
260
287
|
#
|
261
288
|
# @return [String] What was written to standard out.
|
262
289
|
#
|
263
|
-
def capture_proc(func, opts = {})
|
264
|
-
exec_proc(func, opts.merge(out: :capture)).captured_out
|
290
|
+
def capture_proc(func, opts = {}, &block)
|
291
|
+
exec_proc(func, opts.merge(out: :capture, background: false), &block).captured_out
|
265
292
|
end
|
266
293
|
|
267
294
|
##
|
268
295
|
# Execute the given string in a shell. Returns the exit code.
|
296
|
+
# Cannot be run in the background.
|
269
297
|
#
|
270
298
|
# @param [String] cmd The shell command to execute.
|
271
299
|
# @param [Hash] opts The command options. See the section on
|
272
300
|
# configuration options in the {Toys::Utils::Exec} module docs.
|
301
|
+
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
302
|
+
# for the subprocess streams.
|
273
303
|
#
|
274
304
|
# @return [Integer] The exit code
|
275
305
|
#
|
276
|
-
def sh(cmd, opts = {})
|
277
|
-
exec(cmd, opts).exit_code
|
306
|
+
def sh(cmd, opts = {}, &block)
|
307
|
+
exec(cmd, opts.merge(background: false), &block).exit_code
|
278
308
|
end
|
279
309
|
|
280
310
|
##
|
@@ -288,6 +318,7 @@ module Toys
|
|
288
318
|
#
|
289
319
|
CONFIG_KEYS = %i[
|
290
320
|
argv0
|
321
|
+
background
|
291
322
|
cli
|
292
323
|
env
|
293
324
|
err
|
@@ -356,17 +387,24 @@ module Toys
|
|
356
387
|
end
|
357
388
|
|
358
389
|
##
|
359
|
-
# An object
|
390
|
+
# An object that controls a subprocess. This object is returned from an
|
391
|
+
# execution running in the background, or is yielded to a control block
|
392
|
+
# for an execution running in the foreground.
|
360
393
|
# You may use this object to interact with the subcommand's streams,
|
361
|
-
#
|
394
|
+
# send signals to the process, and get its result.
|
362
395
|
#
|
363
396
|
class Controller
|
364
397
|
## @private
|
365
|
-
def initialize(
|
366
|
-
@in =
|
367
|
-
@out = out
|
368
|
-
@err = err
|
398
|
+
def initialize(controller_streams, captures, pid, join_threads, nonzero_status_handler)
|
399
|
+
@in = controller_streams[:in]
|
400
|
+
@out = controller_streams[:out]
|
401
|
+
@err = controller_streams[:err]
|
402
|
+
@captures = captures
|
369
403
|
@pid = pid
|
404
|
+
@join_threads = join_threads
|
405
|
+
@nonzero_status_handler = nonzero_status_handler
|
406
|
+
@wait_thread = ::Process.detach(pid)
|
407
|
+
@result = nil
|
370
408
|
end
|
371
409
|
|
372
410
|
##
|
@@ -408,6 +446,47 @@ module Toys
|
|
408
446
|
def kill(signal)
|
409
447
|
::Process.kill(signal, pid)
|
410
448
|
end
|
449
|
+
|
450
|
+
##
|
451
|
+
# Determine whether the subcommand is still executing
|
452
|
+
#
|
453
|
+
# @return [Boolean]
|
454
|
+
#
|
455
|
+
def executing?
|
456
|
+
@wait_thread.status ? true : false
|
457
|
+
end
|
458
|
+
|
459
|
+
##
|
460
|
+
# Wait for the subcommand to complete, and return a result object.
|
461
|
+
#
|
462
|
+
# @param [Numeric,nil] timeout The timeout in seconds, or `nil` to
|
463
|
+
# wait indefinitely.
|
464
|
+
# @return [Toys::Utils::Exec::Result,nil] The result object, or `nil`
|
465
|
+
# if a timeout occurred.
|
466
|
+
#
|
467
|
+
def result(timeout: nil)
|
468
|
+
return nil unless @wait_thread.join(timeout)
|
469
|
+
@result ||= begin
|
470
|
+
close_streams
|
471
|
+
@join_threads.each(&:join)
|
472
|
+
status = @wait_thread.value
|
473
|
+
if @nonzero_status_handler && status.exitstatus != 0
|
474
|
+
@nonzero_status_handler.call(status)
|
475
|
+
end
|
476
|
+
Result.new(@captures[:out], @captures[:err], status)
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
##
|
481
|
+
# Close all the controller's streams.
|
482
|
+
# @private
|
483
|
+
#
|
484
|
+
def close_streams
|
485
|
+
@in.close if @in && !@in.closed?
|
486
|
+
@out.close if @out && !@out.closed?
|
487
|
+
@err.close if @err && !@err.closed?
|
488
|
+
self
|
489
|
+
end
|
411
490
|
end
|
412
491
|
|
413
492
|
##
|
@@ -471,7 +550,7 @@ module Toys
|
|
471
550
|
# @private
|
472
551
|
#
|
473
552
|
class Executor
|
474
|
-
def initialize(exec_opts, spawn_cmd)
|
553
|
+
def initialize(exec_opts, spawn_cmd, block)
|
475
554
|
@fork_func = spawn_cmd.respond_to?(:call) ? spawn_cmd : nil
|
476
555
|
@spawn_cmd = spawn_cmd.respond_to?(:call) ? nil : spawn_cmd
|
477
556
|
@config_opts = exec_opts.config_opts
|
@@ -481,18 +560,26 @@ module Toys
|
|
481
560
|
@join_threads = []
|
482
561
|
@child_streams = []
|
483
562
|
@parent_streams = []
|
563
|
+
@block = block
|
564
|
+
@default_stream = @config_opts[:background] ? :null : :inherit
|
484
565
|
end
|
485
566
|
|
486
|
-
def execute
|
567
|
+
def execute
|
487
568
|
setup_in_stream
|
488
|
-
setup_out_stream(:out
|
489
|
-
setup_out_stream(:err
|
569
|
+
setup_out_stream(:out)
|
570
|
+
setup_out_stream(:err)
|
490
571
|
log_command
|
491
572
|
pid = @fork_func ? start_fork : start_process
|
492
573
|
@child_streams.each(&:close)
|
493
|
-
|
494
|
-
|
495
|
-
|
574
|
+
controller = Controller.new(@controller_streams, @captures, pid, @join_threads,
|
575
|
+
@config_opts[:nonzero_status_handler])
|
576
|
+
return controller if @config_opts[:background]
|
577
|
+
begin
|
578
|
+
@block&.call(controller)
|
579
|
+
ensure
|
580
|
+
controller.close_streams
|
581
|
+
end
|
582
|
+
controller.result
|
496
583
|
end
|
497
584
|
|
498
585
|
private
|
@@ -613,34 +700,8 @@ module Toys
|
|
613
700
|
end
|
614
701
|
end
|
615
702
|
|
616
|
-
def control_process(wait_thread)
|
617
|
-
begin
|
618
|
-
if block_given?
|
619
|
-
controller = Controller.new(
|
620
|
-
@controller_streams[:in], @controller_streams[:out], @controller_streams[:err],
|
621
|
-
wait_thread.pid
|
622
|
-
)
|
623
|
-
yield controller
|
624
|
-
end
|
625
|
-
ensure
|
626
|
-
@controller_streams.each_value(&:close)
|
627
|
-
end
|
628
|
-
@join_threads.each(&:join)
|
629
|
-
wait_thread.value
|
630
|
-
end
|
631
|
-
|
632
|
-
def create_result(status)
|
633
|
-
nonzero_status_handler = @config_opts[:nonzero_status_handler]
|
634
|
-
nonzero_status_handler.call(status) if nonzero_status_handler && status.exitstatus != 0
|
635
|
-
Result.new(@captures[:out], @captures[:err], status)
|
636
|
-
end
|
637
|
-
|
638
703
|
def setup_in_stream
|
639
|
-
setting = @config_opts[:in]
|
640
|
-
if setting.nil?
|
641
|
-
return if $stdin.respond_to?(:fileno) && $stdin.fileno.zero?
|
642
|
-
setting = $stdin
|
643
|
-
end
|
704
|
+
setting = @config_opts[:in] || @default_stream
|
644
705
|
return unless setting
|
645
706
|
case setting
|
646
707
|
when ::Symbol
|
@@ -683,6 +744,8 @@ module Toys
|
|
683
744
|
@controller_streams[:in] = make_in_pipe
|
684
745
|
when :null
|
685
746
|
make_null_stream(:in, "r")
|
747
|
+
when :inherit
|
748
|
+
@spawn_opts[:in] = :in
|
686
749
|
when :close
|
687
750
|
@spawn_opts[:in] = type
|
688
751
|
when :parent
|
@@ -705,12 +768,8 @@ module Toys
|
|
705
768
|
@spawn_opts[:in] = args + [::File::RDONLY]
|
706
769
|
end
|
707
770
|
|
708
|
-
def setup_out_stream(key
|
709
|
-
setting = @config_opts[key]
|
710
|
-
if setting.nil?
|
711
|
-
return if setting.respond_to?(:fileno) && setting.fileno == stdfileno
|
712
|
-
setting = stdstream
|
713
|
-
end
|
771
|
+
def setup_out_stream(key)
|
772
|
+
setting = @config_opts[key] || @default_stream
|
714
773
|
case setting
|
715
774
|
when ::Symbol
|
716
775
|
setup_out_stream_of_type(key, setting, [])
|
@@ -752,6 +811,8 @@ module Toys
|
|
752
811
|
@controller_streams[key] = make_out_pipe(key)
|
753
812
|
when :null
|
754
813
|
make_null_stream(key, "w")
|
814
|
+
when :inherit
|
815
|
+
@spawn_opts[key] = key
|
755
816
|
when :close, :out, :err
|
756
817
|
@spawn_opts[key] = type
|
757
818
|
when :parent
|
data/lib/toys/utils/terminal.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toys-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|