1 | var assert = require('assert')
|
2 | var fs = require('fs')
|
3 | var path = require('path')
|
4 | var Readable = require('stream').Readable
|
5 | var util = require('util')
|
6 | var assign = require('./assign')
|
7 |
|
8 | function Walker (dir, options) {
|
9 | assert.strictEqual(typeof dir, 'string', '`dir` parameter should be of type string. Got type: ' + typeof dir)
|
10 | var defaultStreamOptions = { objectMode: true }
|
11 | var defaultOpts = { queueMethod: 'shift', pathSorter: undefined }
|
12 | options = assign(defaultOpts, options, defaultStreamOptions)
|
13 |
|
14 | Readable.call(this, options)
|
15 | this.root = path.resolve(dir)
|
16 | this.paths = [this.root]
|
17 | this.options = options
|
18 | this.fs = options.fs || fs
|
19 | }
|
20 | util.inherits(Walker, Readable)
|
21 |
|
22 | Walker.prototype._read = function () {
|
23 | if (this.paths.length === 0) return this.push(null)
|
24 | var self = this
|
25 | var pathItem = this.paths[this.options.queueMethod]()
|
26 |
|
27 | self.fs.lstat(pathItem, function (err, stats) {
|
28 | var item = { path: pathItem, stats: stats }
|
29 | if (err) return self.emit('error', err, item)
|
30 | if (!stats.isDirectory()) return self.push(item)
|
31 |
|
32 | self.fs.readdir(pathItem, function (err, pathItems) {
|
33 | if (err) {
|
34 | self.push(item)
|
35 | return self.emit('error', err, item)
|
36 | }
|
37 |
|
38 | pathItems = pathItems.map(function (part) { return path.join(pathItem, part) })
|
39 | if (self.options.pathSorter) pathItems.sort(self.options.pathSorter)
|
40 | pathItems.forEach(function (pi) { self.paths.push(pi) })
|
41 |
|
42 | self.push(item)
|
43 | })
|
44 | })
|
45 | }
|
46 |
|
47 | function walk (root, options) {
|
48 | return new Walker(root, options)
|
49 | }
|
50 |
|
51 | module.exports = walk
|