Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

cp.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. var fs = require('fs');
  2. var path = require('path');
  3. var common = require('./common');
  4. var os = require('os');
  5. // Buffered file copy, synchronous
  6. // (Using readFileSync() + writeFileSync() could easily cause a memory overflow
  7. // with large files)
  8. function copyFileSync(srcFile, destFile) {
  9. if (!fs.existsSync(srcFile))
  10. common.error('copyFileSync: no such file or directory: ' + srcFile);
  11. var BUF_LENGTH = 64*1024,
  12. buf = new Buffer(BUF_LENGTH),
  13. bytesRead = BUF_LENGTH,
  14. pos = 0,
  15. fdr = null,
  16. fdw = null;
  17. try {
  18. fdr = fs.openSync(srcFile, 'r');
  19. } catch(e) {
  20. common.error('copyFileSync: could not read src file ('+srcFile+')');
  21. }
  22. try {
  23. fdw = fs.openSync(destFile, 'w');
  24. } catch(e) {
  25. common.error('copyFileSync: could not write to dest file (code='+e.code+'):'+destFile);
  26. }
  27. while (bytesRead === BUF_LENGTH) {
  28. bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
  29. fs.writeSync(fdw, buf, 0, bytesRead);
  30. pos += bytesRead;
  31. }
  32. fs.closeSync(fdr);
  33. fs.closeSync(fdw);
  34. fs.chmodSync(destFile, fs.statSync(srcFile).mode);
  35. }
  36. // Recursively copies 'sourceDir' into 'destDir'
  37. // Adapted from https://github.com/ryanmcgrath/wrench-js
  38. //
  39. // Copyright (c) 2010 Ryan McGrath
  40. // Copyright (c) 2012 Artur Adib
  41. //
  42. // Licensed under the MIT License
  43. // http://www.opensource.org/licenses/mit-license.php
  44. function cpdirSyncRecursive(sourceDir, destDir, opts) {
  45. if (!opts) opts = {};
  46. /* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
  47. var checkDir = fs.statSync(sourceDir);
  48. try {
  49. fs.mkdirSync(destDir, checkDir.mode);
  50. } catch (e) {
  51. //if the directory already exists, that's okay
  52. if (e.code !== 'EEXIST') throw e;
  53. }
  54. var files = fs.readdirSync(sourceDir);
  55. for (var i = 0; i < files.length; i++) {
  56. var srcFile = sourceDir + "/" + files[i];
  57. var destFile = destDir + "/" + files[i];
  58. var srcFileStat = fs.lstatSync(srcFile);
  59. if (srcFileStat.isDirectory()) {
  60. /* recursion this thing right on back. */
  61. cpdirSyncRecursive(srcFile, destFile, opts);
  62. } else if (srcFileStat.isSymbolicLink()) {
  63. var symlinkFull = fs.readlinkSync(srcFile);
  64. fs.symlinkSync(symlinkFull, destFile, os.platform() === "win32" ? "junction" : null);
  65. } else {
  66. /* At this point, we've hit a file actually worth copying... so copy it on over. */
  67. if (fs.existsSync(destFile) && !opts.force) {
  68. common.log('skipping existing file: ' + files[i]);
  69. } else {
  70. copyFileSync(srcFile, destFile);
  71. }
  72. }
  73. } // for files
  74. } // cpdirSyncRecursive
  75. //@
  76. //@ ### cp([options ,] source [,source ...], dest)
  77. //@ ### cp([options ,] source_array, dest)
  78. //@ Available options:
  79. //@
  80. //@ + `-f`: force
  81. //@ + `-r, -R`: recursive
  82. //@
  83. //@ Examples:
  84. //@
  85. //@ ```javascript
  86. //@ cp('file1', 'dir1');
  87. //@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
  88. //@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
  89. //@ ```
  90. //@
  91. //@ Copies files. The wildcard `*` is accepted.
  92. function _cp(options, sources, dest) {
  93. options = common.parseOptions(options, {
  94. 'f': 'force',
  95. 'R': 'recursive',
  96. 'r': 'recursive'
  97. });
  98. // Get sources, dest
  99. if (arguments.length < 3) {
  100. common.error('missing <source> and/or <dest>');
  101. } else if (arguments.length > 3) {
  102. sources = [].slice.call(arguments, 1, arguments.length - 1);
  103. dest = arguments[arguments.length - 1];
  104. } else if (typeof sources === 'string') {
  105. sources = [sources];
  106. } else if ('length' in sources) {
  107. sources = sources; // no-op for array
  108. } else {
  109. common.error('invalid arguments');
  110. }
  111. var exists = fs.existsSync(dest),
  112. stats = exists && fs.statSync(dest);
  113. // Dest is not existing dir, but multiple sources given
  114. if ((!exists || !stats.isDirectory()) && sources.length > 1)
  115. common.error('dest is not a directory (too many sources)');
  116. // Dest is an existing file, but no -f given
  117. if (exists && stats.isFile() && !options.force)
  118. common.error('dest file already exists: ' + dest);
  119. if (options.recursive) {
  120. // Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*"
  121. // (see Github issue #15)
  122. sources.forEach(function(src, i) {
  123. if (src[src.length - 1] === '/')
  124. sources[i] += '*';
  125. });
  126. // Create dest
  127. try {
  128. fs.mkdirSync(dest, parseInt('0777', 8));
  129. } catch (e) {
  130. // like Unix's cp, keep going even if we can't create dest dir
  131. }
  132. }
  133. sources = common.expand(sources);
  134. sources.forEach(function(src) {
  135. if (!fs.existsSync(src)) {
  136. common.error('no such file or directory: '+src, true);
  137. return; // skip file
  138. }
  139. // If here, src exists
  140. if (fs.statSync(src).isDirectory()) {
  141. if (!options.recursive) {
  142. // Non-Recursive
  143. common.log(src + ' is a directory (not copied)');
  144. } else {
  145. // Recursive
  146. // 'cp /a/source dest' should create 'source' in 'dest'
  147. var newDest = path.join(dest, path.basename(src)),
  148. checkDir = fs.statSync(src);
  149. try {
  150. fs.mkdirSync(newDest, checkDir.mode);
  151. } catch (e) {
  152. //if the directory already exists, that's okay
  153. if (e.code !== 'EEXIST') {
  154. common.error('dest file no such file or directory: ' + newDest, true);
  155. throw e;
  156. }
  157. }
  158. cpdirSyncRecursive(src, newDest, {force: options.force});
  159. }
  160. return; // done with dir
  161. }
  162. // If here, src is a file
  163. // When copying to '/path/dir':
  164. // thisDest = '/path/dir/file1'
  165. var thisDest = dest;
  166. if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
  167. thisDest = path.normalize(dest + '/' + path.basename(src));
  168. if (fs.existsSync(thisDest) && !options.force) {
  169. common.error('dest file already exists: ' + thisDest, true);
  170. return; // skip file
  171. }
  172. copyFileSync(src, thisDest);
  173. }); // forEach(src)
  174. }
  175. module.exports = _cp;