package/package.json000644 001750 001750 0000001474 12507660670013036 0ustar00000000 000000 { "name": "outpipe", "version": "1.1.1", "description": "write output to a file through shell commands", "main": "index.js", "directories": { "example": "example" }, "dependencies": { "shell-quote": "^1.4.2" }, "devDependencies": { "gaze": "^0.5.1", "minimist": "^1.1.0", "osenv": "^0.1.0", "tape": "^3.5.0", "xtend": "^4.0.0" }, "scripts": { "test": "tape test/*.js" }, "repository": { "type": "git", "url": "git://github.com/substack/outpipe.git" }, "keywords": [ "output", "file", "pipe", "shell", "exec", "spawn", "createWriteStream", "redirect" ], "author": "substack", "license": "MIT", "bugs": { "url": "https://github.com/substack/outpipe/issues" }, "homepage": "https://github.com/substack/outpipe" } package/.npmignore000644 001750 001750 0000000034 12476767421012545 0ustar00000000 000000 example/output node_modules package/LICENSE000644 001750 001750 0000002061 12476764057011557 0ustar00000000 000000 This software is released under the MIT license: 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. package/index.js000644 001750 001750 0000002045 12507660650012206 0ustar00000000 000000 var parse = require('shell-quote').parse; var exec = require('child_process').exec; var path = require('path'); var echo = process.execPath + ' ' + path.join(__dirname, 'bin/echo'); var fs = require('fs'); module.exports = function (str, opts) { var parts = parse(str); for (var i = 0; i < parts.length; i++) { if (parts[i].op) break; } if (i === parts.length) { // no ops var w = fs.createWriteStream(str); w.once('finish', function () { w.emit('exit', 0) }); w.once('error', function (err) { w.emit('exit', 1) }); return w; } else { if (parts[parts.length-1].op === '|') { str += echo; } if (parts[0].op === '|') { str = echo + str; } if (parts[0].op === '>') { str = echo + str; } } var p = exec(str, opts); p.stderr.pipe(process.stderr, { end: false }); p.stdout.pipe(process.stdout, { end: false }); p.once('exit', function (code) { p.stdin.emit('exit', code) }); return p.stdin; }; package/bin/echo.js000755 001750 001750 0000000070 12477014017012560 0ustar00000000 000000 #!/usr/bin/env node process.stdin.pipe(process.stdout); package/example/watch.js000644 001750 001750 0000000577 12476772364013663 0ustar00000000 000000 var outpipe = require('../'); var gaze = require('gaze'); var fs = require('fs'); var minimist = require('minimist'); var argv = minimist(process.argv.slice(2), { alias: { o: 'output' } }); var file = argv._[0]; gaze(file, function (err, w) { w.on('changed', read); }); read(); function read () { var r = fs.createReadStream(file); r.pipe(outpipe(argv.output)); } package/example/input/x.js000644 001750 001750 0000000115 12476770366014147 0ustar00000000 000000 for (var i = 0; i < 100; i++) { var n = 500; console.log('i=', i); } package/example/input/y.js000644 001750 001750 0000000113 12476740365014142 0ustar00000000 000000 (function () { var x = 5; var x = 6; console.log('ogre') })(); package/example/input/z.js000644 001750 001750 0000000073 12476740414014143 0ustar00000000 000000 if (false) console.log('welcome!') console.log('keep out') package/readme.markdown000644 001750 001750 0000005104 12507660712013540 0ustar00000000 000000 # outpipe write output to a file through shell commands # purpose Suppose you have a tool like [watchify](https://npmjs.com/package/watchify) or [factor-bundle](https://npmjs.com/package/factor-bundle) that write to multiple files or write to the same file more than once. If you want to pipe the output of these tools to other programs, such as minification with the `uglify` command, it's very difficult! You might need to use the tool's API or use a separate command to watch for changes to the output files. Ick. You don't get the elegance of something like: ``` sh $ browserify main.js | uglifyjs -cm | gzip > bundle.js.gz ``` Until now! With this library and a hypothetical version of watchify, you could do: ``` sh $ watchify main.js -dv -o 'uglifyjs -cm | gzip > bundle.js.gz' ``` # example Here's a small watcher program that will just copy input files to a destination, but transforms can be applied along the way with shell pipes and redirects. ``` js var outpipe = require('outpipe'); var gaze = require('gaze'); var fs = require('fs'); var minimist = require('minimist'); var argv = minimist(process.argv.slice(2), { alias: { o: 'output' } }); var file = argv._[0]; gaze(file, function (err, w) { w.on('changed', read); }); read(); function read () { var r = fs.createReadStream(file); r.pipe(outpipe(argv.output)); } ``` We can run the program with a single output file: ``` sh $ node watch.js input/x.js -o output/hmm.js ``` which just copies `x.js` to `output/hmm.js` whenever `x.js` changes. We could also run a minification step using the `uglify` command: ``` sh $ node watch.js input/x.js -o 'uglifyjs -cm > output/wow.js' ``` or we can just print the size of the minified and gzipped output to stdout: ``` sh $ node watch.js input/x.js -o 'uglifyjs -cm | gzip | wc -c' 123 ``` or we could write that size to a file: ``` sh $ node watch.js input/x.js -o 'uglifyjs -cm | gzip | wc -c > size.txt' ``` # methods ``` js var outpipe = require('outpipe') ``` ## var w = outpipe(cmd, opts={}) Return a writable stream `w` that will pipe output to the command string `cmd`. If `cmd` has no operators (`|` or `>`), it will write to a file. Otherwise, each command between pipes will be executed and output is written to a file if `>` is given. `opts` can be: * `opts.env` - an object mapping environment variables to their values or a `function (key) {}` that returns the values. stdout and stderr are forwarded to process.stdout and process.stderr if unhandled in the command. # install With [npm](https://npmjs.org) do: ``` npm install outpipe ``` # license MIT package/test/cmd.js000644 001750 001750 0000000754 12476773353012640 0ustar00000000 000000 var outpipe = require('../'); var test = require('tape'); var fs = require('fs'); var path = require('path'); var tmpdir = require('osenv').tmpdir(); test('cmd', function (t) { t.plan(2); var file = path.join(tmpdir, 'outpipe-' + Math.random()); var p = outpipe('wc -c > ' + file); p.end('wow'); p.once('exit', function () { fs.readFile(file, 'utf8', function (err, src) { t.ifError(err); t.equal(src, '3\n'); }); }); }); package/test/outfile.js000644 001750 001750 0000000743 12476773733013544 0ustar00000000 000000 var outpipe = require('../'); var test = require('tape'); var fs = require('fs'); var path = require('path'); var tmpdir = require('osenv').tmpdir(); test('outfile', function (t) { t.plan(2); var file = path.join(tmpdir, 'outpipe-' + Math.random()); var p = outpipe(file); p.end('wow'); p.once('exit', function () { fs.readFile(file, 'utf8', function (err, src) { t.ifError(err); t.equal(src, 'wow'); }); }); });