blob_hash.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /** @module */
  2. 'use strict'
  3. const BPromise = require('bluebird')
  4. const fs = BPromise.promisifyAll(require('fs'))
  5. const crypto = require('crypto')
  6. const { pipeline } = require('stream')
  7. const assert = require('./assert')
  8. function getGitBlobHeader(byteLength) {
  9. return 'blob ' + byteLength + '\x00'
  10. }
  11. function getBlobHash(byteLength) {
  12. const hash = crypto.createHash('sha1')
  13. hash.setEncoding('hex')
  14. hash.update(getGitBlobHeader(byteLength))
  15. return hash
  16. }
  17. /**
  18. * Compute the git blob hash for a blob from a readable stream of its content.
  19. *
  20. * @function
  21. * @param {number} byteLength
  22. * @param {stream.Readable} stream
  23. * @return {Promise.<string>} hexadecimal SHA-1 hash
  24. */
  25. exports.fromStream = BPromise.method(
  26. function blobHashFromStream(byteLength, stream) {
  27. assert.integer(byteLength, 'blobHash: bad byteLength')
  28. assert.object(stream, 'blobHash: bad stream')
  29. const hash = getBlobHash(byteLength)
  30. return new BPromise(function (resolve, reject) {
  31. pipeline(stream, hash, function (err) {
  32. if (err) {
  33. reject(err)
  34. } else {
  35. hash.end()
  36. resolve(hash.read())
  37. }
  38. })
  39. })
  40. }
  41. )
  42. /**
  43. * Compute the git blob hash for a blob with the given string content.
  44. *
  45. * @param {string} string
  46. * @return {string} hexadecimal SHA-1 hash
  47. */
  48. exports.fromString = function blobHashFromString(string) {
  49. assert.string(string, 'blobHash: bad string')
  50. const hash = getBlobHash(Buffer.byteLength(string))
  51. hash.update(string, 'utf8')
  52. hash.end()
  53. return hash.read()
  54. }
  55. /**
  56. * Compute the git blob hash for the content of a file
  57. *
  58. * @param {string} filePath
  59. * @return {string} hexadecimal SHA-1 hash
  60. */
  61. exports.fromFile = function blobHashFromFile(pathname) {
  62. assert.string(pathname, 'blobHash: bad pathname')
  63. function getByteLengthOfFile() {
  64. return fs.statAsync(pathname).then(stat => stat.size)
  65. }
  66. const fromStream = this.fromStream
  67. return getByteLengthOfFile(pathname).then(function (byteLength) {
  68. const stream = fs.createReadStream(pathname)
  69. return fromStream(byteLength, stream)
  70. })
  71. }