@garthk/runlikenpm

1.0.0 • Public • Published

runlikenpm

runlikenpm spawns commands much like npm would, but without running npm.

Typical use under gulp:

var gulp = require('gulp');
var run = require('@garthk/runlikenpm');

gulp.task('babel', run('babel -r -s inline src -d dist'));

run with a single argument returns a function that takes a callback; gulp.task calls it. Boom.

Usage

run(command)            # returns function taking callback
run(command)(callback)  # spawns and calls back
run(command, callback)  # spawns and calls back

run will:

  • Throw an assertion error if its arguments are unexpected types;
  • Spawn the command under the guidance of the appropriate shell;
  • Let its output hit your terminal on the fly without buffering until exit;
  • Not modify your process.env or current working directory; and
  • Call back only once.

Why, oh why?

First, I assume we need gulp, having pushed the use of npm as a build tool as far as we could. Seriously, give it a shot. There are limits, but they're further out than you expect.

Still here? Me, too. I wanted:

  • To shell out to commands to keep my gulpfile.js small, vs long pipeline boilerplate; with
  • Behaviour similar to npm run-script; especially
  • The path adjusted so we can run scripts in node_modules/.bin; and
  • Everything still working on Windows; but
  • Without having to shell out through npm to get that.

TL;DR: I couldn't find anything that did both, either amongst:

  • gulp plugins
  • Packages that don't have gulp in their name

Alternative gulp plugins

Yes, we should use packages directly rather than writing yet another gulp plugin destined for the blacklist. That said: sometimes the code to do so gets long enough we're at risk of endless duplication of bad code for which we can't ship bug-fixes.

Anyone else trying to solve the problem of writing clean looking gulpfiles is probably going to ship it with gulp in the name, so that's how I searched. Options I found before giving up due to exhaustion in the face of 1500 plugins:

They all wear the gulp prefix because they're designed to hook up standard input and output to vinyl streams. I don't need that. If you do, submit bug reports for their Windows handling and use whomever gets it right first.

gulp-exec and gulp-spawn don't fix the path (#19 and #11 respectively). gulp-run does, but not always on Windows because it hard-codes the environment variable name as PATH, when it might be Path. gulp-shell has the same problem. None of them set windowsVerbatimArguments so that PATHEXT will work. I lost interest before checking to see whether any of them take comspec into account.

Alternative regular packages

Outside the gulp universe, I found:

  • cross-spawn: very popular, supports shebangs, escapes arguments, has good tests; but you'll need to break up the arguments yourself and deal with the EventEmitter API

  • exec: also popular, but no Windows support, calls back with strings for stdout and stderr instead of letting them write to the TTY

  • Many others along the same lines

Scope Restrictions

  • No streaming. Use the alternatives above if you don't need Windows support.

  • No promises. You can promisify it yourself using your favourite package.

  • No environment variables from your package configuration. I think you're best off spawning npm run in this case. It'll be slower, but why take the risk on a third party re-implementation of that functionality?

Dependencies

I'm taking a dependency on Tim Oxley's npm-path to fix the path.

Caveats

  • I no longer have a Windows box handy on which to test.

  • I'm worried the check for process.env.comspec is hard-coded for lower case. I'll leave it for now, as npm itself seems to share the limitation.

Readme

Keywords

Package Sidebar

Install

npm i @garthk/runlikenpm

Weekly Downloads

1

Version

1.0.0

License

MIT

Last publish

Collaborators

  • garthk