collectable.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. var fs = require('fs');
  2. // Collectable Mixin
  3. //
  4. // Provides utility methods to read from stdin and remaining arguments.
  5. var collectable = module.exports;
  6. // XXX: tomdocify, generate in readme
  7. collectable.stdin = function stdin(force, done) {
  8. if(!done) done = force, force = false;
  9. var argv = this.nopt.argv;
  10. var self = this;
  11. done = done || function(err) { err && self.emit('error', err); };
  12. this._readFromStdin = true;
  13. // not parsed, register done to be read when parse is called
  14. if(!argv) {
  15. this.once('stdin', done);
  16. return this;
  17. }
  18. // only read from stdin when no reamining args and not forced
  19. if(!argv.remain.length || force) {
  20. this.readStdin(done);
  21. }
  22. return this;
  23. };
  24. // Read files from remaining args, concat the result and call back the `done`
  25. // function with the concatanated result and the list of files.
  26. collectable.files = function files(done) {
  27. var argv = this.nopt.argv;
  28. var self = this;
  29. done = done || function(err) { err && self.emit('error', err); };
  30. // not parsed, register done to be read when parse is called
  31. if(!argv) {
  32. this.once('files', done);
  33. return this;
  34. }
  35. // only read files when we actually have files to read from
  36. if(argv.remain.length) {
  37. this.readFiles(argv.remain, done);
  38. }
  39. return this;
  40. };
  41. collectable.readStdin = function readStdin(done) {
  42. var data = '';
  43. var self = this;
  44. process.stdin.setEncoding('utf8');
  45. process.stdin.on('error', done);
  46. process.stdin.on('data', function(chunk){
  47. data += chunk;
  48. self.emit('stdin:data', chunk);
  49. }).on('end', function(){
  50. self.emit('stdin', null, data);
  51. done(null, data);
  52. }).resume();
  53. return this;
  54. };
  55. // Asynchronous walk of the remaining args, reading the content and returns
  56. // the concatanated result.
  57. collectable.readFiles = function readFiles(filepaths, done) {
  58. var data = '';
  59. var self = this;
  60. var files = filepaths.slice(0);
  61. (function read(file) {
  62. if(!file) {
  63. self.emit('files', null, data, filepaths);
  64. return done(null, data, filepaths);
  65. }
  66. fs.readFile(file, 'utf8', function(err, body) {
  67. if(err) return done(err);
  68. data += body;
  69. self.emit('files:data', body);
  70. read(files.shift());
  71. });
  72. })(files.shift());
  73. return this;
  74. };
  75. // Collect data either from stdin or the list of remaining args
  76. collectable.collect = function collect(done) {
  77. return this.stdin(done).files(done);
  78. };