• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1var fs = require ('graceful-fs')
2var dz = require ('dezalgo')
3var once = require ('once')
4var path = require ('path')
5var debug = require ('debuglog') ('rds')
6
7module . exports = readdir
8readdir.sync = readdirSync
9
10function readdir (dir, cb) {
11  fs . readdir (dir, function (er, kids) {
12    if (er)
13      return cb (er)
14
15    debug ('dir=%j, kids=%j', dir, kids)
16    readScopes (dir, kids, function (er, data) {
17      if (er)
18        return cb (er)
19
20      // Sort for bonus consistency points
21      data = data . sort (function (a, b) {
22        return a > b ? 1 : -1
23      })
24
25      return cb (null, data)
26    })
27  })
28}
29
30function readdirSync (dir) {
31  var kids = fs . readdirSync (dir)
32  debug ('dir=%j, kids=%j', dir, kids)
33  var data =  readScopesSync (dir, kids)
34  // Sort for bonus consistency points
35  data = data . sort (function (a, b) {
36    return a > b ? 1 : -1
37  })
38
39  return data
40}
41
42// Turn [ 'a', '@scope' ] into
43// ['a', '@scope/foo', '@scope/bar']
44function readScopes (root, kids, cb) {
45  var scopes = kids . filter (function (kid) {
46    return kid . charAt (0) === '@'
47  })
48
49  kids = kids . filter (function (kid) {
50    return kid . charAt (0) !== '@'
51  })
52
53  debug ('scopes=%j', scopes)
54
55  if (scopes . length === 0)
56    dz (cb) (null, kids) // prevent maybe-sync zalgo release
57
58  cb = once (cb)
59  var l = scopes . length
60  scopes . forEach (function (scope) {
61    var scopedir = path . resolve (root, scope)
62    debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir)
63    fs . readdir (scopedir, then . bind (null, scope))
64  })
65
66  function then (scope, er, scopekids) {
67    if (er)
68      return cb (er)
69
70    // XXX: Not sure how old this node bug is. Maybe superstition?
71    scopekids = scopekids . filter (function (scopekid) {
72      return !(scopekid === '.' || scopekid === '..' || !scopekid)
73    })
74
75    kids . push . apply (kids, scopekids . map (function (scopekid) {
76      return scope + '/' + scopekid
77    }))
78
79    debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids)
80
81    if (--l === 0)
82      cb (null, kids)
83  }
84}
85
86function readScopesSync (root, kids) {
87  var scopes = kids . filter (function (kid) {
88    return kid . charAt (0) === '@'
89  })
90
91  kids = kids . filter (function (kid) {
92    return kid . charAt (0) !== '@'
93  })
94
95  debug ('scopes=%j', scopes)
96
97  if (scopes . length === 0)
98    return kids
99
100  var l = scopes . length
101  scopes . forEach (function (scope) {
102    var scopedir = path . resolve (root, scope)
103    debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir)
104    then (scope, fs . readdirSync (scopedir))
105  })
106
107  function then (scope, scopekids) {
108    // XXX: Not sure how old this node bug is. Maybe superstition?
109    scopekids = scopekids . filter (function (scopekid) {
110      return !(scopekid === '.' || scopekid === '..' || !scopekid)
111    })
112
113    kids . push . apply (kids, scopekids . map (function (scopekid) {
114      return scope + '/' + scopekid
115    }))
116
117    debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids)
118  }
119
120  return kids
121}
122