• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2
3var Transform = require('stream').Transform
4var crypto = require('crypto')
5var fs = require('graceful-fs')
6
7exports.check = check
8exports.checkSync = checkSync
9exports.get = get
10exports.getSync = getSync
11exports.stream = stream
12
13function check(file, expected, options, cb) {
14  if (typeof options === 'function') {
15    cb = options
16    options = undefined
17  }
18  expected = expected.toLowerCase().trim()
19  get(file, options, function (er, actual) {
20    if (er) {
21      if (er.message) er.message += ' while getting shasum for ' + file
22      return cb(er)
23    }
24    if (actual === expected) return cb(null)
25    cb(new Error(
26        'shasum check failed for ' + file + '\n'
27      + 'Expected: ' + expected + '\n'
28      + 'Actual:   ' + actual))
29  })
30}
31function checkSync(file, expected, options) {
32  expected = expected.toLowerCase().trim()
33  var actual
34  try {
35    actual = getSync(file, options)
36  } catch (er) {
37    if (er.message) er.message += ' while getting shasum for ' + file
38    throw er
39  }
40  if (actual !== expected) {
41    var ex = new Error(
42        'shasum check failed for ' + file + '\n'
43      + 'Expected: ' + expected + '\n'
44      + 'Actual:   ' + actual)
45    throw ex
46  }
47}
48
49
50function get(file, options, cb) {
51  if (typeof options === 'function') {
52    cb = options
53    options = undefined
54  }
55  options = options || {}
56  var algorithm = options.algorithm || 'sha1'
57  var hash = crypto.createHash(algorithm)
58  var source = fs.createReadStream(file)
59  var errState = null
60  source
61    .on('error', function (er) {
62      if (errState) return
63      return cb(errState = er)
64    })
65    .on('data', function (chunk) {
66      if (errState) return
67      hash.update(chunk)
68    })
69    .on('end', function () {
70      if (errState) return
71      var actual = hash.digest("hex").toLowerCase().trim()
72      cb(null, actual)
73    })
74}
75
76function getSync(file, options) {
77  options = options || {}
78  var algorithm = options.algorithm || 'sha1'
79  var hash = crypto.createHash(algorithm)
80  var source = fs.readFileSync(file)
81  hash.update(source)
82  return hash.digest("hex").toLowerCase().trim()
83}
84
85function stream(expected, options) {
86  expected = expected.toLowerCase().trim()
87  options = options || {}
88  var algorithm = options.algorithm || 'sha1'
89  var hash = crypto.createHash(algorithm)
90
91  var stream = new Transform()
92  stream._transform = function (chunk, encoding, callback) {
93    hash.update(chunk)
94    stream.push(chunk)
95    callback()
96  }
97  stream._flush = function (cb) {
98    var actual = hash.digest("hex").toLowerCase().trim()
99    if (actual === expected) return cb(null)
100    cb(new Error(
101        'shasum check failed for:\n'
102      + '  Expected: ' + expected + '\n'
103      + '  Actual:   ' + actual))
104    this.push(null)
105  }
106  return stream
107}