Skip to content

Where is the documentation?

Guilherme Vieira edited this page Dec 10, 2017 · 13 revisions

require("blastoise-shell")

Returns a single BlastoiseShell: The root shell.

The root shell is a null shell (i.e. its command is null), but it can be piped from to create new shells. The only way to create new shells is to pipe from the root shell.

All operations are fully asynchronous. Where the documentation says "return," it means the returned promise is resolved to a value. Where it says "throw," it means the returned promise is rejected with an error.

#noThrow

Returns a new instance of BlastoiseShell, piping from this instance.

The new instance has throw behavior disabled. No errors are thrown if there's an error executing a command, if a subprocess exits with a non-zero exit code, if a subprocess is terminated by a signal, or if there's a pipe error.

Instead, the shell returns the error code (e.g.: EACCES), the non-zero subprocess exit code (e.g. 255), or the termination signal name (e.g. SIGTERM).

throw behavior is inheritted by piping.

throw behavior is enabled by default on the root shell.

Example:

// Returns "ENOENT".
await sh.noThrow.missingCommand();

#throw

Returns a new instance of BlastoiseShell, piping from this instance.

The new instance has throw behavior enabled. Errors will be thrown if there's an error executing a command, if a subprocess exits with a non-zero exit code, if a subprocess is terminated by a signal, or if there's a pipe error.

throw behavior is inheritted by piping.

throw behavior is enabled by default on the root shell.

It only makes sense to call #throw on shells that have throw behavior disabled (usually due to piping from another shell with throw behavior disabled).

Example:

// Returns "ENOENT" due to missing command after throw
// property.
await sh.noThrow.echo('hello').throw.missingCommand();

#someCommandName(...args)

Syntatic sugar for #exec(someCommandName, ...args).

Example:

let { echo } = sh;
await echo(`Hello, world.`).sed('s/Hello/Hi/');

#exec(cmd, ...args)

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Returns a new instance of BlastoiseShell, piping from this instance. The new instance will run cmd with args arguments when it's started.

cmd must be a command available from the PATH environment variable directory list (e.g.: cat), or a relative path from the script's current working directory to an executable file (e.g. ./my-script.sh).

args are expanded according to the following rules:

  • for (let arg of args):
    • If arg is NOT an object, do not expand it (leaves it as-is).
    • for (let [opt, val] of Object.entries(arg)):
      • If val === false, remove arg (arg is elided).
      • If opt is 1 character long, prefix it with a dash (e.g.: f => -f).
      • Otherwise, prefix it with two dashes (e.g.: force => --force).
      • If val === true, expand ${opt} (including prefixes above).
      • If val is an array, for (let v of val):
        • Expand ${opt} ${v} (e.g.: { n: [1, 2, 3] } => -n 1 -n 2 -n 3).
      • Otherwise, expand ${opt} ${val} (e.g.: { depth: 5 } => --depth 5).

Each individual item in args after expansion will be passed exactly to the subprocess as an individual argument.

The subprocess is NOT immediately started. They are lazily started only when #then or #catch is called.

Examples:

// echo "Hello, world."
await sh.echo(`Hello, world.`);

// rm -rf example
await sh.rm('-rf', 'example');

// git add -p
await sh.git('add', { p: true });

// git add
await sh.git('add', { p: false });

// git diff --cached
await sh.git('diff', { cached: true });

// git diff
await sh.git('diff', { cached: false });

// git push --dry-run --set-upstream
await sh.git('push', {
  'dry-run': true,
  'set-upstream': true,
});

// curl localhost:3000 \
//   --header 'Content-Type: text/plain' \
//   --header 'Accept: text/html'
await sh.curl('localhost:3000', {
  header: [
    'Content-Type: text/plain',
    'Accept: text/html',
  ],
});

#pipeTo(dest, ...args)

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Pipes this shell instance's subprocess' standard output to dest, where dest is a string, a function, or another BlastoiseShell.

If dest is a string, this function is equivalent to #exec(dest, ...args).

If dest is a function, this function calls dest(this, ...args), returning its return value.

If dest is a BlastoiseShell, this function is equivalent to #pipeToShell(dest, ...args).

#pipeToShell(shell)

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior. Also throws an error if shell's subprocess is already started.

