readdir.js 2.9 KB

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