You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Breaking changes to the type definitions of
`process.ChildProcess`; now you need to nilcheck `child.stdout/stdin/stderr` or cast to `process.PipedChild`
Spawns a long-running process in a non-blocking manner, returns a `ChildProcess` that contains handles to the spawned process' stdout, stderr, and stdin.
100
+
101
+
There are three primary usecases for `process.spawn`:
102
+
1. Listening to the output of a long-running process.
103
+
2. Running another program in the background while your program does work.
104
+
3. Launching multiple instances of the same program in parallel.
100
105
101
106
## Usage
102
107
103
-
A long-running program you want to listen to.
108
+
Listen to the output of a long-running process:
104
109
105
110
```luau
106
111
localprocess=require("@std/process")
107
112
localchild=process.spawn({
108
113
program="someutil --watch",
109
114
shell="sh",
110
-
})
115
+
})::process.PipedChild
111
116
112
117
forlineinchild.stdout:lines() do
113
118
localthing_changed=line:match("([%w]+) changed!")
114
119
print(`Change detected: {thing_changed}`)
115
120
end
116
121
```
117
122
118
-
Run multiple processes at the same time to finish faster.
123
+
Run multiple processes at the same time to finish faster:
119
124
120
125
For example, `markdownlint-cli2` takes about 0.3 seconds to fix a file, so if you have 20+ files, and you
121
126
fix each file one-at-a-time with `process.run`, it'll take 6+ seconds to do all files.
@@ -125,14 +130,14 @@ export type process = {
125
130
126
131
```luau
127
132
localpaths: { string } =get_files()
128
-
-- make a threadpool to keep track of what files are finished
Immediately terminate the current program with exit `code`.
157
158
@@ -193,26 +194,97 @@ export type Err = {
193
194
stderr:string,
194
195
}
195
196
197
+
exporttypeStdio="Pipe"|"Inherit"|"Ignore"
198
+
199
+
--[=[
200
+
Options for `process.run`; implicitly added to `process.shell` as well.
201
+
]=]
196
202
exporttypeRunOptions= {
203
+
--- the program you want to run, must be available in $PATH or be an absolute path to an executable
197
204
program:string,
198
205
--- an optional list of arguments to pass into the program; on Windows, you should use this instead of trying to pass whitespace-separated arguments in `program`
199
206
args: { string }?,
200
-
--- specify a shell to run the program with; otherwise runs it as a bare process with no shell
201
-
shell:string?,
207
+
--[=[
208
+
Specify a shell to run `program` with; if unspecified or nil,
209
+
defaults to running it as a bare process with no shell (behavior may differ on Windows vs. Unix-like).
210
+
211
+
If `shell == true`, performs some magic (like checking `$SHELL`) to try and figure out
212
+
what your current shell is, defaulting to WindowsPowerShell on Windows and `sh` on Unix-like.
213
+
214
+
Be careful with shell escapes w/ user-provided values; can be a security risk.
215
+
]=]
216
+
shell: (true|string)?,
202
217
--- path to the the working directory you want your command to execute in, defaults to your shell's cwd
203
218
cwd:string?,
219
+
--[=[
220
+
Control whether the child process reads and writes to its own terminal (`"Pipe"`) or
221
+
to the terminal you're running *seal* in (`"Inherit"`).
222
+
223
+
By default, stdio is *piped*; this means the process reads and writes from separate
224
+
stdin, stdout, and stderr streams that you can read once the process completes.
225
+
226
+
If you want everything the process says to be displayed on your terminal (and not
227
+
read from the process programmatically), use `"Inherit"`.
228
+
229
+
If you want anything the process says to get ignored (redirected to `/dev/null`), use `"Ignore"`.
230
+
231
+
This field `stdio` can be either a string (if you want all streams to share the same behavior)
232
+
or a table (if you want different per-stream behavior).
233
+
]=]
234
+
stdio: {
235
+
stdout:Stdio?,
236
+
stderr:Stdio?,
237
+
stdin:Stdio?,
238
+
}?|Stdio?,
239
+
--[=[
240
+
Override environment variables of the spawned `ChildProcess`.
241
+
By default, the spawned process inherits its environment from the current process;
242
+
so all environment variables visible to *seal* will be visible to it unless removed or cleared.
243
+
244
+
- To clear *all* environment variables for the spawned `ChildProcess` so
245
+
that the spawned process does not inherit from *seal*'s environment, set `env.clear = true`.
246
+
- To add additional environment variables, define a map of them (`{ [string]: string }`)
247
+
in `env.add`.
248
+
- To prevent specific environment variables from being inherited
249
+
by the child process, list them in `env.remove`.
250
+
251
+
The order is clear, add, remove (so clearing the environment doesn't prevent variables from being
252
+
added).
253
+
254
+
## Errors
255
+
256
+
- if you pass a table to `env` without keys `clear`, `add`, and/or `remove`.
257
+
- if `env.add` is present and isn't `{ [string]: string }`
258
+
- if `env.remove` is present and isn't `{ string }`.
259
+
]=]
260
+
env: {
261
+
clear:boolean?,
262
+
add: {
263
+
[string]: string
264
+
}?,
265
+
remove: { string }?,
266
+
}?
204
267
}
205
268
206
269
exporttypeSpawnOptions= {
207
270
--- the program you want to run, must be available in $PATH or be an absolute path to an executable
208
271
program:string,
209
272
--- an optional list of arguments to pass into the program; on Windows, you should use this instead of trying to pass whitespace-separated arguments in `program`
210
273
args: { string }?,
211
-
shell:string?,
274
+
--[=[
275
+
Specify a shell to run `program` with; if unspecified or nil,
276
+
defaults to running it as a bare process with no shell (behavior may differ on Windows vs. Unix-like).
277
+
278
+
If `shell == true`, performs some magic (like checking `$SHELL`) to try and figure out
279
+
what your current shell is, defaulting to WindowsPowerShell on Windows and `sh` on Unix-like.
280
+
281
+
Be careful with shell escapes w/ user-provided values; can be a security risk.
282
+
]=]
283
+
shell: (true|string)?,
212
284
--- path to the the working directory you want your command to execute in, defaults to your shell's cwd
213
285
cwd:string?,
214
286
--[=[
215
-
A `ChildProcessStream` captures incoming bytes from your `ChildProcess`' output streams (either stdout or stderr),
287
+
A `ChildProcessStream` captures incoming bytes from a `ChildProcess`' output stream (either stdout or stderr),
216
288
and caches them in its `inner` buffer. Each stream is spawned in a separate Rust thread to facilitate
217
289
consistently nonblocking, dependable reads, allowing most `ChildProcess.stream:read` methods to be fully nonblocking unless
218
290
specifically requested otherwise.
@@ -243,11 +315,60 @@ export type SpawnOptions = {
243
315
stdout_capacity:number?,
244
316
--- inner buffer capacity of `ChildProcess.stderr`, default 1024
245
317
stderr_capacity:number?,
246
-
--- what side of stdout should be truncated when full? defaults to "front"
247
-
stdout_truncate: ("front"|"back")?,
248
-
--- what side of stderr should be truncated when full? defaults to "front"
249
-
stderr_truncate: ("front"|"back")?,
318
+
--- what side of stdout should be truncated when full? defaults to "Front"
319
+
stdout_truncate: ("Front"|"Back")?,
320
+
--- what side of stderr should be truncated when full? defaults to "Front"
321
+
stderr_truncate: ("Front"|"Back")?,
250
322
}?,
323
+
--[=[
324
+
Control whether the child process reads and writes to its own terminal (`"Pipe"`) or
325
+
to the terminal you're running *seal* in (`"Inherit"`).
326
+
327
+
By default, the child process's stdio is *piped*; this means the process
328
+
reads and writes from separate stdin, stdout, and stderr streams that you
329
+
can access through the `ChildProcessStream` API.
330
+
331
+
If you want everything the process says to be displayed on your terminal (and not
332
+
read from the process programmatically), use `"Inherit"`.
333
+
334
+
If you want anything the `ChildProcess` says to get ignored (redirected to `/dev/null`), use `"Ignore"`.
335
+
336
+
This field `stdio` can be either a string (if you want all streams to share the same behavior)
337
+
or a table (if you want different per-stream behavior).
338
+
]=]
339
+
stdio: {
340
+
stdout:Stdio?,
341
+
stderr:Stdio?,
342
+
stdin:Stdio?,
343
+
}?|Stdio?,
344
+
--[=[
345
+
Override environment variables of the spawned `ChildProcess`.
346
+
By default, the spawned process inherits its environment from the current process;
347
+
so all environment variables visible to *seal* will be visible to it unless removed or cleared.
348
+
349
+
- To clear *all* environment variables for the spawned `ChildProcess` so
350
+
that the spawned process does not inherit from *seal*'s environment, set `env.clear = true`.
351
+
- To add additional environment variables, define a map of them (`{ [string]: string }`)
352
+
in `env.add`.
353
+
- To prevent specific environment variables from being inherited
354
+
by the child process, list them in `env.remove`.
355
+
356
+
The order is clear, add, remove (so clearing the environment doesn't prevent variables from being
357
+
added).
358
+
359
+
## Errors
360
+
361
+
- if you pass a table to `env` without keys `clear`, `add`, and/or `remove`.
362
+
- if `env.add` is present and isn't `{ [string]: string }`
363
+
- if `env.remove` is present and isn't `{ string }`.
364
+
]=]
365
+
env: {
366
+
clear:boolean?,
367
+
add: {
368
+
[string]: string
369
+
}?,
370
+
remove: { string }?,
371
+
}?
251
372
}
252
373
--- Represents the stdout and stderr streams of a `ChildProcess`, both ran in parallel threads
253
374
--- and streamed for nonblocking behavior.
@@ -433,7 +554,7 @@ export type ChildProcessStream = setmetatable<{
433
554
localchild=process.spawn({
434
555
program="someutil --watch",
435
556
shell="sh",
436
-
})
557
+
})::process.PipedChild
437
558
438
559
forlineinchild.stdout:lines() do
439
560
localthing_changed=line:match("([%w]+) changed!")
@@ -450,9 +571,11 @@ export type ChildProcessStream = setmetatable<{
0 commit comments