From 4d579a18617511468df8dc434890fa81fadfaa85 Mon Sep 17 00:00:00 2001 From: Benjamin Coe Date: Fri, 15 May 2015 08:34:39 -0700 Subject: [PATCH 1/3] things are actually starting to work --- .gitignore | 1 + .npmignore | 2 - README.md | 50 ++- bin/nyc-report.js | 2 +- bin/nyc.js | 48 ++- index.js | 33 +- node_modules/spawn-wrap/README.md | 28 +- node_modules/spawn-wrap/index.js | 308 ++++++++++++------ .../spawn-wrap/node_modules/.bin/which | 1 - .../spawn-wrap/node_modules/which/LICENSE | 15 - .../spawn-wrap/node_modules/which/README.md | 34 -- .../spawn-wrap/node_modules/which/bin/which | 13 - .../which/node_modules/is-absolute/LICENSE | 21 -- .../which/node_modules/is-absolute/README.md | 53 --- .../which/node_modules/is-absolute/index.js | 27 -- .../node_modules/is-relative/LICENSE-MIT | 21 -- .../node_modules/is-relative/README.md | 38 --- .../node_modules/is-relative/index.js | 21 -- .../node_modules/is-relative/package.json | 75 ----- .../node_modules/is-absolute/package.json | 75 ----- .../node_modules/which/package.json | 56 ---- .../node_modules/which/test/basic.js | 84 ----- .../spawn-wrap/node_modules/which/which.js | 137 -------- node_modules/spawn-wrap/package.json | 21 +- node_modules/spawn-wrap/scripts/argv.js | 3 - node_modules/spawn-wrap/t.js | 20 +- node_modules/spawn-wrap/wrap-main.js | 37 --- package.json | 17 +- test/fixtures/sighup.js | 1 - test/fixtures/sigint.js | 2 + test/fixtures/sigterm.js | 2 + test/nyc-test.js | 51 ++- 32 files changed, 384 insertions(+), 913 deletions(-) delete mode 100644 .npmignore delete mode 120000 node_modules/spawn-wrap/node_modules/.bin/which delete mode 100644 node_modules/spawn-wrap/node_modules/which/LICENSE delete mode 100644 node_modules/spawn-wrap/node_modules/which/README.md delete mode 100755 node_modules/spawn-wrap/node_modules/which/bin/which delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/LICENSE delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/README.md delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/index.js delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/LICENSE-MIT delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/README.md delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/index.js delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/package.json delete mode 100644 node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/package.json delete mode 100644 node_modules/spawn-wrap/node_modules/which/package.json delete mode 100644 node_modules/spawn-wrap/node_modules/which/test/basic.js delete mode 100644 node_modules/spawn-wrap/node_modules/which/which.js delete mode 100755 node_modules/spawn-wrap/scripts/argv.js mode change 100644 => 100755 node_modules/spawn-wrap/t.js delete mode 100644 node_modules/spawn-wrap/wrap-main.js delete mode 100644 test/fixtures/sighup.js mode change 100644 => 100755 test/fixtures/sigint.js mode change 100644 => 100755 test/fixtures/sigterm.js diff --git a/.gitignore b/.gitignore index 172a3374c..91fc9125e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ nyc_output coverage +node_modules diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 172a3374c..000000000 --- a/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -nyc_output -coverage diff --git a/README.md b/README.md index a7ac459e1..8c41b51a0 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,53 @@ [![Coverage Status](https://coveralls.io/repos/bcoe/nyc/badge.svg?branch=)](https://coveralls.io/r/bcoe/nyc?branch=) [![NPM version](https://img.shields.io/npm/v/nyc.svg)](https://www.npmjs.com/package/nyc) -a code coverage reporter built on [istanbul](https://www.npmjs.com/package/istanbul) +a code coverage tool built on [istanbul](https://www.npmjs.com/package/istanbul) that works well for applications that spawn child processes. + +## Usage + +Run your tests with the test coverage collector: + +```json +{ + "script": { + "test": "nyc tap ./test/*.js", + } +} +``` + +Now run the reporter afterwords to view your coverage statistics: + +```bash +nyc-report + +--------------------|-----------|-----------|-----------|-----------| +File | % Stmts |% Branches | % Funcs | % Lines | +--------------------|-----------|-----------|-----------|-----------| + ./ | 85.96 | 50 | 75 | 92.31 | + index.js | 85.96 | 50 | 75 | 92.31 | + ./test/ | 98.08 | 50 | 95 | 98.04 | + nyc-test.js | 98.08 | 50 | 95 | 98.04 | + ./test/fixtures/ | 100 | 100 | 100 | 100 | + sigint.js | 100 | 100 | 100 | 100 | + sigterm.js | 100 | 100 | 100 | 100 | +--------------------|-----------|-----------|-----------|-----------| +All files | 91.89 | 50 | 86.11 | 95.24 | +--------------------|-----------|-----------|-----------|-----------| +``` + +or use any reporter supported by istanbul: + +```bash +nyc-report --reporter=lcov +``` + +or, toss a script in your package.json: + +```bash +{ + "script": { + "test": "nyc-report --reporter=text-lcov | coveralls", + } +} +``` diff --git a/bin/nyc-report.js b/bin/nyc-report.js index 0965c71d4..df8805615 100755 --- a/bin/nyc-report.js +++ b/bin/nyc-report.js @@ -14,7 +14,7 @@ var NYC = require('../'), }) .help('h') .alias('h', 'help') - .epilog('github.com/gotwarlost/istanbul for available reporters') + .epilog('http://github.com/gotwarlost/istanbul for available reporters') .argv process.env.NYC_CWD = argv['cwd'] diff --git a/bin/nyc.js b/bin/nyc.js index a185d4fd8..0db06969a 100755 --- a/bin/nyc.js +++ b/bin/nyc.js @@ -1,25 +1,37 @@ #!/usr/bin/env node +var sw = require('spawn-wrap') -var NYC = require('../'), - yargs = require('yargs') - .usage('$0 [file-to-instrument]') - .example('$0 ./node_modules/.bin/mocha', 'run mocha test-suite and output JSON files with coverage information') +if (process.env.NYC_CWD) { + var NYC = require('../') + ;(new NYC()).wrap() -;(new NYC()).wrap() + // make sure we can run coverage on + // our own index.js, I like turtles. + var name = require.resolve('../') + delete require.cache[name] -// make it so we can run coverage on nyc itself. -var name = require.resolve('../') -delete require.cache[name] + sw.runMain() +} else { + var NYC = require('../') -// hide the fact that nyc.js was used to execute command. -if (process.argv[1].match((/(nyc.js$)|(nyc$)/))) process.argv.splice(1, 1) + ;(new NYC()).cleanup() -// execute main on whatever file was wrapped by nyc. -// ./bin/nyc.js ./node_modules/.bin/mocha -if (process.argv[1]) { - delete require('module')._cache[process.argv[1]] - process.argv[1] = require('path').resolve(process.argv[1]) - require('module').runMain() -} else { - yargs.showHelp() + sw([__filename], { + NYC_CWD: process.cwd() + }) + + // this spawn gets wrapped + var child = require('child_process').spawn( + process.argv[2], + process.argv.slice(3), + { stdio: 'inherit' } + ) + + child.on('close', function (code, signal) { + if (signal) { + process.kill(process.pid, signal) + } else { + process.exit(code) + } + }) } diff --git a/index.js b/index.js index 8b7dc1b01..0e6444ba1 100755 --- a/index.js +++ b/index.js @@ -1,3 +1,5 @@ +/* global __coverage__ */ + var _ = require('lodash'), fs = require('fs'), istanbul = require('istanbul'), @@ -5,7 +7,6 @@ var _ = require('lodash'), mkdirp = require('mkdirp'), path = require('path'), rimraf = require('rimraf'), - spawnWrap = require('spawn-wrap'), stripBom = require('strip-bom') function NYC (opts) { @@ -28,10 +29,13 @@ function NYC (opts) { return new RegExp(p) }) - if (!process.env.NYC_CWD) rimraf.sync(this.tmpDirectory()) mkdirp.sync(this.tmpDirectory()) } +NYC.prototype.cleanup = function () { + if (!process.env.NYC_CWD) rimraf.sync(this.tmpDirectory()) +} + NYC.prototype._wrapRequire = function () { var _this = this @@ -59,27 +63,30 @@ NYC.prototype._wrapRequire = function () { NYC.prototype._wrapExit = function () { var _this = this, - outputCoverage = function (arg) { - if (!global.__coverage__) return + outputCoverage = function () { + var coverage + if (typeof __coverage__ === 'object') coverage = __coverage__ + if (!coverage) return fs.writeFileSync( path.resolve(_this.tmpDirectory(), './', process.pid + '.json'), - JSON.stringify(global.__coverage__), + JSON.stringify(coverage), 'utf-8' ) } - // output temp coverage reports as processes exit. - ;['exit', 'SIGTERM', 'SIGINT', 'SIGHUP'].forEach(function (signal) { - process.on(signal, function () { - outputCoverage() - if (signal === 'SIGTERM') process.exit(143) - }) + var _kill = process.kill + process.kill = function (pid, signal) { + outputCoverage() + _kill(pid, signal) + } + + process.on('exit', function () { + outputCoverage() }) } -NYC.prototype.wrap = function () { - spawnWrap([this.subprocessBin], {NYC_CWD: this.cwd}) +NYC.prototype.wrap = function (bin) { this._wrapRequire() this._wrapExit() return this diff --git a/node_modules/spawn-wrap/README.md b/node_modules/spawn-wrap/README.md index e0d744e85..a6ca493fd 100644 --- a/node_modules/spawn-wrap/README.md +++ b/node_modules/spawn-wrap/README.md @@ -30,13 +30,33 @@ In this example, the `/path/to/my/main.js` file will be used as the whether via a call to `spawn` or `exec`, whether node is invoked directly as the command or as the result of a shebang `#!` lookup. +In `/path/to/my/main.js`, you can do whatever instrumentation or +environment manipulation you like. When you're done, and ready to run +the "real" main.js file (ie, the one that was spawned in the first +place), you can do this: + +```javascript +// /path/to/my/main.js +// process.argv[1] === 'foo=bar' +// and process.env.FOO === '1' + +// my wrapping manipulations +setupInstrumentationOrCoverageOrWhatever() +process.on('exit', function (code) { + storeCoverageInfoSynchronously() +}) + +// now run the instrumented and covered or whatever codes +require('spawn-wrap').runMain() +``` + ## CAVEATS -Lookups of shebangs require synchronous I/O. Probably you should not +The initial wrap call uses synchronous I/O. Probably you should not be using this script in any production environments anyway. Also, this will slow down child process execution by a lot, since -we're adding at least one layer of indirection. +we're adding a few layers of indirection. -You can't at this time use the wrapperArgs to pass node args like -`--use_strict` that come before the main file. +I would not be very surprised to find out that it works on Windows. +No way to tell for certain, though. diff --git a/node_modules/spawn-wrap/index.js b/node_modules/spawn-wrap/index.js index eb0f01057..7f5d9f788 100644 --- a/node_modules/spawn-wrap/index.js +++ b/node_modules/spawn-wrap/index.js @@ -1,134 +1,236 @@ -// sure would be nice if the class were exposed... -var cp = require('child_process') +module.exports = wrap +wrap.runMain = runMain + +var Module = require('module') var fs = require('fs') -var child = cp.spawn('echo', []) -var ChildProcess = child.constructor -var path = require('path') -var which = require('which') +var ChildProcess var assert = require('assert') -child.kill('SIGKILL') +var crypto = require('crypto') +var mkdirp = require('mkdirp') +var rimraf = require('rimraf') +var path = require('path') -var shebangRe = new RegExp( - '^#!' + - '(?:(?:(?:\\/usr)?\\/bin\\/)?env (iojs|node))' + // $1 - env lookup - '|' + - '(.*\\/(?:iojs|node))' // $2 - absolute path -) +var shim = '#!' + process.execPath + '\n' + + fs.readFileSync(__dirname + '/shim.js') -var wrapMain = require.resolve('./wrap-main.js') +var cmdShim = 'SETLOCAL\r\n' + + 'SET PATHEXT=%PATHEXT:;.JS;=;%\r\n' + + process.execPath + ' "%~dp0\\.\\node" %*\r\n' -var hasDashR = /^(1\.[6-9]|2)\./.test(process.version) +var isWindows = false +var pathRe = /^PATH=/ +if (process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys') { + pathRe = /^PATH=/i + isWindows = true +} -module.exports = wrap +var colon = isWindows ? ';' : ':' -function wrap (args, envs) { - if (args) - assert(Array.isArray(args), 'args must be array') - else - args = [] - - var pairs = [] - if (envs) { - assert.equal(typeof envs, 'object', 'envs must be object') - pairs = Object.keys(envs).map(function (k) { - return k + '=' + envs[k] - }) +function wrap (argv, env, workingDir) { + if (!ChildProcess) { + // sure would be nice if the class were exposed... + var child = require('child_process').spawn(process.execPath, []) + ChildProcess = child.constructor + child.kill('SIGKILL') } + // if we're passed in the working dir, then it means that setup + // was already done, so no need. + var doSetup = !workingDir + if (doSetup) { + workingDir = setup(argv, env) + } var spawn = ChildProcess.prototype.spawn - var exec = cp.exec - - var injectArgs = [wrapMain] - injectArgs.push('--args=' + args.length) - injectArgs.push.apply(injectArgs, args) - - injectArgs.push('--envs=' + pairs.length) - pairs.forEach(function (k) { - injectArgs.push(k) - }) - - injectArgs.push('--') - - var spliceArgs = [1, 0].concat(injectArgs) function unwrap () { + if (doSetup) { + rimraf.sync(workingDir) + } ChildProcess.prototype.spawn = spawn - cp.exec = exec } ChildProcess.prototype.spawn = function (options) { - // TODO: Have to look up shebangs for spawn as well. - - if (options.file === process.execPath || - path.basename(options.file) === 'node' || - path.basename(options.file) === 'iojs') { - options.args.splice.apply(options.args, spliceArgs) - if (envs) - options.envPairs.push.apply(options.envPairs, pairs) + // var out = fs.createWriteStream('/dev/tty') + // out.write('\nSPAWN ' + options.args.join(' ') + '\n') + var pathEnv + var cmdi, c, re, match, exe + + // handle case where node/iojs is exec'd + // this doesn't handle EVERYTHING, but just the most common + // case of doing `exec(process.execPath + ' file.js') + var file = path.basename(options.file) + if (file === 'sh' || file === 'bash' || file === 'zsh') { + // out.write('\n shell file\n') + cmdi = options.args.indexOf('-c') + if (cmdi !== -1) { + c = options.args[cmdi + 1] + re = /^\s*((?:[^\= ]*\=[^\=\s]*\s*)*)([^\s]+)/ + match = c.match(re) + if (match) { + exe = path.basename(match[2]) + if (exe === 'iojs' || exe === 'node') { + c = c.replace(re, '$1' + exe) + options.args[cmdi + 1] = c + } + } + } + // out.write('\n shell '+options.args.join(' ')+'\n') + } else if (isWindows && ( + file === path.basename(process.env.comspec) || + file === 'cmd.exe')) { + cmdi = options.args.indexOf('/c') + if (cmdi !== -1) { + c = options.args[cmdi + 1] + re = new RegExp('^\\s*"([^\\s]*(?:node|iojs)) ') + match = c.match(re) + if (match) { + exe = path.basename(match[1]).replace(/\.exe$/, '') + if (exe === 'node' || exe === 'iojs') { + c = c.replace(re, exe + ' ') + options.args[cmdi + 1] = c + } + } + } + } else if (file === 'node' || file === 'iojs') { + // out.write('\n node '+options.args.join(' ')+'\n') + // make sure it has a main script. + // otherwise, just let it through. + var a = 0 + var hasMain = false + for (var a = 1; !hasMain && a < options.args.length; a++) { + switch (options.args[a]) { + case '-i': + case '--interactive': + case '--eval': + case '-e': + case '-pe': + hasMain = false + a = options.args.length + continue + + case '-r': + case '--require': + a += 1 + continue + + default: + if (options.args[a].match(/^-/)) { + continue + } else { + hasMain = true + a = options.args.length + break + } + } + } + + if (hasMain) { + options.file = workingDir + '/' + file + options.args[0] = workingDir + '/' + file + // out.write('\n has main '+options.args.join(' ')+'\n') + } } + for (var i = 0; i < options.envPairs.length; i++) { + var ep = options.envPairs[i] + if (ep.match(pathRe)) { + pathEnv = ep.substr(5) + var k = ep.substr(0, 5) + options.envPairs[i] = k + workingDir + colon + pathEnv + } + } + if (!pathEnv) { + options.envPairs.push((isWindows ? 'Path=' : 'PATH=') + workingDir) + } + + //fs.createWriteStream('/dev/tty').write('SET PATH ' + p + '\n') + + // out.write('\n env\n '+options.envPairs.join('\n ')+'\n') return spawn.call(this, options) } - cp.exec = function (command /*...*/) { - var doWrap = false - - // if the first cmd is node, we definitely wrap - var b = command.trim().split(/\s+/) - var shebang = null - var exe = b[0] - if (path.basename(exe) === 'node' || - path.basename(exe) === 'iojs' || - exe === process.execPath) { - doWrap = true - } else { - // might be a shebang. Check for that. - // no way to do this without sync i/o - try { - // TODO: this uses the *caller's* PATH environ, but in fact, - // when the shell looks up the file to execute, it is using - // the *callee's* PATH. The 'which' module must be extended - // to take a PATH as an argument. - var resolved = which.sync(b[0]) - var fd = fs.openSync(resolved, 'r') - var buf = new Buffer(1024) - fs.readSync(fd, buf, 0, 1024) - var chunk = buf.toString().split(/\n/)[0] - shebang = chunk.match(shebangRe) - if (shebang) - doWrap = true - } catch (er) { - // oh well, not ours. - try { fs.closeSync(fd) } catch (er) {} - doWrap = false - } - } + return unwrap +} - var args - if (doWrap) { - command = command.trim() - var node = exe - if (shebang) { - node = shebang[1] || shebang[2] || process.execPath - command = resolved + command.substr(exe.length) - } else { - command = command.substr(exe.length) - } +function setup (argv, env) { + if (argv && typeof argv === 'object' && !env && !Array.isArray(argv)) { + env = argv + argv = [] + } + + if (!argv && !env) { + throw new Error('at least one of "argv" and "env" required') + } - command = [node].concat(injectArgs.map(function (a) { - return JSON.stringify(a) - })).join(' ') + ' ' + command + if (argv) { + assert(Array.isArray(argv), 'argv must be array') + } else { + argv = [] + } + + if (env) { + assert(typeof env === 'object', 'env must be an object') + } else { + env = {} + } - args = [ command ] - for (var i = 1; i < arguments.length; i++) { - args.push(arguments[i]) + // For stuff like --use_strict or --harmony, we need to inject + // the argument *before* the wrap-main. + var execArgv = [] + for (var i = 0; i < argv.length; i++) { + if (argv[i].match(/^-/)) { + execArgv.push(argv[i]) + if (argv[i] === '-r' || argv[i] === '--require') { + execArgv.push(argv[++i]) } } else { - args = arguments + break } + } + if (execArgv.length) { + if (execArgv.length === argv.length) { + argv.length = 0 + } else { + argv = argv.slice(execArgv.length) + } + } + + var settings = JSON.stringify({ + module: __filename, + argv: argv, + execArgv: execArgv, + env: env, + root: process.pid + }, null, 2) + '\n' + + var workingDir = '/tmp/node-spawn-wrap-' + process.pid + '-' + + crypto.randomBytes(6).toString('hex') - return exec.apply(cp, args) + process.on('exit', function () { + rimraf.sync(workingDir) + }) + + mkdirp.sync(workingDir) + workingDir = fs.realpathSync(workingDir) + if (isWindows) { + fs.writeFileSync(workingDir + '/node.cmd', cmdShim) + fs.chmodSync(workingDir + '/node.cmd', '0755') + fs.writeFileSync(workingDir + '/iojs.cmd', cmdShim) + fs.chmodSync(workingDir + '/iojs.cmd', '0755') } + fs.writeFileSync(workingDir + '/node', shim) + fs.chmodSync(workingDir + '/node', '0755') + fs.writeFileSync(workingDir + '/iojs', shim) + fs.chmodSync(workingDir + '/iojs', '0755') + fs.writeFileSync(workingDir + '/settings.json', settings) - return unwrap + return workingDir +} + +function runMain () { + process.argv.splice(1, 1) + process.argv[1] = path.resolve(process.argv[1]) + Module.runMain() } diff --git a/node_modules/spawn-wrap/node_modules/.bin/which b/node_modules/spawn-wrap/node_modules/.bin/which deleted file mode 120000 index f62471c85..000000000 --- a/node_modules/spawn-wrap/node_modules/.bin/which +++ /dev/null @@ -1 +0,0 @@ -../which/bin/which \ No newline at end of file diff --git a/node_modules/spawn-wrap/node_modules/which/LICENSE b/node_modules/spawn-wrap/node_modules/which/LICENSE deleted file mode 100644 index 19129e315..000000000 --- a/node_modules/spawn-wrap/node_modules/which/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/spawn-wrap/node_modules/which/README.md b/node_modules/spawn-wrap/node_modules/which/README.md deleted file mode 100644 index d5571528a..000000000 --- a/node_modules/spawn-wrap/node_modules/which/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# which - -Like the unix `which` utility. - -Finds the first instance of a specified executable in the PATH -environment variable. Does not cache the results, so `hash -r` is not -needed when the PATH changes. - -## USAGE - -```javascript -var which = require('which') - -// async usage -which('node', function (er, resolvedPath) { - // er is returned if no "node" is found on the PATH - // if it is found, then the absolute path to the exec is returned -}) - -// sync usage -// throws if not found -var resolved = which.sync('node') - -// Pass options to override the PATH and PATHEXT environment vars. -which('node', { path: someOtherPath }, function (er, resolved) { - if (er) - throw er - console.log('found at %j', resolved) -}) -``` - -## OPTIONS - -If you pass in options, then `path` and `pathExt` are relevant. diff --git a/node_modules/spawn-wrap/node_modules/which/bin/which b/node_modules/spawn-wrap/node_modules/which/bin/which deleted file mode 100755 index 58ca6eff2..000000000 --- a/node_modules/spawn-wrap/node_modules/which/bin/which +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env node -var which = require("../") -if (process.argv.length < 3) { - console.error("Usage: which ") - process.exit(1) -} - -which(process.argv[2], function (er, thing) { - if (er) { - console.error(er.message) - process.exit(er.errno || 127) - } -}) diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/LICENSE b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/LICENSE deleted file mode 100644 index 904ab073b..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014-2015, Jon Schlinkert.Copyright (c) 2009-2015, TJ Holowaychuk. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/README.md b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/README.md deleted file mode 100644 index 768f4b833..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# is-absolute [![NPM version](https://badge.fury.io/js/is-absolute.svg)](http://badge.fury.io/js/is-absolute) [![Build Status](https://travis-ci.org/jonschlinkert/is-absolute.svg)](https://travis-ci.org/jonschlinkert/is-absolute) - -> Return true if a file path is absolute. - -Based on the `isAbsolute` utility method in [express](https://github.com/visionmedia/express). - -## Install with [npm](npmjs.org) - -```bash -npm i is-absolute --save -``` - -## Usage - -```js -var isAbsolute = require('is-absolute'); -console.log(isAbsolute('a/b/c.js')); -//=> 'false'; -``` - -## Running tests -Install dev dependencies. - -```bash -npm i -d && npm test -``` - - -## Contributing -Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-absolute/issues) - - -## Other projects -* [is-relative](https://github.com/jonschlinkert/is-relative): Returns `true` if the path appears to be relative. -* [is-dotfile](https://github.com/regexps/is-dotfile): Return true if a file path is (or has) a dotfile. -* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern. -* [cwd](https://github.com/jonschlinkert/cwd): Node.js util for easily getting the current working directory of a project based on package.json or the given path. -* [git-config-path](https://github.com/jonschlinkert/git-config-path): Resolve the path to the user's global .gitconfig. - -## Author - -**Jon Schlinkert** - -+ [github/jonschlinkert](https://github.com/jonschlinkert) -+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) - -## License -Copyright (c) 2014-2015 Jon Schlinkert -Released under the MIT license - -*** - -_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 05, 2015._ diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/index.js b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/index.js deleted file mode 100644 index e7a40dd73..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/index.js +++ /dev/null @@ -1,27 +0,0 @@ -/*! - * is-absolute - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - -'use strict'; - -var isRelative = require('is-relative'); - -module.exports = function isAbsolute(filepath) { - if ('/' === filepath[0]) { - return true; - } - if (':' === filepath[1] && '\\' === filepath[2]) { - return true; - } - // Microsoft Azure absolute filepath - if ('\\\\' == filepath.substring(0, 2)) { - return true; - } - if (!isRelative(filepath)) { - return true; - } -}; - diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/LICENSE-MIT b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/LICENSE-MIT deleted file mode 100644 index b576e8d48..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Jon Schlinkert - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/README.md b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/README.md deleted file mode 100644 index 760be8d06..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# is-relative [![NPM version](https://badge.fury.io/js/is-relative.svg)](http://badge.fury.io/js/is-relative) - -> Returns `true` if the path appears to be relative. - -## Install -### Install with [npm](npmjs.org) - -```bash -npm i is-relative --save -``` - -## Usage -### [isRelative](index.js#L16) - -* `filepath` **{String}**: Path to test. -* `returns`: {Boolean} - -```js -var isRelative = require('is-relative'); -isRelative('README.md'); -//=> true -``` - - -## Author - -**Jon Schlinkert** - -+ [github/jonschlinkert](https://github.com/jonschlinkert) -+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) - -## License -Copyright (c) 2014 Jon Schlinkert -Released under the MIT license - -*** - -_This file was generated by [verb](https://github.com/assemble/verb) on November 17, 2014._ \ No newline at end of file diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/index.js b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/index.js deleted file mode 100644 index ffc760a82..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/index.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -/** - * ```js - * var isRelative = require('is-relative'); - * isRelative('README.md'); - * //=> true - * ``` - * - * @name isRelative - * @param {String} `filepath` Path to test. - * @return {Boolean} - * @api public - */ - -module.exports = function isRelative(filepath) { - if (typeof filepath !== 'string') { - throw new Error('isRelative expects a string.'); - } - return !/^([a-z]+:)?[\\\/]/i.test(filepath); -}; \ No newline at end of file diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/package.json b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/package.json deleted file mode 100644 index 4d766e22c..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/node_modules/is-relative/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "is-relative", - "description": "Returns `true` if the path appears to be relative.", - "version": "0.1.3", - "homepage": "https://github.com/jonschlinkert/is-relative", - "author": { - "name": "Jon Schlinkert", - "url": "https://github.com/jonschlinkert" - }, - "repository": { - "type": "git", - "url": "git://github.com/jonschlinkert/is-relative.git" - }, - "bugs": { - "url": "https://github.com/jonschlinkert/is-relative/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/jonschlinkert/is-relative/blob/master/LICENSE-MIT" - } - ], - "keywords": [ - "absolute", - "check", - "file", - "filepath", - "is", - "normalize", - "path", - "path.relative", - "relative", - "resolve", - "slash", - "slashes", - "uri", - "url" - ], - "main": "index.js", - "files": [ - "index.js", - "LICENSE-MIT" - ], - "engines": { - "node": ">=0.10.0" - }, - "scripts": { - "test": "mocha -R spec" - }, - "devDependencies": { - "mocha": "*", - "verb": ">= 0.2.6", - "verb-tag-jscomments": "^0.1.4" - }, - "_id": "is-relative@0.1.3", - "_shasum": "905fee8ae86f45b3ec614bc3c15c869df0876e82", - "_from": "is-relative@>=0.1.0 <0.2.0", - "_npmVersion": "1.4.9", - "_npmUser": { - "name": "jonschlinkert", - "email": "github@sellside.com" - }, - "maintainers": [ - { - "name": "jonschlinkert", - "email": "github@sellside.com" - } - ], - "dist": { - "shasum": "905fee8ae86f45b3ec614bc3c15c869df0876e82", - "tarball": "http://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz" -} diff --git a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/package.json b/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/package.json deleted file mode 100644 index 1187a59d5..000000000 --- a/node_modules/spawn-wrap/node_modules/which/node_modules/is-absolute/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "is-absolute", - "description": "Return true if a file path is absolute.", - "version": "0.1.7", - "homepage": "https://github.com/jonschlinkert/is-absolute", - "author": { - "name": "Jon Schlinkert", - "url": "https://github.com/jonschlinkert" - }, - "repository": { - "type": "git", - "url": "git://github.com/jonschlinkert/is-absolute.git" - }, - "bugs": { - "url": "https://github.com/jonschlinkert/is-absolute/issues" - }, - "license": { - "type": "MIT", - "url": "https://github.com/jonschlinkert/is-absolute/blob/master/LICENSE" - }, - "files": [ - "index.js" - ], - "main": "index.js", - "engines": { - "node": ">=0.10.0" - }, - "scripts": { - "test": "mocha" - }, - "dependencies": { - "is-relative": "^0.1.0" - }, - "devDependencies": { - "mocha": "*" - }, - "keywords": [ - "absolute", - "check", - "file", - "filepath", - "is", - "normalize", - "path", - "path.relative", - "relative", - "resolve", - "slash", - "slashes", - "uri", - "url" - ], - "gitHead": "90cca7b671620bf28b778a61fddc8a986a2e1095", - "_id": "is-absolute@0.1.7", - "_shasum": "847491119fccb5fb436217cc737f7faad50f603f", - "_from": "is-absolute@>=0.1.7 <0.2.0", - "_npmVersion": "2.5.1", - "_nodeVersion": "0.12.0", - "_npmUser": { - "name": "jonschlinkert", - "email": "github@sellside.com" - }, - "maintainers": [ - { - "name": "jonschlinkert", - "email": "github@sellside.com" - } - ], - "dist": { - "shasum": "847491119fccb5fb436217cc737f7faad50f603f", - "tarball": "http://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz" -} diff --git a/node_modules/spawn-wrap/node_modules/which/package.json b/node_modules/spawn-wrap/node_modules/which/package.json deleted file mode 100644 index cf30613b7..000000000 --- a/node_modules/spawn-wrap/node_modules/which/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me" - }, - "name": "which", - "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.", - "version": "1.1.1", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-which.git" - }, - "main": "which.js", - "bin": { - "which": "./bin/which" - }, - "license": "ISC", - "dependencies": { - "is-absolute": "^0.1.7" - }, - "devDependencies": { - "mkdirp": "^0.5.0", - "rimraf": "^2.3.3", - "tap": "^1.0.2" - }, - "scripts": { - "test": "tap test/*.js" - }, - "gitHead": "c80a08e9f8cf7a5c0f39c2e2f87f18f153b118a8", - "bugs": { - "url": "https://github.com/isaacs/node-which/issues" - }, - "homepage": "https://github.com/isaacs/node-which#readme", - "_id": "which@1.1.1", - "_shasum": "9ce512459946166e12c083f08ec073380fc8cbbb", - "_from": "which@>=1.0.9 <2.0.0", - "_npmVersion": "2.9.1", - "_nodeVersion": "2.0.1", - "_npmUser": { - "name": "isaacs", - "email": "isaacs@npmjs.com" - }, - "dist": { - "shasum": "9ce512459946166e12c083f08ec073380fc8cbbb", - "tarball": "http://registry.npmjs.org/which/-/which-1.1.1.tgz" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_resolved": "https://registry.npmjs.org/which/-/which-1.1.1.tgz" -} diff --git a/node_modules/spawn-wrap/node_modules/which/test/basic.js b/node_modules/spawn-wrap/node_modules/which/test/basic.js deleted file mode 100644 index 189ca6d0a..000000000 --- a/node_modules/spawn-wrap/node_modules/which/test/basic.js +++ /dev/null @@ -1,84 +0,0 @@ -var t = require('tap') -var fs = require('fs') -var rimraf = require('rimraf') -var mkdirp = require('mkdirp') -var fixture = __dirname + '/fixture' -var which = require('../which.js') -var path = require('path') - -var isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' - -var skip = { skip: isWindows ? 'not relevant on windows' : false } - -t.test('setup', function (t) { - rimraf.sync(fixture) - mkdirp.sync(fixture) - fs.writeFileSync(fixture + '/foo.sh', 'echo foo\n') - t.end() -}) - -t.test('does not find non-executable', skip, function (t) { - t.plan(2) - - t.test('absolute', function (t) { - t.plan(2) - which(fixture + '/foo.sh', function (er) { - t.isa(er, Error) - }) - - t.throws(function () { - which.sync(fixture + '/foo.sh') - }) - }) - - t.test('with path', function (t) { - t.plan(2) - which('foo.sh', { path: fixture }, function (er) { - t.isa(er, Error) - }) - - t.throws(function () { - which.sync('foo.sh', { path: fixture }) - }) - }) -}) - -t.test('make executable', function (t) { - fs.chmodSync(fixture + '/foo.sh', '0755') - t.end() -}) - -t.test('find when executable', function (t) { - t.plan(2) - var opt = { pathExt: '.sh' } - var expect = path.resolve(fixture, 'foo.sh').toLowerCase() - - t.test('absolute', function (t) { - t.plan(2) - runTest(t) - }) - - function runTest(t) { - which(fixture + '/foo.sh', opt, function (er, found) { - if (er) - throw er - t.equal(found.toLowerCase(), expect) - }) - - var found = which.sync(fixture + '/foo.sh', opt).toLowerCase() - t.equal(found, expect) - } - - t.test('with path', function (t) { - t.plan(2) - opt.path = fixture - runTest(t) - }) -}) - -t.test('clean', function (t) { - rimraf.sync(fixture) - t.end() -}) diff --git a/node_modules/spawn-wrap/node_modules/which/which.js b/node_modules/spawn-wrap/node_modules/which/which.js deleted file mode 100644 index 13fc26dcf..000000000 --- a/node_modules/spawn-wrap/node_modules/which/which.js +++ /dev/null @@ -1,137 +0,0 @@ -module.exports = which -which.sync = whichSync - -var isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' - -var path = require('path') -var COLON = isWindows ? ';' : ':' -var isExe -var fs = require('fs') -var isAbsolute = require('is-absolute') - -if (isWindows) { - // On windows, there is no good way to check that a file is executable - isExe = function isExe () { return true } -} else { - isExe = function isExe (mod, uid, gid) { - var ret = (mod & 0001) - || (mod & 0010) && process.getgid && gid === process.getgid() - || (mod & 0100) && process.getuid && uid === process.getuid() - || (mod & 0110) && process.getuid && 0 === process.getuid() - - if (process.getgroups && (mod & 0010)) { - var groups = process.getgroups() - for (var g = 0; g < groups.length; g++) { - if (groups[g] === gid) - return true - } - } - - return ret - } -} - -function which (cmd, opt, cb) { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - - var colon = opt.colon || COLON - var pathEnv = opt.path || process.env.PATH || '' - var pathExt = [''] - - // On windows, env.Path is common. - if (isWindows && !pathEnv) { - var k = Object.keys(process.env) - for (var p = 0; p < k.length; p++) { - if (p.toLowerCase() === 'path') { - pathEnv = process.env[p] - break - } - } - } - - pathEnv = pathEnv.split(colon) - - if (isWindows) { - pathEnv.unshift(process.cwd()) - pathExt = (opt.pathExt || process.env.PATHEXT || '.EXE').split(colon) - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } - - // If it's absolute, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - if (isAbsolute(cmd)) - pathEnv = [''] - - ;(function F (i, l) { - if (i === l) return cb(new Error('not found: '+cmd)) - var p = path.resolve(pathEnv[i], cmd) - ;(function E (ii, ll) { - if (ii === ll) return F(i + 1, l) - var ext = pathExt[ii] - fs.stat(p + ext, function (er, stat) { - if (!er && - stat.isFile() && - isExe(stat.mode, stat.uid, stat.gid)) { - return cb(null, p + ext) - } - return E(ii + 1, ll) - }) - })(0, pathExt.length) - })(0, pathEnv.length) -} - -function whichSync (cmd, opt) { - if (!opt) - opt = {} - - var colon = opt.colon || COLON - - var pathEnv = opt.path || process.env.PATH || '' - var pathExt = [''] - - // On windows, env.Path is common. - if (isWindows && !pathEnv) { - var k = Object.keys(process.env) - for (var p = 0; p < k.length; p++) { - if (p.toLowerCase() === 'path') { - pathEnv = process.env[p] - break - } - } - } - - pathEnv = pathEnv.split(colon) - - if (isWindows) { - pathEnv.unshift(process.cwd()) - pathExt = (opt.pathExt || process.env.PATHEXT || '.EXE').split(colon) - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } - - // If it's absolute, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - if (isAbsolute(cmd)) - pathEnv = [''] - - for (var i = 0, l = pathEnv.length; i < l; i ++) { - var p = path.join(pathEnv[i], cmd) - for (var j = 0, ll = pathExt.length; j < ll; j ++) { - var cur = p + pathExt[j] - var stat - try { - stat = fs.statSync(cur) - if (stat.isFile() && isExe(stat.mode, stat.uid, stat.gid)) - return cur - } catch (ex) {} - } - } - - throw new Error('not found: '+cmd) -} diff --git a/node_modules/spawn-wrap/package.json b/node_modules/spawn-wrap/package.json index 4327d6b8e..c93387a6f 100644 --- a/node_modules/spawn-wrap/package.json +++ b/node_modules/spawn-wrap/package.json @@ -1,10 +1,11 @@ { "name": "spawn-wrap", - "version": "0.0.0", + "version": "0.0.9", "description": "Wrap all spawned Node.js child processes by adding environs and arguments ahead of the main JavaScript file argument.", "main": "index.js", "dependencies": { - "which": "^1.0.9" + "mkdirp": "^0.5.0", + "rimraf": "^2.3.3" }, "devDependencies": {}, "scripts": { @@ -24,19 +25,19 @@ "url": "https://github.com/isaacs/spawn-wrap/issues" }, "homepage": "https://github.com/isaacs/spawn-wrap#readme", - "gitHead": "df53fd88c6853ef5d5d1288ebd3e11b1ec709b01", - "_id": "spawn-wrap@0.0.0", - "_shasum": "47c032ae164e446b303f38da23d0699a9e810a64", - "_from": "spawn-wrap@0.0.0", - "_npmVersion": "2.9.1", + "gitHead": "372543dea960b0dddd7cb570913b4a430e0e25d0", + "_id": "spawn-wrap@0.0.9", + "_shasum": "4a8f5f6c76b73569e25f254e5d54df34e8cffeb4", + "_from": "spawn-wrap@*", + "_npmVersion": "2.10.0", "_nodeVersion": "2.0.1", "_npmUser": { "name": "isaacs", "email": "isaacs@npmjs.com" }, "dist": { - "shasum": "47c032ae164e446b303f38da23d0699a9e810a64", - "tarball": "http://registry.npmjs.org/spawn-wrap/-/spawn-wrap-0.0.0.tgz" + "shasum": "4a8f5f6c76b73569e25f254e5d54df34e8cffeb4", + "tarball": "http://registry.npmjs.org/spawn-wrap/-/spawn-wrap-0.0.9.tgz" }, "maintainers": [ { @@ -45,5 +46,5 @@ } ], "directories": {}, - "_resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-0.0.0.tgz" + "_resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-0.0.9.tgz" } diff --git a/node_modules/spawn-wrap/scripts/argv.js b/node_modules/spawn-wrap/scripts/argv.js deleted file mode 100755 index f7cfa2c77..000000000 --- a/node_modules/spawn-wrap/scripts/argv.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -console.log(process.argv) diff --git a/node_modules/spawn-wrap/t.js b/node_modules/spawn-wrap/t.js old mode 100644 new mode 100755 index 0d674dd3c..fa0ce2b7a --- a/node_modules/spawn-wrap/t.js +++ b/node_modules/spawn-wrap/t.js @@ -1,24 +1,26 @@ +#!/usr/bin/env node if (process.env.xyz) { console.log('in t.js, xyz=%j', process.env.xyz) - var Module = require('module') - delete Module._cache[__filename] - process.argv.splice(1, 1) - process.argv[1] = require('path').resolve(process.argv[1]) - Module.runMain() - console.error('ran wrapped main') + console.log('gc is a', typeof gc) + console.log('%j', process.argv) + console.log('about to run the main file\u001b[32m') + require('./index.js').runMain() + console.log('\u001b[31mran wrapped main') return } var wrap = require('./index.js') -var unwrap = wrap([__filename], { xyz: 'ABC' }) +var unwrap = wrap(['--expose_gc', __filename, ' a $ b '], { xyz: 'ABC' }) +console.log('about to run child process') +console.log('gc is a', typeof gc) var cp = require('child_process') -var child = cp.exec('tap -h', function (er, out, err) { +var child = cp.exec(process.execPath + ' $(which tap ) -h', { env: { foo: 'asdf', PATH:process.env.PATH } }, function (er, out, err) { console.error('returned') console.error('error = ', er) console.error('outlen=', out.length) - console.error(out.split(/\n\n/)[0]) + console.error('\u001b[31m' + out + '\u001b[m') console.error('errlen=', err.length) process.stderr.write(err) }) diff --git a/node_modules/spawn-wrap/wrap-main.js b/node_modules/spawn-wrap/wrap-main.js deleted file mode 100644 index 22bc30745..000000000 --- a/node_modules/spawn-wrap/wrap-main.js +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env node - -//console.log('IN THE WRAPAMABOB', process.argv) -if (module !== require.main) { -// console.error('are you quite sure this is what you want?') - process.exit(1) -} - -var assert = require('assert') -var n = +(process.argv[2].match(/^--args=([0-9]+)$/)[1]) -assert(!isNaN(n) && n >= 0) -var injectArgs = [] -var i -for (i = 3; i < n + 3; i++) { - injectArgs.push(process.argv[i]) -} - -var n = +(process.argv[i].match(/^--envs=([0-9]+)$/)[1]) -assert(!isNaN(n) && n >= 0) -var start = i + 1 -for (i = start; i < start + n; i++) { - var kv = process.argv[i].split('=') - var key = kv.shift() - var val = kv.join('=') - process.env[key] = val -} - -assert.equal(process.argv[i], '--') -var n = i - 1 -var spliceArgs = [1, i].concat(injectArgs) -process.argv.splice.apply(process.argv, spliceArgs) - -//console.error(process.argv) - -delete require('module')._cache[__filename] -//console.log('About to run main file: %j', process.argv[1]) -require('module').runMain() diff --git a/package.json b/package.json index de399b590..5626ef0ce 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "forking code-coverage using istanbul.", "main": "index.js", "scripts": { - "test": "standard && ./bin/nyc.js ./node_modules/.bin/mocha --ui exports", + "test": "standard && ./bin/nyc.js tap ./test/nyc-test.js", "coverage": "./bin/nyc-report.js --reporter=text-lcov | coveralls" }, "bin": { @@ -22,25 +22,26 @@ "coverage", "subprocess" ], + "contributors": [ + "Isaac Schlueter " + ], "author": "Ben Coe ", "license": "ISC", "dependencies": { "istanbul": "^0.3.14", + "jsonstream": "^1.0.3", "lodash": "^3.8.0", "mkdirp": "^0.5.0", "rimraf": "^2.3.3", + "spawn-wrap": "0.0.9", "strip-bom": "^1.0.0", - "yargs": "^3.8.0", - "spawn-wrap": "0.0.0" + "yargs": "^3.8.0" }, - "bundledDependencies": [ - "spawn-wrap" - ], "devDependencies": { "chai": "^2.3.0", "coveralls": "^2.11.2", - "mocha": "^2.2.4", - "standard": "^3.7.3" + "standard": "^3.7.3", + "tap": "^1.0.4" }, "repository": { "type": "git", diff --git a/test/fixtures/sighup.js b/test/fixtures/sighup.js deleted file mode 100644 index bb20d2fa3..000000000 --- a/test/fixtures/sighup.js +++ /dev/null @@ -1 +0,0 @@ -process.kill(process.pid, 'SIGHUP') diff --git a/test/fixtures/sigint.js b/test/fixtures/sigint.js old mode 100644 new mode 100755 index bb7dfc8d1..ecd35eee5 --- a/test/fixtures/sigint.js +++ b/test/fixtures/sigint.js @@ -1 +1,3 @@ +#!/usr/bin/env node + process.kill(process.pid, 'SIGINT') diff --git a/test/fixtures/sigterm.js b/test/fixtures/sigterm.js old mode 100644 new mode 100755 index d7d41998a..63e0483c3 --- a/test/fixtures/sigterm.js +++ b/test/fixtures/sigterm.js @@ -1 +1,3 @@ +#!/usr/bin/env node + process.kill(process.pid, 'SIGTERM') diff --git a/test/nyc-test.js b/test/nyc-test.js index d12d3ef9b..0fcd02e08 100644 --- a/test/nyc-test.js +++ b/test/nyc-test.js @@ -1,28 +1,29 @@ -/* global describe, it, afterEach, before */ - -require('chai').should() +/* global describe, it */ var _ = require('lodash'), - fs = require('fs'), - spawn = require('child_process').spawn, NYC = require('../'), path = require('path'), - rimraf = require('rimraf') + rimraf = require('rimraf'), + spawn = require('child_process').spawn + +require('chai').should() +require('tap').mochaGlobals() describe('nyc', function () { var fixtures = path.resolve(__dirname, './fixtures') describe('cwd', function () { - afterEach(function () { + function afterEach () { delete process.env.NYC_CWD rimraf.sync(path.resolve(fixtures, './nyc_output')) - }) + } it('sets cwd to process.cwd() if no environment variable is set', function () { var nyc = new NYC() nyc.cwd.should.eql(process.cwd()) + afterEach() }) it('uses NYC_CWD environment variable for cwd if it is set', function () { @@ -31,6 +32,7 @@ describe('nyc', function () { var nyc = new NYC() nyc.cwd.should.match(/nyc\/test\/fixtures/) + afterEach() }) }) @@ -47,41 +49,30 @@ describe('nyc', function () { describe('wrap', function () { var nyc - before(function () { + it('wraps modules with coverage counters when they are required', function () { nyc = (new NYC({ cwd: process.cwd() })).wrap() - }) - it('wraps modules with coverage counters when they are required', function () { // clear the module cache so that // we pull index.js in again and wrap it. var name = require.resolve('../') delete require.cache[name] - // when we require index.js it shoudl be wrapped. + // when we require index.js it should be wrapped. var index = require('../') index.should.match(/__cov_/) }) - it('writes coverage report when process exits', function (done) { - var proc = spawn('./bin/nyc.js', ['index.js'], { - cwd: process.cwd(), - env: process.env, - stdio: [process.stdin, process.stdout, process.stderr] - }) - - proc.on('close', function () { - fs.readdirSync('./nyc_output').length.should.be.gte(1) - return done() - }) - }) - function testSignal (signal, done) { - var proc = spawn('./bin/nyc.js', ['./test/fixtures/' + signal + '.js'], { + var bin = './bin/nyc.js' + // use node as the bin if we're already wrapped. + if (~process.env._.indexOf('nyc')) bin = 'node' + + var proc = spawn(bin, ['./test/fixtures/' + signal + '.js'], { cwd: process.cwd(), env: process.env, - stdio: [process.stdin, process.stdout, process.stderr] + stdio: 'inherit' }) proc.on('close', function () { @@ -97,10 +88,6 @@ describe('nyc', function () { testSignal('sigterm', done) }) - it('writes coverage report when process is killed with SIGHUP', function (done) { - testSignal('sighup', done) - }) - it('writes coverage report when process is killed with SIGINT', function (done) { testSignal('sigint', done) }) @@ -111,7 +98,7 @@ describe('nyc', function () { var nyc = new NYC({ cwd: fixtures }), - proc = spawn('../../bin/nyc.js', ['sigterm.js'], { + proc = spawn('../../bin/nyc.js', ['./sigterm.js'], { cwd: fixtures, env: process.env, stdio: [process.stdin, process.stdout, process.stderr] From 21c4dda00f944e9e990e9b1d90d614017897f976 Mon Sep 17 00:00:00 2001 From: Benjamin Coe Date: Fri, 15 May 2015 08:45:12 -0700 Subject: [PATCH 2/3] removed checked-in spawn-wrap folder --- node_modules/spawn-wrap/LICENSE | 15 -- node_modules/spawn-wrap/README.md | 62 ------- node_modules/spawn-wrap/index.js | 236 --------------------------- node_modules/spawn-wrap/package.json | 50 ------ node_modules/spawn-wrap/t.js | 26 --- 5 files changed, 389 deletions(-) delete mode 100644 node_modules/spawn-wrap/LICENSE delete mode 100644 node_modules/spawn-wrap/README.md delete mode 100644 node_modules/spawn-wrap/index.js delete mode 100644 node_modules/spawn-wrap/package.json delete mode 100755 node_modules/spawn-wrap/t.js diff --git a/node_modules/spawn-wrap/LICENSE b/node_modules/spawn-wrap/LICENSE deleted file mode 100644 index 19129e315..000000000 --- a/node_modules/spawn-wrap/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/spawn-wrap/README.md b/node_modules/spawn-wrap/README.md deleted file mode 100644 index a6ca493fd..000000000 --- a/node_modules/spawn-wrap/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# spawn-wrap - -Wrap all spawned Node.js child processes by adding environs and -arguments ahead of the main JavaScript file argument. - -Any child processes launched by that child process will also be -wrapped in a similar fashion. - -This is a bit of a brutal hack, designed primarily to support code -coverage reporting in cases where tests or the system under test are -loaded via child processes rather than via `require()`. - -It can also be handy if you want to run your own mock executable -instead of some other thing when child procs call into it. - -## USAGE - -```javascript -var wrap = require('spawn-wrap') - -// wrap(wrapperArgs, environs) -var unwrap = wrap(['/path/to/my/main.js', 'foo=bar'], { FOO: 1 }) - -// later to undo the wrapping, you can call the returned function -unwrap() -``` - -In this example, the `/path/to/my/main.js` file will be used as the -"main" module, whenever any Node or io.js child process is started, -whether via a call to `spawn` or `exec`, whether node is invoked -directly as the command or as the result of a shebang `#!` lookup. - -In `/path/to/my/main.js`, you can do whatever instrumentation or -environment manipulation you like. When you're done, and ready to run -the "real" main.js file (ie, the one that was spawned in the first -place), you can do this: - -```javascript -// /path/to/my/main.js -// process.argv[1] === 'foo=bar' -// and process.env.FOO === '1' - -// my wrapping manipulations -setupInstrumentationOrCoverageOrWhatever() -process.on('exit', function (code) { - storeCoverageInfoSynchronously() -}) - -// now run the instrumented and covered or whatever codes -require('spawn-wrap').runMain() -``` - -## CAVEATS - -The initial wrap call uses synchronous I/O. Probably you should not -be using this script in any production environments anyway. - -Also, this will slow down child process execution by a lot, since -we're adding a few layers of indirection. - -I would not be very surprised to find out that it works on Windows. -No way to tell for certain, though. diff --git a/node_modules/spawn-wrap/index.js b/node_modules/spawn-wrap/index.js deleted file mode 100644 index 7f5d9f788..000000000 --- a/node_modules/spawn-wrap/index.js +++ /dev/null @@ -1,236 +0,0 @@ -module.exports = wrap -wrap.runMain = runMain - -var Module = require('module') -var fs = require('fs') -var ChildProcess -var assert = require('assert') -var crypto = require('crypto') -var mkdirp = require('mkdirp') -var rimraf = require('rimraf') -var path = require('path') - -var shim = '#!' + process.execPath + '\n' + - fs.readFileSync(__dirname + '/shim.js') - -var cmdShim = 'SETLOCAL\r\n' + - 'SET PATHEXT=%PATHEXT:;.JS;=;%\r\n' + - process.execPath + ' "%~dp0\\.\\node" %*\r\n' - -var isWindows = false -var pathRe = /^PATH=/ -if (process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys') { - pathRe = /^PATH=/i - isWindows = true -} - -var colon = isWindows ? ';' : ':' - -function wrap (argv, env, workingDir) { - if (!ChildProcess) { - // sure would be nice if the class were exposed... - var child = require('child_process').spawn(process.execPath, []) - ChildProcess = child.constructor - child.kill('SIGKILL') - } - - // if we're passed in the working dir, then it means that setup - // was already done, so no need. - var doSetup = !workingDir - if (doSetup) { - workingDir = setup(argv, env) - } - var spawn = ChildProcess.prototype.spawn - - function unwrap () { - if (doSetup) { - rimraf.sync(workingDir) - } - ChildProcess.prototype.spawn = spawn - } - - ChildProcess.prototype.spawn = function (options) { - // var out = fs.createWriteStream('/dev/tty') - // out.write('\nSPAWN ' + options.args.join(' ') + '\n') - var pathEnv - var cmdi, c, re, match, exe - - // handle case where node/iojs is exec'd - // this doesn't handle EVERYTHING, but just the most common - // case of doing `exec(process.execPath + ' file.js') - var file = path.basename(options.file) - if (file === 'sh' || file === 'bash' || file === 'zsh') { - // out.write('\n shell file\n') - cmdi = options.args.indexOf('-c') - if (cmdi !== -1) { - c = options.args[cmdi + 1] - re = /^\s*((?:[^\= ]*\=[^\=\s]*\s*)*)([^\s]+)/ - match = c.match(re) - if (match) { - exe = path.basename(match[2]) - if (exe === 'iojs' || exe === 'node') { - c = c.replace(re, '$1' + exe) - options.args[cmdi + 1] = c - } - } - } - // out.write('\n shell '+options.args.join(' ')+'\n') - } else if (isWindows && ( - file === path.basename(process.env.comspec) || - file === 'cmd.exe')) { - cmdi = options.args.indexOf('/c') - if (cmdi !== -1) { - c = options.args[cmdi + 1] - re = new RegExp('^\\s*"([^\\s]*(?:node|iojs)) ') - match = c.match(re) - if (match) { - exe = path.basename(match[1]).replace(/\.exe$/, '') - if (exe === 'node' || exe === 'iojs') { - c = c.replace(re, exe + ' ') - options.args[cmdi + 1] = c - } - } - } - } else if (file === 'node' || file === 'iojs') { - // out.write('\n node '+options.args.join(' ')+'\n') - // make sure it has a main script. - // otherwise, just let it through. - var a = 0 - var hasMain = false - for (var a = 1; !hasMain && a < options.args.length; a++) { - switch (options.args[a]) { - case '-i': - case '--interactive': - case '--eval': - case '-e': - case '-pe': - hasMain = false - a = options.args.length - continue - - case '-r': - case '--require': - a += 1 - continue - - default: - if (options.args[a].match(/^-/)) { - continue - } else { - hasMain = true - a = options.args.length - break - } - } - } - - if (hasMain) { - options.file = workingDir + '/' + file - options.args[0] = workingDir + '/' + file - // out.write('\n has main '+options.args.join(' ')+'\n') - } - } - - for (var i = 0; i < options.envPairs.length; i++) { - var ep = options.envPairs[i] - if (ep.match(pathRe)) { - pathEnv = ep.substr(5) - var k = ep.substr(0, 5) - options.envPairs[i] = k + workingDir + colon + pathEnv - } - } - if (!pathEnv) { - options.envPairs.push((isWindows ? 'Path=' : 'PATH=') + workingDir) - } - - //fs.createWriteStream('/dev/tty').write('SET PATH ' + p + '\n') - - // out.write('\n env\n '+options.envPairs.join('\n ')+'\n') - return spawn.call(this, options) - } - - return unwrap -} - -function setup (argv, env) { - if (argv && typeof argv === 'object' && !env && !Array.isArray(argv)) { - env = argv - argv = [] - } - - if (!argv && !env) { - throw new Error('at least one of "argv" and "env" required') - } - - if (argv) { - assert(Array.isArray(argv), 'argv must be array') - } else { - argv = [] - } - - if (env) { - assert(typeof env === 'object', 'env must be an object') - } else { - env = {} - } - - // For stuff like --use_strict or --harmony, we need to inject - // the argument *before* the wrap-main. - var execArgv = [] - for (var i = 0; i < argv.length; i++) { - if (argv[i].match(/^-/)) { - execArgv.push(argv[i]) - if (argv[i] === '-r' || argv[i] === '--require') { - execArgv.push(argv[++i]) - } - } else { - break - } - } - if (execArgv.length) { - if (execArgv.length === argv.length) { - argv.length = 0 - } else { - argv = argv.slice(execArgv.length) - } - } - - var settings = JSON.stringify({ - module: __filename, - argv: argv, - execArgv: execArgv, - env: env, - root: process.pid - }, null, 2) + '\n' - - var workingDir = '/tmp/node-spawn-wrap-' + process.pid + '-' + - crypto.randomBytes(6).toString('hex') - - process.on('exit', function () { - rimraf.sync(workingDir) - }) - - mkdirp.sync(workingDir) - workingDir = fs.realpathSync(workingDir) - if (isWindows) { - fs.writeFileSync(workingDir + '/node.cmd', cmdShim) - fs.chmodSync(workingDir + '/node.cmd', '0755') - fs.writeFileSync(workingDir + '/iojs.cmd', cmdShim) - fs.chmodSync(workingDir + '/iojs.cmd', '0755') - } - fs.writeFileSync(workingDir + '/node', shim) - fs.chmodSync(workingDir + '/node', '0755') - fs.writeFileSync(workingDir + '/iojs', shim) - fs.chmodSync(workingDir + '/iojs', '0755') - fs.writeFileSync(workingDir + '/settings.json', settings) - - return workingDir -} - -function runMain () { - process.argv.splice(1, 1) - process.argv[1] = path.resolve(process.argv[1]) - Module.runMain() -} diff --git a/node_modules/spawn-wrap/package.json b/node_modules/spawn-wrap/package.json deleted file mode 100644 index c93387a6f..000000000 --- a/node_modules/spawn-wrap/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "spawn-wrap", - "version": "0.0.9", - "description": "Wrap all spawned Node.js child processes by adding environs and arguments ahead of the main JavaScript file argument.", - "main": "index.js", - "dependencies": { - "mkdirp": "^0.5.0", - "rimraf": "^2.3.3" - }, - "devDependencies": {}, - "scripts": { - "test": "node t.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/spawn-wrap.git" - }, - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "license": "ISC", - "bugs": { - "url": "https://github.com/isaacs/spawn-wrap/issues" - }, - "homepage": "https://github.com/isaacs/spawn-wrap#readme", - "gitHead": "372543dea960b0dddd7cb570913b4a430e0e25d0", - "_id": "spawn-wrap@0.0.9", - "_shasum": "4a8f5f6c76b73569e25f254e5d54df34e8cffeb4", - "_from": "spawn-wrap@*", - "_npmVersion": "2.10.0", - "_nodeVersion": "2.0.1", - "_npmUser": { - "name": "isaacs", - "email": "isaacs@npmjs.com" - }, - "dist": { - "shasum": "4a8f5f6c76b73569e25f254e5d54df34e8cffeb4", - "tarball": "http://registry.npmjs.org/spawn-wrap/-/spawn-wrap-0.0.9.tgz" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "isaacs@npmjs.com" - } - ], - "directories": {}, - "_resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-0.0.9.tgz" -} diff --git a/node_modules/spawn-wrap/t.js b/node_modules/spawn-wrap/t.js deleted file mode 100755 index fa0ce2b7a..000000000 --- a/node_modules/spawn-wrap/t.js +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env node -if (process.env.xyz) { - console.log('in t.js, xyz=%j', process.env.xyz) - console.log('gc is a', typeof gc) - console.log('%j', process.argv) - console.log('about to run the main file\u001b[32m') - require('./index.js').runMain() - console.log('\u001b[31mran wrapped main') - return -} - -var wrap = require('./index.js') - -var unwrap = wrap(['--expose_gc', __filename, ' a $ b '], { xyz: 'ABC' }) - -console.log('about to run child process') -console.log('gc is a', typeof gc) -var cp = require('child_process') -var child = cp.exec(process.execPath + ' $(which tap ) -h', { env: { foo: 'asdf', PATH:process.env.PATH } }, function (er, out, err) { - console.error('returned') - console.error('error = ', er) - console.error('outlen=', out.length) - console.error('\u001b[31m' + out + '\u001b[m') - console.error('errlen=', err.length) - process.stderr.write(err) -}) From b0671ac9b7fec40eabaf02f56cd986b34696d6b7 Mon Sep 17 00:00:00 2001 From: Benjamin Coe Date: Fri, 15 May 2015 08:50:44 -0700 Subject: [PATCH 3/3] run with process.execPath --- test/nyc-test.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/nyc-test.js b/test/nyc-test.js index 0fcd02e08..162c22d32 100644 --- a/test/nyc-test.js +++ b/test/nyc-test.js @@ -65,11 +65,7 @@ describe('nyc', function () { }) function testSignal (signal, done) { - var bin = './bin/nyc.js' - // use node as the bin if we're already wrapped. - if (~process.env._.indexOf('nyc')) bin = 'node' - - var proc = spawn(bin, ['./test/fixtures/' + signal + '.js'], { + var proc = spawn(process.execPath, ['./test/fixtures/' + signal + '.js'], { cwd: process.cwd(), env: process.env, stdio: 'inherit'