├── .gitignore ├── README.md ├── package.json ├── run-npm.js ├── run-para.js ├── run.js ├── src ├── api.coffee └── cli.coffee └── test ├── api.coffee ├── cache.json ├── cli.coffee └── snapy.config.coffee /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | shrinkwrap.yaml 4 | lib/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Script runner 2 | 3 | Invoke multiple commands, running in parallel / sequential, matching npm scripts 4 | 5 | ### Install 6 | 7 | ```bash 8 | npm install --save-dev script-runner 9 | ``` 10 | 11 | ### Usage 12 | 13 | ``` 14 | usage: run [ [cmd..]..] 15 | 16 | 17 | options: 18 | -h, --help output usage information 19 | -v, --verbose verbose logging (not implemented yet) 20 | --silent suppress output of children 21 | --no-errors also suppress error-output of children 22 | -t, --test no running only show process structure 23 | -s, --sequential following cmds will be run in sequence 24 | -p, --parallel following cmds will be run in parallel 25 | -i, --ignore the following cmd will be ignored for --first, --wait and errors 26 | -f, --first only in parallel block: close all sibling processes after first exits 27 | -w, --wait only in parallel block: will not close sibling processes on error 28 | -m, --master only in parallel block: close all sibling processes when the following cmd exits. exitCode will only depend on master 29 | 30 | run also looks in node_modules/.bin for cmds 31 | run-para is a shorthand for run --parallel 32 | run-seq is a longhand for run 33 | run-npm will match cmd with npm script and replace them, usage of globs is allowed 34 | e.g. 35 | run-npm -p build:* -s deploy 36 | ``` 37 | 38 | ### Examples 39 | 40 | ```bash 41 | run "echo 1" "echo 2" 42 | run-para "echo 1" "echo 2" 43 | run-npm build:* 44 | run mocha 45 | run-npm -p serve --master "run-npm 'sleep 1' test:e2e" 46 | ``` 47 | 48 | ```json 49 | // package.json 50 | "scripts": { 51 | ... 52 | "build": "run-npm build:*", 53 | "build:step1": "do something", 54 | "build:step2": "do another thing" 55 | ... 56 | } 57 | ``` 58 | 59 | 60 | ## License 61 | Copyright (c) 2016 Paul Pflugradt 62 | Licensed under the MIT license. 63 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "script-runner", 3 | "version": "0.1.8", 4 | "description": "Invoke multiple commands, running in parallel / sequential, matching npm scripts", 5 | "homepage": "https://github.com/paulpflug", 6 | "author": { 7 | "name": "Paul Pflugradt", 8 | "email": "paul.pflugradt@gmail.com" 9 | }, 10 | "license": "MIT", 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/paulpflug/script-runner" 14 | }, 15 | "main": "lib/index.js", 16 | "bin": { 17 | "run": "./run.js", 18 | "run-seq": "./run.js", 19 | "run-para": "./run-para.js", 20 | "run-npm": "./run-npm.js" 21 | }, 22 | "files": [ 23 | "*.js", 24 | "lib/*.js" 25 | ], 26 | "keywords": [ 27 | "parallel", 28 | "sequential", 29 | "npm script", 30 | "shell" 31 | ], 32 | "dependencies": { 33 | "better-spawn": "^1.0.4", 34 | "minimatch": "^3.0.4", 35 | "yaku": "^0.18.6" 36 | }, 37 | "devDependencies": { 38 | "coffeescript": "^2.3.1", 39 | "snapy": "^0.1.6", 40 | "coffee-loader": "^0.9.0" 41 | }, 42 | "scripts": { 43 | "build": "coffee --no-header --compile --output lib/ src/*.coffee", 44 | "test": "snapy", 45 | "test2": "nothing here 2", 46 | "test:2": "nothingHere2", 47 | "test:3": "nothingHere3", 48 | "watch": "snapy --watch", 49 | "preversion": "npm test", 50 | "version": "npm run build && git add .", 51 | "postversion": "git push && git push --tags && npm publish" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /run-npm.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var pkg = require(process.cwd() + "/package.json") 3 | var minimatch = require("minimatch") 4 | 5 | var i, j, len, len2, identifier = [], args = process.argv.slice(2); 6 | 7 | if (pkg.scripts) { 8 | var scripts = Object.keys(pkg.scripts) 9 | for (i = 0, len = scripts.length; i < len; i++) { 10 | identifier.push(scripts[i].replace(":", "/")) 11 | } 12 | for (i = 0, len = args.length; i < len; i++) { 13 | if (args[i][0] != '-') { 14 | cmd = args[i].replace(":", "/") 15 | var matched = [] 16 | for (j = 0, len2 = identifier.length; j < len2; j++) { 17 | if (minimatch(identifier[j], cmd)) { 18 | matched.push(pkg.scripts[scripts[j]]) 19 | } 20 | } 21 | if (matched.length) { 22 | args.splice(i, 1, matched) 23 | len = args.length 24 | i += matched.length - 1 25 | } 26 | } 27 | } 28 | } 29 | 30 | try { 31 | require("coffeescript/register") 32 | require("./src/cli.coffee")(args) 33 | } catch (e) { 34 | if (e.code == "MODULE_NOT_FOUND") { 35 | require("./lib/cli.js")(args) 36 | } else { 37 | console.log(e) 38 | } 39 | } -------------------------------------------------------------------------------- /run-para.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var args = process.argv.slice(2) 4 | args.unshift("-p") 5 | try { 6 | require("coffeescript/register") 7 | require("./src/cli.coffee")(args) 8 | } catch (e) { 9 | if (e.code == "MODULE_NOT_FOUND") { 10 | require("./lib/cli.js")(args) 11 | } else { 12 | console.log(e) 13 | } 14 | } -------------------------------------------------------------------------------- /run.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var args 4 | args = process.argv.slice(2) 5 | 6 | try { 7 | require("coffeescript/register") 8 | require("./src/cli.coffee")(args) 9 | } catch (e) { 10 | if (e.code == "MODULE_NOT_FOUND") { 11 | require("./lib/cli.js")(args) 12 | } else { 13 | console.log(e) 14 | } 15 | } -------------------------------------------------------------------------------- /src/api.coffee: -------------------------------------------------------------------------------- 1 | 2 | module.exports = (cmdGroups, options, cb) => 3 | betterSpawn = require "better-spawn" 4 | Promise = options.Promise or require "yaku" 5 | 6 | allChildren = [] 7 | 8 | running = true 9 | _exitCode = 0 10 | 11 | _close = (children) => 12 | closed = [] 13 | for child in children 14 | closed.push child.close() 15 | return Promise.all(closed).then => 1 16 | 17 | closeGroup = (group) => 18 | if group and not group.closed 19 | group.closed = true 20 | _close group.units.map (unit) => unit.child 21 | return Promise.resolve() 22 | 23 | close = => 24 | if running = true 25 | running = false 26 | return _close(allChildren) 27 | return Promise.resolve(_exitCode) 28 | 29 | spawn = (unit, group, exitCode) => 30 | if running 31 | if group and unit.master 32 | group.wait = true 33 | allChildren.push child = unit.child = betterSpawn(unit.cmd, noOut: options.silent, noErr: options.noErr) 34 | if unit.timeout 35 | setTimeout child.close, unit.timeout 36 | return child.closed.then (child) => 37 | unless unit.ignore 38 | if child.exitCode 39 | if group and not group.closed 40 | await closeGroup(group) unless group.wait 41 | else 42 | await close() 43 | return child.exitCode 44 | else 45 | if group and not group.closed 46 | if group.first or unit.master 47 | unit.master = true 48 | await closeGroup(group) 49 | return 0 50 | return Promise.resolve(exitCode) 51 | 52 | 53 | 54 | done = cmdGroups.reduce(((acc, cur) => 55 | return acc.then (exitCode) => 56 | return Promise.resolve(exitCode) if exitCode 57 | if cur.parallel 58 | return Promise.all(cur.units.map((unit) => spawn(unit, cur, exitCode))) 59 | .then (exitCodes) => 60 | for unit,i in cur.units 61 | if unit.master 62 | await close() if exitCodes[i] 63 | return exitCodes[i] 64 | for exitCode in exitCodes 65 | if exitCode 66 | await close() 67 | return exitCode 68 | return 0 69 | else 70 | return cur.units.reduce ((acc2, cur2) => 71 | return acc2.then (exitCode) => spawn cur2, null, exitCode 72 | ), Promise.resolve(0) 73 | ), Promise.resolve(0) 74 | ).then (exitCode) => 75 | cb?(exitCode) 76 | return _exitCode = exitCode 77 | .catch (e) => 78 | console.log e 79 | 80 | return close: close, done: done 81 | -------------------------------------------------------------------------------- /src/cli.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (args, test) -> 2 | options = {} 3 | unit = {} 4 | cmdGroup = parallel: false, units: [] 5 | cmdGroups = [] 6 | for arg in args 7 | if arg[0] == "-" 8 | switch arg 9 | when "-s", "--sequential" 10 | cmdGroups.push cmdGroup if cmdGroup.units.length 11 | cmdGroup = parallel: false, units: [] 12 | when "-p", "--parallel" 13 | cmdGroups.push cmdGroup if cmdGroup.units.length 14 | cmdGroup = parallel: true, units: [] 15 | when "-w", "--wait" 16 | cmdGroup.wait = true 17 | when "-f", "--first" 18 | cmdGroup.first = true 19 | when "-m", "--master" 20 | unit.master = true 21 | when "-i", "--ignore" 22 | unit.ignore = true 23 | when "-v", "--verbose" 24 | options.verbose = true 25 | when "--silent" 26 | options.silent = true 27 | when "--no-errors" 28 | options.noErr = true 29 | when "-t", "--test" 30 | options.test = true 31 | when "-h", "--help" 32 | console.log """ 33 | usage: run [ [cmd..]..] 34 | 35 | 36 | options: 37 | -h, --help output usage information 38 | -v, --verbose verbose logging (not implemented yet) 39 | --silent suppress output of children 40 | --no-errors also suppress error-output of children 41 | -t, --test no running only show process structure 42 | -s, --sequential following cmds will be run in sequence 43 | -p, --parallel following cmds will be run in parallel 44 | -i, --ignore the following cmd will be ignored for --first, --wait and errors 45 | -f, --first only in parallel block: close all sibling processes after first exits 46 | -w, --wait only in parallel block: will not close sibling processes on error 47 | -m, --master only in parallel block: close all sibling processes when the following cmd exits. exitCode will only depend on master 48 | 49 | run also looks in node_modules/.bin for cmds 50 | run-para is a shorthand for run --parallel 51 | run-seq is a longhand for run 52 | run-npm will match cmd with npm script and replace them, usage of globs is allowed 53 | e.g. 54 | run-npm -p build:* -s deploy 55 | """ 56 | process.exit() 57 | else 58 | unit.cmd = arg 59 | cmdGroup.units.push unit 60 | unit = {} 61 | 62 | cmdGroup.units.push unit if unit.cmd 63 | 64 | cmdGroups.push cmdGroup if cmdGroup.units.length 65 | if options.test 66 | return cmdGroups if test 67 | return console.log(JSON.stringify(cmdGroups)) 68 | {close} = require("./api")(cmdGroups, options, process.exit) 69 | process.on "SIGTERM", => close "SIGTERM" 70 | process.on "SIGINT", => close "SIGINT" 71 | process.on "SIGHUP", => close "SIGHUP" 72 | 73 | -------------------------------------------------------------------------------- /test/api.coffee: -------------------------------------------------------------------------------- 1 | {test} = require "snapy" 2 | 3 | api = require "../src/api.coffee" 4 | 5 | waitingProcess = (time=10000) => "node -e 'setTimeout(function(){console.log(\"waiting #{time}\")},#{time});'" 6 | failingProcess = "node -e 'throw new Error();'" 7 | options = silent: false, noErr: false 8 | 9 | test (snap) => 10 | # success in sequenz 11 | {done} = api [{parallel:false, units: [{cmd:waitingProcess(10)}]}],options 12 | snap promise: done 13 | # success in parallel 14 | {done} = api [{parallel:true, units: [{cmd:waitingProcess(10)}]}],options 15 | snap promise: done 16 | 17 | test (snap) => 18 | # fail in sequenz 19 | {done} = api [{parallel:false, units: [{cmd:failingProcess}]}],options 20 | snap promise: done 21 | # fail in parallel 22 | {done} = api [{parallel:true, units: [{cmd:failingProcess}]}],options 23 | snap promise: done 24 | 25 | test (snap) => 26 | # fail in sequenz with multiple processes 27 | {done} = api [{parallel:false, units: [{cmd:failingProcess},{cmd:waitingProcess()}]}],options 28 | snap promise: done 29 | # fail in parallel with multiple processes 30 | {done} = api [{parallel:true, units: [{cmd:waitingProcess()},{cmd:failingProcess}]}],options 31 | snap promise: done 32 | 33 | test (snap) => 34 | # should fail because it is still running with multiple process groups 35 | {close} = api [ 36 | { 37 | parallel:false 38 | units: [{cmd:waitingProcess(50)}] 39 | },{ 40 | parallel:false 41 | units: [{cmd:waitingProcess(50)}] 42 | } 43 | ],options 44 | setTimeout (=>snap promise: close()),80 45 | # should fail because it is still running with multiple process groups 46 | {close} = api [ 47 | { 48 | parallel:true 49 | units: [{cmd:waitingProcess(50)}] 50 | },{ 51 | parallel:true 52 | units: [{cmd:waitingProcess(50)}] 53 | } 54 | ],options 55 | setTimeout (=>snap promise: close()),80 56 | 57 | test (snap) => 58 | # fail in sequenz with multiple process groups 59 | {done} = api [ 60 | { 61 | parallel:false 62 | units: [{cmd:failingProcess}] 63 | },{ 64 | parallel:false 65 | units: [{cmd:waitingProcess()}] 66 | } 67 | ],options 68 | snap promise: done 69 | # fail in parallel with multiple process groups 70 | {done} = api [ 71 | { 72 | parallel:true 73 | units: [{cmd:failingProcess}] 74 | },{ 75 | parallel:false 76 | units: [{cmd:waitingProcess()}] 77 | } 78 | ],options 79 | snap promise: done 80 | 81 | test (snap) => 82 | # exitcode 0 with ignore 83 | {done} = api [{parallel:false, units: [{cmd:failingProcess,ignore:true},{cmd:waitingProcess(10)}]}],options 84 | snap promise: done 85 | # exitcode 0 with ignore in parellel 86 | {done} = api [{parallel:true, units: [{cmd:failingProcess,ignore:true},{cmd:waitingProcess(10)}]}],options 87 | snap promise: done 88 | 89 | test (snap) => 90 | # first should work successful 91 | {done} = api [{parallel:true,first:true, units: [{cmd:waitingProcess()},{cmd:waitingProcess(10)}]}],options 92 | snap promise: done 93 | 94 | # first should respekt ignore and be still running while closing 95 | {close} = api [{parallel:true,first:true, units: [{cmd:waitingProcess()},{cmd:waitingProcess(10),ignore:true}]}],options 96 | 97 | setTimeout (=>snap promise: close()),50 98 | 99 | test (snap) => 100 | # wait should keep process running 101 | {close} = api [{parallel:true,wait:true, units: [{cmd:failingProcess},{cmd:waitingProcess(100)}]}],options 102 | setTimeout (=>snap promise: close()),50 103 | 104 | test (snap) => 105 | # master should rule exitcode successful 106 | {done} = api [{parallel:true, units: [{cmd:failingProcess},{cmd:waitingProcess(10),master:true}]}],options 107 | snap promise: done 108 | # master should kill siblings, but return successful 109 | {done} = api [{parallel:true, units: [{cmd:waitingProcess()},{cmd:waitingProcess(10),master:true}]}],options 110 | snap promise: done 111 | 112 | -------------------------------------------------------------------------------- /test/cache.json: -------------------------------------------------------------------------------- 1 | {"chunks":{"set":true,"value":{"api.coffee":"ab65ccd8d1220f06bf2b8cbb3516988b","cli.coffee":"da6979cf40880b1039c26a1fa305809a"}},"9416f0436b293e1ba890e54b2c6bf9ae0":{"set":true,"value":{"resolved":1}},"9416f0436b293e1ba890e54b2c6bf9ae1":{"set":true,"value":{"resolved":0}},"e443757a5a204a2c5a2769bece98e23c0":{"set":true,"value":{"resolved":0}},"d7217b71f33fe4a31cfe3062c86de4240":{"set":true,"value":{"resolved":1}},"b13e0022459b3411fa20b4ad76cb33410":{"set":true,"value":{"resolved":1}},"5c9f30ecfe980703e94aeda4ed9336981":{"set":true,"value":{"resolved":0}},"5c9f30ecfe980703e94aeda4ed9336980":{"set":true,"value":{"resolved":0}},"aed18e4f06754ab58884c3804365ec731":{"set":true,"value":{"resolved":1}},"aed18e4f06754ab58884c3804365ec730":{"set":true,"value":{"resolved":1}},"ace0aa1ff557e29b161880b90a71a5620":{"set":true,"value":{"resolved":0}},"ace0aa1ff557e29b161880b90a71a5621":{"set":true,"value":{"resolved":0}},"11c5754590a6293e61bf6e2199f513980":{"set":true,"value":{"resolved":1}},"11c5754590a6293e61bf6e2199f513981":{"set":true,"value":{"resolved":1}},"e443757a5a204a2c5a2769bece98e23c1":{"set":true,"value":{"resolved":0}},"d7217b71f33fe4a31cfe3062c86de4241":{"set":true,"value":{"resolved":1}},"c188fd9d4449151de6e4c714210c831d0":{"set":true,"value":{"resolved":1}},"c188fd9d4449151de6e4c714210c831d1":{"set":true,"value":{"resolved":1}},"2ce6172e491ffa25bcafa3828a0cbcd50":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"},{"cmd":"cmd2"}]}]},"a68d6d4900de03cb7e015bb082b3da8c0":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}]}]},"e19e3e35bce5ea59de2df6db8062969e1":{"set":true,"value":[{"parallel":true,"units":[{"cmd":"cmd1"}]}]},"e19e3e35bce5ea59de2df6db8062969e0":{"set":true,"value":[{"parallel":true,"units":[{"cmd":"cmd1"}]}]},"e7d7c82cb9ffebc6ebf21535ca740c8b1":{"set":true,"value":[]},"e7d7c82cb9ffebc6ebf21535ca740c8b0":{"set":true,"value":[]},"729078455dcee5259f210477d0116c011":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}]}]},"729078455dcee5259f210477d0116c010":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}]}]},"52ecdfb81f34926e16270c70fe65471b0":{"set":true,"value":[{"parallel":true,"units":[{"cmd":"cmd2"}]},{"parallel":false,"units":[{"cmd":"cmd1"}]}]},"d132471adb751c04172c1f72e41f07071":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}],"wait":true}]},"d132471adb751c04172c1f72e41f07070":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}],"wait":true}]},"080f0827bae79cb954bef757f532f0910":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"'test 1'"}]}]},"c0649e806c608fd42107c84cd69ab09c1":{"set":true,"value":[{"parallel":false,"units":[{"master":true,"cmd":"cmd1"}]}]},"c0649e806c608fd42107c84cd69ab09c0":{"set":true,"value":[{"parallel":false,"units":[{"master":true,"cmd":"cmd1"}]}]},"7e917108565d8df58428d0b316ec7e951":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}],"first":true}]},"7e917108565d8df58428d0b316ec7e950":{"set":true,"value":[{"parallel":false,"units":[{"cmd":"cmd1"}],"first":true}]},"624a9083aef90967678e2f654365da241":{"set":true,"value":[{"parallel":false,"units":[{"ignore":true,"cmd":"cmd1"}]}]},"624a9083aef90967678e2f654365da240":{"set":true,"value":[{"parallel":false,"units":[{"ignore":true,"cmd":"cmd1"}]}]},"ff22030f9da371391eac0da2452fe9c12":{"set":true,"value":"[]"},"ff22030f9da371391eac0da2452fe9c11":{"set":true,"value":"[{\"parallel\":true,\"units\":[{\"cmd\":\"cmd1\"}]}]"},"ff22030f9da371391eac0da2452fe9c10":{"set":true,"value":"[{\"parallel\":true,\"units\":[{\"cmd\":\"cmd 1\"}]}]"},"ce021613b0c7340d1082da34a9ce550c0":{"set":true,"value":"[{\"parallel\":false,\"units\":[{\"cmd\":\"cmd1\"}]}]"},"ce021613b0c7340d1082da34a9ce550c1":{"set":true,"value":"[]"},"1d7667036022cc356e2b2ec562324a400":{"set":true,"value":"[{\"parallel\":true,\"units\":[{\"cmd\":[\"nothingHere2\",\"nothingHere3\"]}]},{\"parallel\":false,\"units\":[{\"cmd\":[\"nothing here 2\"]}]}]"},"1d7667036022cc356e2b2ec562324a402":{"set":true,"value":"[]"},"1d7667036022cc356e2b2ec562324a401":{"set":true,"value":"[{\"parallel\":false,\"units\":[{\"cmd\":[\"snapy\"]}]}]"},"ce54311d77b107940450e405772b5e030":{"set":true,"value":"test"},"c42b2fbfc7c07512cad3c2439e81b7260":{"set":true,"value":{"resolved.isClosed":true,"resolved.isKilled":true}},"6cdcaa9411af07070fa6f345cdf1999c2":{"set":true,"value":{"resolved.isClosed":true,"resolved.isKilled":true}},"6cdcaa9411af07070fa6f345cdf1999c1":{"set":true,"value":{"resolved.isClosed":true,"resolved.isKilled":true}},"6cdcaa9411af07070fa6f345cdf1999c0":{"set":true,"value":{"resolved.isClosed":true,"resolved.isKilled":true}}} 2 | -------------------------------------------------------------------------------- /test/cli.coffee: -------------------------------------------------------------------------------- 1 | {test} = require "snapy" 2 | spawn = require("better-spawn") 3 | 4 | 5 | cli = require "../src/cli.coffee" 6 | 7 | getStream = (cmd) => 8 | child = spawn cmd, stdio:"pipe" 9 | return child.stdout 10 | 11 | test (snap) => 12 | snap obj: cli ["--test"], true 13 | snap obj: cli ["-t"], true 14 | 15 | test (snap) => 16 | snap obj: cli ["--test", "cmd1"], true 17 | 18 | test (snap) => 19 | snap obj: cli ["--test", "cmd1", "cmd2"], true 20 | 21 | test (snap) => 22 | snap obj: cli ["--test", "--parallel","cmd1"], true 23 | snap obj: cli ["--test", "-p","cmd1"], true 24 | 25 | test (snap) => 26 | snap obj: cli ["--test", "--sequential","cmd1"], true 27 | snap obj: cli ["--test", "-s","cmd1"], true 28 | 29 | test (snap) => 30 | snap obj: cli ["--test", "-p","cmd2","-s","cmd1"], true 31 | 32 | test (snap) => 33 | snap obj: cli ["--test", "--wait","cmd1"], true 34 | snap obj: cli ["--test", "-w","cmd1"], true 35 | 36 | test (snap) => 37 | snap obj: cli ["--test", "--first","cmd1"], true 38 | snap obj: cli ["--test", "-f","cmd1"], true 39 | 40 | test (snap) => 41 | snap obj: cli ["--test", "--master","cmd1"], true 42 | snap obj: cli ["--test", "-m","cmd1"], true 43 | 44 | test (snap) => 45 | snap obj: cli ["--test", "--ignore","cmd1"], true 46 | snap obj: cli ["--test", "-i","cmd1"], true 47 | 48 | test (snap) => 49 | snap obj: cli ["--test", "'test 1'"], true 50 | 51 | test (snap) => 52 | snap stream: getStream "./run.js --test" 53 | snap stream: getStream "./run.js --test cmd1" 54 | 55 | test (snap) => 56 | snap stream: getStream "./run-para.js --test" 57 | snap stream: getStream "./run-para.js --test cmd1" 58 | snap stream: getStream "./run-para.js --test 'cmd 1'" 59 | 60 | test (snap) => 61 | snap stream: getStream "./run-npm.js --test" 62 | snap stream: getStream "./run-npm.js --test test" 63 | snap stream: getStream "./run-npm.js --test -p test:* -s test2" 64 | 65 | test (snap) => 66 | snap stream: getStream "./run.js 'echo 'test''" 67 | 68 | filter = ["resolved.isClosed","resolved.isKilled"] 69 | 70 | test (snap) => 71 | child = spawn "./run.js 'sleep 5'" 72 | snap promise: child.close(), filter: filter 73 | child = spawn "./run.js 'sleep 5'" 74 | snap promise: child.close("SIGHUP"), filter: filter 75 | child = spawn "./run.js 'sleep 5'" 76 | snap promise: child.close("SIGINT"), filter: filter 77 | 78 | 79 | test (snap) => 80 | child = spawn "./run.js -p 'sleep 5' 'sleep 5'" 81 | snap promise: child.close(), filter: filter -------------------------------------------------------------------------------- /test/snapy.config.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | directOutput: false --------------------------------------------------------------------------------