PageRenderTime 33ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/platforms/browser/cordova/node_modules/shelljs/src/cp.js

https://gitlab.com/romanvenicagcba/Cordova
JavaScript | 210 lines | 90 code | 20 blank | 100 comment | 32 complexity | e7ee71ccc7b4022dc088d74d74f0553b MD5 | raw file
  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.no_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 (default behavior)
  81. //@ + `-n`: no-clobber
  82. //@ + `-r, -R`: recursive
  83. //@
  84. //@ Examples:
  85. //@
  86. //@ ```javascript
  87. //@ cp('file1', 'dir1');
  88. //@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
  89. //@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
  90. //@ ```
  91. //@
  92. //@ Copies files. The wildcard `*` is accepted.
  93. function _cp(options, sources, dest) {
  94. options = common.parseOptions(options, {
  95. 'f': '!no_force',
  96. 'n': 'no_force',
  97. 'R': 'recursive',
  98. 'r': 'recursive'
  99. });
  100. // Get sources, dest
  101. if (arguments.length < 3) {
  102. common.error('missing <source> and/or <dest>');
  103. } else if (arguments.length > 3) {
  104. sources = [].slice.call(arguments, 1, arguments.length - 1);
  105. dest = arguments[arguments.length - 1];
  106. } else if (typeof sources === 'string') {
  107. sources = [sources];
  108. } else if ('length' in sources) {
  109. sources = sources; // no-op for array
  110. } else {
  111. common.error('invalid arguments');
  112. }
  113. var exists = fs.existsSync(dest),
  114. stats = exists && fs.statSync(dest);
  115. // Dest is not existing dir, but multiple sources given
  116. if ((!exists || !stats.isDirectory()) && sources.length > 1)
  117. common.error('dest is not a directory (too many sources)');
  118. // Dest is an existing file, but no -f given
  119. if (exists && stats.isFile() && options.no_force)
  120. common.error('dest file already exists: ' + dest);
  121. if (options.recursive) {
  122. // Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*"
  123. // (see Github issue #15)
  124. sources.forEach(function(src, i) {
  125. if (src[src.length - 1] === '/') {
  126. sources[i] += '*';
  127. // If src is a directory and dest doesn't exist, 'cp -r src dest' should copy src/* into dest
  128. } else if (fs.statSync(src).isDirectory() && !exists) {
  129. sources[i] += '/*';
  130. }
  131. });
  132. // Create dest
  133. try {
  134. fs.mkdirSync(dest, parseInt('0777', 8));
  135. } catch (e) {
  136. // like Unix's cp, keep going even if we can't create dest dir
  137. }
  138. }
  139. sources = common.expand(sources);
  140. sources.forEach(function(src) {
  141. if (!fs.existsSync(src)) {
  142. common.error('no such file or directory: '+src, true);
  143. return; // skip file
  144. }
  145. // If here, src exists
  146. if (fs.statSync(src).isDirectory()) {
  147. if (!options.recursive) {
  148. // Non-Recursive
  149. common.log(src + ' is a directory (not copied)');
  150. } else {
  151. // Recursive
  152. // 'cp /a/source dest' should create 'source' in 'dest'
  153. var newDest = path.join(dest, path.basename(src)),
  154. checkDir = fs.statSync(src);
  155. try {
  156. fs.mkdirSync(newDest, checkDir.mode);
  157. } catch (e) {
  158. //if the directory already exists, that's okay
  159. if (e.code !== 'EEXIST') {
  160. common.error('dest file no such file or directory: ' + newDest, true);
  161. throw e;
  162. }
  163. }
  164. cpdirSyncRecursive(src, newDest, {no_force: options.no_force});
  165. }
  166. return; // done with dir
  167. }
  168. // If here, src is a file
  169. // When copying to '/path/dir':
  170. // thisDest = '/path/dir/file1'
  171. var thisDest = dest;
  172. if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
  173. thisDest = path.normalize(dest + '/' + path.basename(src));
  174. if (fs.existsSync(thisDest) && options.no_force) {
  175. common.error('dest file already exists: ' + thisDest, true);
  176. return; // skip file
  177. }
  178. copyFileSync(src, thisDest);
  179. }); // forEach(src)
  180. }
  181. module.exports = _cp;