Pipes this shell instance's subprocess' standard output to another BlastoiseShell.

#map(fn)

Pipes each line of this shell instance's subprocess' standard output to a function fn. The function is invoked once for each line, together with the corresponding line index.

Returns a new BlastoiseShell whose standard output contains the mapped lines. Lines mapped to null or undefined` are omitted.

Example:

// Output:
// 0: Hello
// 1: World
await sh.echo(`Hello\nWorld`).map(
  (ln, i) => `${i}: ${ln}`
);

#forEach(fn)

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Pipes each line of this shell instance's subprocess' standard output to a function fn. The function is invoked once for each line together with the corresponding line index.

Returns when all lines have been processed by fn. Lines are considered processed once all fn invocations are finished, including async invocations.

May fail with errors: EPIPE, etc.

May also fail in case of errors in piped from shells.

If throw behavior is enabled, errors are thrown. Otherwise, error codes are returned.

Example:

// Output:
// 0: Hello
// 1: World
await sh.echo(`Hello\nWorld`).forEach(
  (ln, i) => console.log(`${i}: ${ln}`)
);

#appendTo(path)

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Pipes this shell instance's subprocess' standard output to the file located under path. The file is appended to, not overwritten.

Returns once all contents have been written to the file.

May fail with errors: EACCES, EISDIR, etc.

May also fail in case of errors in piped from shells.

If throw behavior is enabled, errors are thrown. Otherwise, error codes are returned.

Example:

// echo "Hello, world." >> example
await sh.echo(`Hello, world.`).appendTo('example');

#writeTo(path)

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Pipes this shell instance's subprocess' standard output to the file located under path. The file is truncated and overwritten.

Returns once all contents have been written to the file.

May fail with errors: EACCES, EISDIR, etc.

May also fail in case of errors in piped from shells.

If throw behavior is enabled, errors are thrown. Otherwise, error codes are returned.

Example:

// echo "Hello, world." > example
await sh.echo(`Hello, world.`).writeTo('example');

#toString()

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Pipes this shell instance's subprocess' standard output to a string, and returns the string.

May fail with errors: EPIPE, etc.

May also fail in case of errors in piped from shells.

If throw behavior is enabled, errors are thrown. Otherwise, error codes are returned.

Example:

// Output:
// Hello, world.
let hi = await sh.echo(`Hello, world.`).toString();
console.log(hi);

#lines

Note: Throws an error if this shell instance's subprocess is already started, regardless of throw behavior.

Pipes each line of this shell instance's subprocess' standard output to an array of lines, and returns the array.

May fail with errors: EPIPE, etc.

May also fail in case of errors in piped from shells.

If throw behavior is enabled, errors are thrown. Otherwise, error codes are returned.

Example:

// Output:
// [ 'Hello', 'World' ]
let lns = await sh.echo(`Hello\nWorld`).lines;
console.log(lns);

#err

Returns a new BlastoiseShell, piping from this instance's standard error stream.

Examples:

// some-command 2> errors
await sh.exec('some-command').err.writeTo('errors');

// Pipe some-command's stderr ONLY to another-command
// (really hard to do with Bash).
await sh.exec('some-command').err.exec('another-command');

#withErr

Returns a new BlastoiseShell, piping from this instance's standard output and standard error streams.

Example:

// some-command 2>&1 > logs
await sh.exec('some-command').withErr.writeTo('logs');

#then(successCallback, errorCallback)

Starts all piped subprocesses and calls successCallback with this instance's subprocess' exit code.

May fail if the exit code is non-zero or if the subprocess is terminated by a signal.

May also fail in case of errors in piped from shells.

If throw behavior is enabled, non-zero exit codes and errors are passed to errorCallback. Otherwise, they're passed to successCallback.

Example:

// echo "Hello, world."
// (await calls #then).
await sh.echo(`Hello, world.`);

#catch(callback)

Starts all piped subprocesses and calls callback in case of errors: non-zero exit codes, error codes, or termination signals.

May also call callback in case of errors in piped from shells.

If throw behavior is disabled, this function never calls callback.

Example:

sh.exec('randomly-crashing-command')
  .then(() => console.log(`OK!`))
  .catch(console.error);