a zip code crypto-currency system good for red ONLY

ncp.js 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // imported from ncp (this is temporary, will rewrite)
  2. var fs = require('graceful-fs')
  3. var path = require('path')
  4. var utimes = require('../util/utimes')
  5. function ncp (source, dest, options, callback) {
  6. if (!callback) {
  7. callback = options
  8. options = {}
  9. }
  10. var basePath = process.cwd()
  11. var currentPath = path.resolve(basePath, source)
  12. var targetPath = path.resolve(basePath, dest)
  13. var filter = options.filter
  14. var transform = options.transform
  15. var overwrite = options.overwrite
  16. // If overwrite is undefined, use clobber, otherwise default to true:
  17. if (overwrite === undefined) overwrite = options.clobber
  18. if (overwrite === undefined) overwrite = true
  19. var errorOnExist = options.errorOnExist
  20. var dereference = options.dereference
  21. var preserveTimestamps = options.preserveTimestamps === true
  22. var started = 0
  23. var finished = 0
  24. var running = 0
  25. var errored = false
  26. startCopy(currentPath)
  27. function startCopy (source) {
  28. started++
  29. if (filter) {
  30. if (filter instanceof RegExp) {
  31. console.warn('Warning: fs-extra: Passing a RegExp filter is deprecated, use a function')
  32. if (!filter.test(source)) {
  33. return doneOne(true)
  34. }
  35. } else if (typeof filter === 'function') {
  36. if (!filter(source, dest)) {
  37. return doneOne(true)
  38. }
  39. }
  40. }
  41. return getStats(source)
  42. }
  43. function getStats (source) {
  44. var stat = dereference ? fs.stat : fs.lstat
  45. running++
  46. stat(source, function (err, stats) {
  47. if (err) return onError(err)
  48. // We need to get the mode from the stats object and preserve it.
  49. var item = {
  50. name: source,
  51. mode: stats.mode,
  52. mtime: stats.mtime, // modified time
  53. atime: stats.atime, // access time
  54. stats: stats // temporary
  55. }
  56. if (stats.isDirectory()) {
  57. return onDir(item)
  58. } else if (stats.isFile() || stats.isCharacterDevice() || stats.isBlockDevice()) {
  59. return onFile(item)
  60. } else if (stats.isSymbolicLink()) {
  61. // Symlinks don't really need to know about the mode.
  62. return onLink(source)
  63. }
  64. })
  65. }
  66. function onFile (file) {
  67. var target = file.name.replace(currentPath, targetPath.replace('$', '$$$$')) // escapes '$' with '$$'
  68. isWritable(target, function (writable) {
  69. if (writable) {
  70. copyFile(file, target)
  71. } else {
  72. if (overwrite) {
  73. rmFile(target, function () {
  74. copyFile(file, target)
  75. })
  76. } else if (errorOnExist) {
  77. onError(new Error(target + ' already exists'))
  78. } else {
  79. doneOne()
  80. }
  81. }
  82. })
  83. }
  84. function copyFile (file, target) {
  85. var readStream = fs.createReadStream(file.name)
  86. var writeStream = fs.createWriteStream(target, { mode: file.mode })
  87. readStream.on('error', onError)
  88. writeStream.on('error', onError)
  89. if (transform) {
  90. transform(readStream, writeStream, file)
  91. } else {
  92. writeStream.on('open', function () {
  93. readStream.pipe(writeStream)
  94. })
  95. }
  96. writeStream.once('close', function () {
  97. fs.chmod(target, file.mode, function (err) {
  98. if (err) return onError(err)
  99. if (preserveTimestamps) {
  100. utimes.utimesMillis(target, file.atime, file.mtime, function (err) {
  101. if (err) return onError(err)
  102. return doneOne()
  103. })
  104. } else {
  105. doneOne()
  106. }
  107. })
  108. })
  109. }
  110. function rmFile (file, done) {
  111. fs.unlink(file, function (err) {
  112. if (err) return onError(err)
  113. return done()
  114. })
  115. }
  116. function onDir (dir) {
  117. var target = dir.name.replace(currentPath, targetPath.replace('$', '$$$$')) // escapes '$' with '$$'
  118. isWritable(target, function (writable) {
  119. if (writable) {
  120. return mkDir(dir, target)
  121. }
  122. copyDir(dir.name)
  123. })
  124. }
  125. function mkDir (dir, target) {
  126. fs.mkdir(target, dir.mode, function (err) {
  127. if (err) return onError(err)
  128. // despite setting mode in fs.mkdir, doesn't seem to work
  129. // so we set it here.
  130. fs.chmod(target, dir.mode, function (err) {
  131. if (err) return onError(err)
  132. copyDir(dir.name)
  133. })
  134. })
  135. }
  136. function copyDir (dir) {
  137. fs.readdir(dir, function (err, items) {
  138. if (err) return onError(err)
  139. items.forEach(function (item) {
  140. startCopy(path.join(dir, item))
  141. })
  142. return doneOne()
  143. })
  144. }
  145. function onLink (link) {
  146. var target = link.replace(currentPath, targetPath)
  147. fs.readlink(link, function (err, resolvedPath) {
  148. if (err) return onError(err)
  149. checkLink(resolvedPath, target)
  150. })
  151. }
  152. function checkLink (resolvedPath, target) {
  153. if (dereference) {
  154. resolvedPath = path.resolve(basePath, resolvedPath)
  155. }
  156. isWritable(target, function (writable) {
  157. if (writable) {
  158. return makeLink(resolvedPath, target)
  159. }
  160. fs.readlink(target, function (err, targetDest) {
  161. if (err) return onError(err)
  162. if (dereference) {
  163. targetDest = path.resolve(basePath, targetDest)
  164. }
  165. if (targetDest === resolvedPath) {
  166. return doneOne()
  167. }
  168. return rmFile(target, function () {
  169. makeLink(resolvedPath, target)
  170. })
  171. })
  172. })
  173. }
  174. function makeLink (linkPath, target) {
  175. fs.symlink(linkPath, target, function (err) {
  176. if (err) return onError(err)
  177. return doneOne()
  178. })
  179. }
  180. function isWritable (path, done) {
  181. fs.lstat(path, function (err) {
  182. if (err) {
  183. if (err.code === 'ENOENT') return done(true)
  184. return done(false)
  185. }
  186. return done(false)
  187. })
  188. }
  189. function onError (err) {
  190. // ensure callback is defined & called only once:
  191. if (!errored && callback !== undefined) {
  192. errored = true
  193. return callback(err)
  194. }
  195. }
  196. function doneOne (skipped) {
  197. if (!skipped) running--
  198. finished++
  199. if ((started === finished) && (running === 0)) {
  200. if (callback !== undefined) {
  201. return callback(null)
  202. }
  203. }
  204. }
  205. }
  206. module.exports = ncp