catFile.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. 'use strict';
  2. /**
  3. * catFile
  4. * @module gulp-git/lib/catFile
  5. */
  6. var through = require('through2');
  7. var PluginError = require('plugin-error');
  8. var spawn = require('child_process').spawn;
  9. var stripBom = require('strip-bom-stream');
  10. /**
  11. * get a buffer.
  12. * @callback requestCallback
  13. * @param {buffer} buf
  14. */
  15. /**
  16. * Convert stream to buffer
  17. *
  18. * @param {Stream} stream stream that what to read
  19. * @param {readStreamCallback} callback function that receive buffer
  20. * @returns {void}
  21. */
  22. function readStream(stream, callback) {
  23. var buf;
  24. stream.on('data', function(data) {
  25. if (buf) {
  26. buf = Buffer.concat([buf, data]);
  27. } else {
  28. buf = data;
  29. }
  30. });
  31. stream.once('finish', function() {
  32. if (buf) {
  33. callback(buf);
  34. }
  35. });
  36. }
  37. /**
  38. * @typedef {object} catFileOptions
  39. * @property {boolean} stripBOM {@link https://github.com/gulpjs/vinyl-fs#optionsstripbom}
  40. * @property {boolean} buffer {@link https://github.com/gulpjs/vinyl-fs#optionsbuffer}
  41. */
  42. /**
  43. * read vinyl file contents
  44. * @param {catFileOptions} opt [catFileOptions]{@link module:gulp-git/lib/catFile~catFileOptions}
  45. * @returns {stream} stream of vinyl `File` objects.
  46. */
  47. module.exports = function (opt) {
  48. if (!opt) opt = {};
  49. if (undefined === opt.stripBOM || null === opt.stripBOM) opt.stripBOM = true;
  50. if (undefined === opt.buffer || null === opt.buffer) opt.buffer = true;
  51. /**
  52. * transform function of stream {@link https://nodejs.org/docs/latest/api/stream.html#stream_transform_transform_chunk_encoding_callback}
  53. *
  54. * @param {vinyl} file The file to be transformed.
  55. * @param {any} enc encoding type.
  56. * @param {function} cb A callback function (optionally with an error argument and data) to be called after the supplied `file` has been processed.
  57. * @returns {void}
  58. */
  59. var write = function(file, enc, cb) {
  60. var hash = file.git && file.git.hash;
  61. /**
  62. * set file contents and send file to stream
  63. *
  64. * @param {Buffer} contents file contents
  65. * @returns {void}
  66. */
  67. var sendFile = function(contents) {
  68. if (contents) {
  69. file.contents = contents;
  70. }
  71. return cb(null, file);
  72. };
  73. if (!hash || /^0+$/.test(hash)) {
  74. return sendFile();
  75. }
  76. var catFile = spawn('git', ['cat-file', 'blob', hash], {
  77. cwd: file.cwd
  78. });
  79. var contents = catFile.stdout;
  80. var that = this;
  81. readStream(catFile.stderr, function(error) {
  82. that.emit('error', new PluginError('gulp-git', 'Command failed: ' + catFile.spawnargs.join(' ').trim() + '\n' + error.toString()));
  83. });
  84. if (opt.stripBOM) {
  85. contents = contents.pipe(stripBom());
  86. }
  87. if (opt.buffer) {
  88. readStream(contents, sendFile);
  89. } else {
  90. sendFile(contents);
  91. }
  92. };
  93. var stream = through.obj(write);
  94. return stream;
  95. };