You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
2.6 KiB

4 years ago
  1. 'use strict';
  2. /*!
  3. * concatenate dependencies
  4. */
  5. var fs = require('fs')
  6. , globs = require('globs');
  7. /**
  8. * Simple callback generator for `concatenate()`
  9. *
  10. * @api private
  11. * @param {String} file
  12. * @return {Function}
  13. */
  14. function makeCb(file) {
  15. return function (err, data) {
  16. if (err) {
  17. throw err;
  18. }
  19. fs.writeFileSync(file, data);
  20. };
  21. }
  22. /**
  23. * Concatenate files and such. Will maintain order of files.
  24. *
  25. * Examples:
  26. *
  27. * ```js
  28. * // write all logs to `logs.txt`
  29. * concatenate([ '*.txt', '*.log' ], 'logs.txt');
  30. *
  31. * // output the contents of all local javascript files
  32. * concatenate('*.js', function (err, js) {
  33. * if (err) throw err;
  34. *
  35. * console.log(js);
  36. * });
  37. * ```
  38. *
  39. * @api public
  40. * @param {String|Array} patterns Files/wildcard patterns to concatenate
  41. * @param {String|Function} cb File to write or callback
  42. */
  43. var concatenate = module.exports = function (patterns, cb) {
  44. // concatenate('*.txt', function () { ... })
  45. if (!Array.isArray(patterns)) {
  46. patterns = [ patterns ];
  47. }
  48. // concatenate([ '*.txt' ], 'all-text.js')
  49. if (typeof cb === 'string') {
  50. cb = makeCb(cb);
  51. }
  52. globs(patterns, function (err, files) {
  53. if (err) {
  54. return cb(err);
  55. }
  56. var done = false
  57. , res = [];
  58. /**
  59. * Add the `file` at the `index` to the stack
  60. *
  61. * Will add the next `file` at `index++`, or fire
  62. * `cb` if there is not another `file`.
  63. *
  64. * This is rather ugly, but maintains order
  65. * of the provided files.
  66. *
  67. * @api private
  68. * @param {Number} index
  69. */
  70. function add(index) {
  71. var file = files[index];
  72. if (!file) {
  73. done = true;
  74. return cb(new Error('Invalid file "' + file + '"'));
  75. }
  76. fs.readFile(files[index], 'utf-8', function (err, data) {
  77. if (done) { return; }
  78. if (err) {
  79. done = true;
  80. return cb(err);
  81. }
  82. res.push(data);
  83. index++;
  84. if (!files[index]) {
  85. done = true;
  86. cb(null, res.join('\n'));
  87. } else {
  88. add(index);
  89. }
  90. });
  91. }
  92. // start the loop by adding the first file
  93. add(0);
  94. });
  95. };
  96. /**
  97. * Synchronously concatenate files and such
  98. *
  99. * @api public
  100. * @param {String|Array} patterns
  101. * @param {String} [out] Output file
  102. */
  103. concatenate.sync = function (patterns, out) {
  104. var index
  105. , files = globs.sync(patterns)
  106. , length = files.length
  107. , all = [];
  108. for (index = 0; index < length; index++) {
  109. all.push(fs.readFileSync(files[index], 'utf-8'));
  110. }
  111. all = all.join('\n');
  112. if (out) {
  113. // write file
  114. fs.writeFileSync(out, all);
  115. }
  116. // return concatenated stuff
  117. return all;
  118. };