7
7
-- | import Node.ChildProcess (ChildProcess(), CHILD_PROCESS())
8
8
-- | import Node.ChildProcess as ChildProcess
9
9
-- | ```
10
+ -- |
11
+ -- | The [Node.js documentation](https://nodejs.org/api/child_process.html)
12
+ -- | will probably also be useful to read if you want to use this module.
10
13
module Node.ChildProcess
11
14
( Handle ()
12
15
, ChildProcess ()
@@ -28,9 +31,13 @@ module Node.ChildProcess
28
31
, onMessage
29
32
, onError
30
33
, spawn
31
- , fork
32
34
, SpawnOptions ()
33
35
, defaultSpawnOptions
36
+ , exec
37
+ , ExecOptions ()
38
+ , ExecResult ()
39
+ , defaultExecOptions
40
+ , fork
34
41
, StdIOBehaviour (..)
35
42
, pipe
36
43
, inherit
@@ -48,13 +55,15 @@ import Control.Monad.Eff.Exception.Unsafe (unsafeThrow)
48
55
import Data.StrMap (StrMap ())
49
56
import Data.Function (Fn2 (), runFn2 )
50
57
import Data.Nullable (Nullable (), toNullable , toMaybe )
51
- import Data.Maybe (Maybe (..), fromMaybe )
58
+ import Data.Maybe (Maybe (..), fromMaybe , maybe )
52
59
import Data.Foreign (Foreign ())
53
- import Data.Posix (Pid ())
60
+ import Data.Posix (Pid (), Gid (), Uid () )
54
61
import Data.Posix.Signal (Signal ())
55
62
import Data.Posix.Signal as Signal
56
63
import Unsafe.Coerce (unsafeCoerce )
57
64
65
+ import Node.Buffer (Buffer ())
66
+ import Node.Encoding (Encoding ())
58
67
import Node.FS as FS
59
68
import Node.Stream (Readable (), Writable (), Stream ())
60
69
@@ -138,14 +147,6 @@ instance showExit :: Show Exit where
138
147
show (Normally x) = " Normally " <> show x
139
148
show (BySignal sig) = " BySignal " <> show sig
140
149
141
- type SpawnOptions =
142
- { cwd :: Maybe String
143
- , stdio :: Array (Maybe StdIOBehaviour )
144
- , env :: Maybe (StrMap String )
145
- , detached :: Boolean
146
- , uid :: Maybe Int
147
- , gid :: Maybe Int
148
- }
149
150
150
151
mkExit :: Nullable Int -> Nullable String -> Exit
151
152
mkExit code signal =
@@ -201,10 +202,14 @@ foreign import spawnImpl :: forall opts eff. String -> Array String -> { | opts
201
202
-- There's gotta be a better way.
202
203
foreign import undefined :: forall a . a
203
204
204
- -- | A special case of `spawn` for creating Node.js child processes. The first
205
- -- | argument is the module to be run, and the second is the argv (command line
206
- -- | arguments).
207
- foreign import fork :: forall eff . String -> Array String -> Eff (cp :: CHILD_PROCESS | eff ) ChildProcess
205
+ type SpawnOptions =
206
+ { cwd :: Maybe String
207
+ , stdio :: Array (Maybe StdIOBehaviour )
208
+ , env :: Maybe (StrMap String )
209
+ , detached :: Boolean
210
+ , uid :: Maybe Uid
211
+ , gid :: Maybe Gid
212
+ }
208
213
209
214
defaultSpawnOptions :: SpawnOptions
210
215
defaultSpawnOptions =
@@ -216,6 +221,71 @@ defaultSpawnOptions =
216
221
, gid: Nothing
217
222
}
218
223
224
+ -- | Similar to `spawn`, except that this variant will buffer output, and wait
225
+ -- | until the process has exited before calling the callback.
226
+ -- |
227
+ -- | Note that the child process will be killed if the amount of output exceeds
228
+ -- | a certain threshold (the default is defined by Node.js).
229
+ exec :: forall eff .
230
+ String ->
231
+ ExecOptions ->
232
+ (ExecResult -> Eff (cp :: CHILD_PROCESS | eff ) Unit ) ->
233
+ Eff (cp :: CHILD_PROCESS | eff ) Unit
234
+ exec cmd opts callback =
235
+ execImpl cmd (convert opts) \err stdout' stderr' ->
236
+ callback { error: (toMaybe err)
237
+ , stdout: stdout'
238
+ , stderr: stderr'
239
+ }
240
+ where
241
+ convert opts =
242
+ { cwd: fromMaybe undefined opts.cwd
243
+ , env: fromMaybe undefined opts.env
244
+ , timeout: fromMaybe undefined opts.timeout
245
+ , maxBuffer: fromMaybe undefined opts.maxBuffer
246
+ , killSignal: fromMaybe undefined opts.killSignal
247
+ , uid: fromMaybe undefined opts.uid
248
+ , gid: fromMaybe undefined opts.gid
249
+ }
250
+
251
+ foreign import execImpl :: forall eff opts .
252
+ String ->
253
+ { | opts } ->
254
+ (Nullable Exception.Error -> Buffer -> Buffer -> Eff (cp :: CHILD_PROCESS | eff ) Unit ) ->
255
+ Eff (cp :: CHILD_PROCESS | eff ) Unit
256
+
257
+ type ExecOptions =
258
+ { cwd :: Maybe String
259
+ , env :: Maybe (StrMap String )
260
+ , timeout :: Maybe Number
261
+ , maxBuffer :: Maybe Int
262
+ , killSignal :: Maybe Signal
263
+ , uid :: Maybe Uid
264
+ , gid :: Maybe Gid
265
+ }
266
+
267
+ defaultExecOptions :: ExecOptions
268
+ defaultExecOptions =
269
+ { cwd: Nothing
270
+ , env: Nothing
271
+ , timeout: Nothing
272
+ , maxBuffer: Nothing
273
+ , killSignal: Nothing
274
+ , uid: Nothing
275
+ , gid: Nothing
276
+ }
277
+
278
+ type ExecResult =
279
+ { stderr :: Buffer
280
+ , stdout :: Buffer
281
+ , error :: Maybe Exception.Error
282
+ }
283
+
284
+ -- | A special case of `spawn` for creating Node.js child processes. The first
285
+ -- | argument is the module to be run, and the second is the argv (command line
286
+ -- | arguments).
287
+ foreign import fork :: forall eff . String -> Array String -> Eff (cp :: CHILD_PROCESS | eff ) ChildProcess
288
+
219
289
-- | An error which occurred inside a child process.
220
290
type Error =
221
291
{ code :: String
0 commit comments