Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Overhaul child_process #47

Merged
merged 1 commit into from
Sep 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The following core Node.js modules (v8.7.0+) have been implemented:
| ------------------------------------------------------------ | ------------------ |
| [assert](https://nodejs.org/api/assert.html) | |
| [buffer](https://nodejs.org/api/buffer.html) | :heavy_check_mark: |
| [child_process](https://nodejs.org/api/child_process.html) | |
| [child_process](https://nodejs.org/api/child_process.html) | :heavy_check_mark: |
| [cluster](https://nodejs.org/api/cluster.html) | |
| [console](https://nodejs.org/api/console.html) | :heavy_check_mark: |
| [crypto](https://nodejs.org/api/crypto.html) | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,21 @@ import scala.scalajs.js.|
*/
@js.native
trait ChildProcess extends IEventEmitter {
def kill(signal: js.UndefOr[Int | String] = js.native): Unit = js.native
def kill(signal: js.UndefOr[KillSignal] = js.native): Unit = js.native
def ref(): Unit = js.native
def unref(): Unit = js.native
// TODO: Are those available in limited scenario?
//def disconnect(): Unit = js.native
//def send(message: js.Any, sendHandle: Handle = js.native, options: SendOptions | RawOptions = js.native, callback: js.Function1[nodejs.Error, Any] = js.native): Boolean = js.native

val channel: js.UndefOr[js.Object] = js.native
val connected: Boolean = js.native
val killed: Boolean = js.native
val pid: Int = js.native
val stderr: stream.Readable = js.native
val stdin: stream.Writable = js.native
val stdio: js.Array[IEventEmitter] = js.native
val stdout: stream.Readable = js.native
}

/**
Expand All @@ -26,8 +40,20 @@ trait ChildProcess extends IEventEmitter {
@js.native
object ChildProcess extends scala.scalajs.js.Object {
def exec(
command: String,
options: js.UndefOr[ExecOptions | io.scalajs.RawOptions] = js.undefined,
args: String,
options: ExecOptions | io.scalajs.RawOptions = js.native,
callback: js.Function3[
nodejs.Error,
Output,
Output,
Any
]
): ChildProcess = js.native

def execFile(
file: String,
args: js.Array[String] = js.native,
options: ExecOptions | io.scalajs.RawOptions = js.native,
callback: js.Function3[
nodejs.Error,
Output,
Expand All @@ -41,6 +67,12 @@ object ChildProcess extends scala.scalajs.js.Object {
options: ExecOptions | io.scalajs.RawOptions = js.native
): Output = js.native

def execFileSync(
file: String,
args: js.Array[String] = js.native,
options: ExecFileSyncOptions | io.scalajs.RawOptions = js.native
): Output = js.native

def fork(
modulePath: String,
args: js.Array[String] = js.native,
Expand All @@ -56,11 +88,7 @@ object ChildProcess extends scala.scalajs.js.Object {
def spawnSync(
command: String,
args: js.Array[String] = js.native,
options: SpawnOptions | io.scalajs.RawOptions = js.native
): SpawnResult = js.native
options: SpawnSyncOptions | io.scalajs.RawOptions = js.native
): SpawnSyncResult = js.native

def spawnSync(
command: String,
options: SpawnOptions | io.scalajs.RawOptions
): SpawnResult = js.native
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.scalajs.nodejs.child_process

import io.scalajs.JsNumber

import scala.scalajs.js
import scala.scalajs.js.|

/**
* Spawns a shell then executes the command within that shell, buffering any generated output.
*
* Note: Never pass unsanitized user input to this function. Any input containing shell meta-characters
* may be used to trigger arbitrary command execution.
*
* @param cwd Current working directory of the child process
* @param input The value which will be passed as stdin to the spawned process.
* Supplying this value will override stdio[0].
* @param stdio Child's stdio configuration. stderr by default will be output to the parent process' stderr unless stdio is specified.
* Default: 'pipe'.
* @param env Environment key-value pairs
* @param encoding (Default: 'utf8')
* @param shell Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows,
* The shell should understand the -c switch on UNIX or /d /s /c on Windows. On Windows, command line
* parsing should be compatible with cmd.exe.)
* @param timeout (Default: 0)
* @param maxBuffer largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process
* is killed (Default: 200*1024)
* @param killSignal (Default: 'SIGTERM')
* @param uid Sets the user identity of the process. (See setuid(2).)
* @param gid Sets the group identity of the process. (See setgid(2).)
* @param windowsHide Hide the subprocess console window that would normally be created on Windows systems. Default: `false`.
*/
class ExecFileSyncOptions(val cwd: js.UndefOr[String] = js.undefined,
val input: js.UndefOr[Input],
val stdio: js.UndefOr[StdIo] = js.undefined,
val env: js.UndefOr[js.Object] = js.undefined,
val encoding: js.UndefOr[String] = js.undefined,
val shell: js.UndefOr[Boolean | String] = js.undefined,
val timeout: js.UndefOr[JsNumber] = js.undefined,
val maxBuffer: js.UndefOr[JsNumber] = js.undefined,
val killSignal: js.UndefOr[KillSignal] = js.undefined,
val uid: js.UndefOr[JsNumber] = js.undefined,
val gid: js.UndefOr[JsNumber] = js.undefined,
val windowsHide: js.UndefOr[Boolean] = js.undefined)
extends js.Object
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,38 @@ package child_process
import io.scalajs.JsNumber

import scala.scalajs.js
import scala.scalajs.js.|

/**
* Spawns a shell then executes the command within that shell, buffering any generated output.
*
* Note: Never pass unsanitized user input to this function. Any input containing shell meta-characters
* may be used to trigger arbitrary command execution.
* @param cwd <String> Current working directory of the child process
* @param env <Object> Environment key-value pairs
* @param encoding <String> (Default: 'utf8')
* @param shell <String> Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows,
* @param cwd Current working directory of the child process
* @param env Environment key-value pairs
* @param encoding (Default: 'utf8')
* @param shell Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows,
* The shell should understand the -c switch on UNIX or /d /s /c on Windows. On Windows, command line
* parsing should be compatible with cmd.exe.)
* @param timeout <Number> (Default: 0)
* @param maxBuffer <Number> largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process
* @param timeout (Default: 0)
* @param maxBuffer largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process
* is killed (Default: 200*1024)
* @param killSignal <String> (Default: 'SIGTERM')
* @param uid <Number> Sets the user identity of the process. (See setuid(2).)
* @param gid <Number> Sets the group identity of the process. (See setgid(2).)
* @param killSignal (Default: 'SIGTERM')
* @param uid Sets the user identity of the process. (See setuid(2).)
* @param gid Sets the group identity of the process. (See setgid(2).)
* @param windowsHide Hide the subprocess console window that would normally be created on Windows systems. Default: `false`.
* @param windowsVerbatimArguments No quoting or escaping of arguments is done on Windows.
* Ignored on Unix. This is set to true automatically when shell is specified and is CMD. Default: false.
*/
class ExecOptions(val cwd: js.UndefOr[String] = js.undefined,
val env: js.Any = js.undefined,
val env: js.UndefOr[js.Object] = js.undefined,
val encoding: js.UndefOr[String] = js.undefined,
val shell: js.UndefOr[String] = js.undefined,
val shell: js.UndefOr[Boolean | String] = js.undefined,
val timeout: js.UndefOr[JsNumber] = js.undefined,
val maxBuffer: js.UndefOr[JsNumber] = js.undefined,
val killSignal: js.UndefOr[String] = js.undefined,
val killSignal: js.UndefOr[KillSignal] = js.undefined,
val uid: js.UndefOr[JsNumber] = js.undefined,
val gid: js.UndefOr[JsNumber] = js.undefined)
val gid: js.UndefOr[JsNumber] = js.undefined,
val windowsHide: js.UndefOr[Boolean] = js.undefined,
val windowsVerbatimArguments: js.UndefOr[Boolean] = js.undefined)
extends js.Object
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,32 @@ package child_process
import io.scalajs.JsNumber

import scala.scalajs.js
import scala.scalajs.js.|

/**
* Fork Options
* @param cwd <String> Current working directory of the child process
* @param env <Object> Environment key-value pairs
* @param execPath <String> Executable used to create the child process
* @param execArgv <Array> List of string arguments passed to the executable (Default: process.execArgv)
* @param silent <Boolean> If true, stdin, stdout, and stderr of the child will be piped to the parent,
* @param cwd Current working directory of the child process
* @param detached Prepare child to run independently of its parent process
* Specific behavior depends on the platform (see options.detached).
* @param env Environment key-value pairs
* @param execPath Executable used to create the child process
* @param execArgv List of string arguments passed to the executable (Default: process.execArgv)
* @param silent If true, stdin, stdout, and stderr of the child will be piped to the parent,
* otherwise they will be inherited from the parent, see the 'pipe' and 'inherit' options
* for child_process.spawn()'s stdio for more details (Default: false)
* @param stdio <Array> Supports the array version of child_process.spawn()'s stdio option. When this
* @param stdio Supports the array version of child_process.spawn()'s stdio option. When this
* option is provided, it overrides silent. The array must contain exactly one item with
* value 'ipc' or an error will be thrown. For instance [0, 1, 2, 'ipc'].
* @param uid <Number> Sets the user identity of the process. (See setuid(2).)
* @param gid <Number> Sets the group identity of the process. (See setgid(2).)
* @param uid Sets the user identity of the process. (See setuid(2).)
* @param gid Sets the group identity of the process. (See setgid(2).)
*/
class ForkOptions(val cwd: js.UndefOr[String] = js.undefined,
val env: js.Any = js.undefined,
val detached: js.UndefOr[Boolean] = js.undefined,
val env: js.UndefOr[js.Object] = js.undefined,
val execPath: js.UndefOr[String] = js.undefined,
val execArgv: js.UndefOr[Array[String]] = js.undefined,
val silent: js.UndefOr[Boolean] = js.undefined,
val stdio: js.UndefOr[Array[String]] = js.undefined,
val stdio: js.UndefOr[String | Array[String]] = js.undefined,
val uid: js.UndefOr[JsNumber] = js.undefined,
val gid: js.UndefOr[JsNumber] = js.undefined)
extends js.Object
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.scalajs.nodejs.child_process

import scala.scalajs.js

class SendOptions(
val keepOpen: js.UndefOr[Boolean] = js.undefined
) extends js.Object {}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ import scala.scalajs.js.|
/**
* Spawn Options
*
* @param cwd <String> Current working directory of the child process
* @param env <Object> Environment key-value pairs
* @param argv0 <String> Explicitly set the value of argv[0] sent to the child process.
* @param cwd Current working directory of the child process
* @param env Environment key-value pairs
* @param argv0 Explicitly set the value of argv[0] sent to the child process.
* This will be set to command if not specified.
* @param stdio <Array> | <String> Child's stdio configuration. (See options.stdio)
* @param detached <Boolean> Prepare child to run independently of its parent process.
* @param stdio Child's stdio configuration. (See options.stdio)
* @param detached Prepare child to run independently of its parent process.
* Specific behavior depends on the platform, see options.detached)
* @param uid <Number> Sets the user identity of the process. (See setuid(2).)
* @param gid <Number> Sets the group identity of the process. (See setgid(2).)
* @param shell <Boolean> | <String> If true, runs command inside of a shell.
* @param uid Sets the user identity of the process. (See setuid(2).)
* @param gid Sets the group identity of the process. (See setgid(2).)
* @param shell If true, runs command inside of a shell.
* Uses '/bin/sh' on UNIX, and 'cmd.exe' on Windows. A different shell can be specified as a string.
* The shell should understand the -c switch on UNIX, or /d /s /c on Windows. Defaults to false (no shell).
*/
class SpawnOptions(
val cwd: js.UndefOr[String] = js.undefined,
val env: js.Any = js.undefined,
val argv0: js.UndefOr[String] = js.undefined,
val stdio: js.UndefOr[js.Array[String | io.scalajs.nodejs.FileDescriptor] | js.Array[
io.scalajs.nodejs.FileDescriptor
] | js.Array[String] | String] = js.undefined,
val stdio: js.UndefOr[StdIo] = js.undefined,
val detached: js.UndefOr[Boolean] = js.undefined,
val uid: js.UndefOr[Int] = js.undefined,
val gid: js.UndefOr[Int] = js.undefined,
val shell: js.UndefOr[Boolean | String] = js.undefined
val shell: js.UndefOr[Boolean | String] = js.undefined,
val windowsVerbatimArguments: js.UndefOr[Boolean] = js.undefined,
val windowsHide: js.UndefOr[Boolean] = js.undefined
) extends js.Object
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.scalajs.nodejs.child_process

import io.scalajs.JsNumber

import scala.scalajs.js
import scala.scalajs.js.|

/**
* Spawns a shell then executes the command within that shell, buffering any generated output.
*
* Note: Never pass unsanitized user input to this function. Any input containing shell meta-characters
* may be used to trigger arbitrary command execution.
*
* @param cwd Current working directory of the child process
* @param input The value which will be passed as stdin to the spawned process.
* Supplying this value will override stdio[0].
* @param argv0 Explicitly set the value of argv[0] sent to the child process.
* This will be set to command if not specified.
* @param stdio Child's stdio configuration. stderr by default will be output to the parent process' stderr unless stdio is specified.
* Default: 'pipe'.
* @param env Environment key-value pairs
* @param encoding (Default: 'utf8')
* @param shell Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows,
* The shell should understand the -c switch on UNIX or /d /s /c on Windows. On Windows, command line
* parsing should be compatible with cmd.exe.)
* @param timeout (Default: 0)
* @param maxBuffer largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process
* is killed (Default: 200*1024)
* @param killSignal (Default: 'SIGTERM')
* @param uid Sets the user identity of the process. (See setuid(2).)
* @param gid Sets the group identity of the process. (See setgid(2).)
* @param windowsHide Hide the subprocess console window that would normally be created on Windows systems. Default: `false`.
* @param windowsVerbatimArguments No quoting or escaping of arguments is done on Windows.
* Ignored on Unix. This is set to true automatically when shell is specified and is CMD. Default: false.
*/
class SpawnSyncOptions(val cwd: js.UndefOr[String] = js.undefined,
val input: js.UndefOr[Input] = js.undefined,
val argv0: js.UndefOr[String] = js.undefined,
val stdio: js.UndefOr[StdIo] = js.undefined,
val env: js.UndefOr[js.Object] = js.undefined,
val encoding: js.UndefOr[String] = js.undefined,
val shell: js.UndefOr[Boolean | String] = js.undefined,
val timeout: js.UndefOr[JsNumber] = js.undefined,
val maxBuffer: js.UndefOr[JsNumber] = js.undefined,
val killSignal: js.UndefOr[KillSignal] = js.undefined,
val uid: js.UndefOr[JsNumber] = js.undefined,
val gid: js.UndefOr[JsNumber] = js.undefined,
val windowsHide: js.UndefOr[Boolean] = js.undefined,
val windowsVerbatimArguments: js.UndefOr[Boolean] = js.undefined)
extends js.Object
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package io.scalajs.nodejs.child_process

import scala.scalajs.js
import scala.scalajs.js.|

class SpawnResult(
class SpawnSyncResult(
val pid: Int,
val output: js.Array[Output],
val stdout: Output,
val stderr: Output,
val status: js.UndefOr[Int],
val signal: js.UndefOr[String],
val status: Int | Null,
val signal: String | Null,
val error: js.UndefOr[js.Error]
) extends js.Object
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,35 @@ import io.scalajs.util.PromiseHelper._

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.typedarray.{DataView, TypedArray}
import scala.scalajs.js.|

package object child_process {
type Output = nodejs.buffer.Buffer | String
type Input = String | nodejs.buffer.Buffer | TypedArray[_, _] | DataView
type StdIo = String | js.Array[String] | js.Array[io.scalajs.nodejs.FileDescriptor] | js.Array[
String | io.scalajs.nodejs.FileDescriptor
]
type KillSignal = Int | String

implicit final class ChildProcessExtensions(val cp: ChildProcess.type) extends AnyVal {
implicit final class ChildProcessExtensions(private val cp: ChildProcess.type) extends AnyVal {
@inline
def execFuture(
command: String,
options: js.UndefOr[ExecOptions | io.scalajs.RawOptions] = js.undefined
): Future[(Output, Output)] = {
promiseWithError2[nodejs.Error, Output, Output](cp.exec(command, options, _))
promiseWithError2[nodejs.Error, Output, Output](cp.exec(command, options.orNull, _))
}
}

@inline
def execFileFuture(
file: String,
args: js.UndefOr[js.Array[String]] = js.undefined,
options: js.UndefOr[ExecOptions | io.scalajs.RawOptions] = js.undefined
): Future[(Output, Output)] = {
promiseWithError2[nodejs.Error, Output, Output](cp.execFile(file, args.orNull, options.orNull, _))
}

// TODO: spawn, fork
}
}
Loading