-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwalkup.coffee
60 lines (47 loc) · 1.32 KB
/
walkup.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
path = require( 'path' )
fs = require( 'fs' )
glob = require "glob"
_ = require "underscore"
EventEmitter = require( "events" ).EventEmitter
Q = require 'q'
class WalkUp extends EventEmitter
Object.defineProperty @prototype, 'done',
get : -> @defer.promise
constructor : ( @pattern, @opts, @cb ) ->
@results = []
@defer = Q.defer()
@walk @opts.cwd
walk : ( dir ) =>
return @onDone() if @aborted or !_.isString dir
opts = _.extend {}, @opts, cwd : dir, noglobstar : true, matchBase : false, nonull : false
glob @pattern, opts, @visitor( dir )
visitor : ( dir ) => ( err, files ) =>
return @onError err if err?
@onMatch dir, files if files? && !_.isEmpty files
parent = path.dirname dir
if parent in [ "", path.sep, "." ] or (@results.length >= @opts.maxResults)
@onDone()
else
@walk parent
onMatch : ( dir, files ) =>
res =
dir : dir
files : files
@results.push res
@emit "match", res
onError : ( err ) =>
return if @aborted
@emit "error", err
@cb err if @cb?
@defer.reject err
onDone : =>
return if @aborted
@emit "end"
@cb null, @results if @cb?
@defer.resolve @results
abort : =>
glob.abort()
@aborted = true
@emit "aborted"
@defer.reject new Error "aborted by user"
module.exports = WalkUp