walker.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. var fs = require('fs')
  2. var path = require('path')
  3. var Readable = require('stream').Readable
  4. var util = require('util')
  5. var assign = require('../util/assign')
  6. function Walker (dir, filter, streamOptions) {
  7. Readable.call(this, assign({ objectMode: true }, streamOptions))
  8. this.path = path.resolve(dir)
  9. this.filter = filter
  10. this.pending = 0
  11. this.start()
  12. }
  13. util.inherits(Walker, Readable)
  14. Walker.prototype.start = function () {
  15. this.visit(this.path)
  16. return this
  17. }
  18. Walker.prototype.visit = function (item) {
  19. this.pending++
  20. var self = this
  21. fs.lstat(item, function (err, stat) {
  22. if (err) {
  23. self.emit('error', err, {path: item, stat: stat})
  24. return self.finishItem()
  25. }
  26. if (self.filter && !self.filter({path: item, stat: stat})) return self.finishItem()
  27. if (!stat.isDirectory()) {
  28. self.push({ path: item, stat: stat })
  29. return self.finishItem()
  30. }
  31. fs.readdir(item, function (err, items) {
  32. if (err) {
  33. self.emit('error', err, {path: item, stat: stat})
  34. return self.finishItem()
  35. }
  36. self.push({path: item, stat: stat})
  37. items.forEach(function (part) {
  38. self.visit(path.join(item, part))
  39. })
  40. self.finishItem()
  41. })
  42. })
  43. return this
  44. }
  45. Walker.prototype.finishItem = function () {
  46. this.pending -= 1
  47. if (this.pending === 0) this.push(null)
  48. return this
  49. }
  50. Walker.prototype._read = function () { }
  51. module.exports = Walker