aboutsummaryrefslogtreecommitdiff
path: root/node_modules/shelljs/src/mv.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/shelljs/src/mv.js')
-rw-r--r--node_modules/shelljs/src/mv.js99
1 files changed, 99 insertions, 0 deletions
diff --git a/node_modules/shelljs/src/mv.js b/node_modules/shelljs/src/mv.js
new file mode 100644
index 000000000..7fc7cf04c
--- /dev/null
+++ b/node_modules/shelljs/src/mv.js
@@ -0,0 +1,99 @@
+var fs = require('fs');
+var path = require('path');
+var common = require('./common');
+var cp = require('./cp');
+var rm = require('./rm');
+
+common.register('mv', _mv, {
+ cmdOptions: {
+ 'f': '!no_force',
+ 'n': 'no_force',
+ },
+});
+
+//@
+//@ ### mv([options ,] source [, source ...], dest')
+//@ ### mv([options ,] source_array, dest')
+//@ Available options:
+//@
+//@ + `-f`: force (default behavior)
+//@ + `-n`: no-clobber
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ mv('-n', 'file', 'dir/');
+//@ mv('file1', 'file2', 'dir/');
+//@ mv(['file1', 'file2'], 'dir/'); // same as above
+//@ ```
+//@
+//@ Moves files.
+function _mv(options, sources, dest) {
+ // Get sources, dest
+ if (arguments.length < 3) {
+ common.error('missing <source> and/or <dest>');
+ } else if (arguments.length > 3) {
+ sources = [].slice.call(arguments, 1, arguments.length - 1);
+ dest = arguments[arguments.length - 1];
+ } else if (typeof sources === 'string') {
+ sources = [sources];
+ } else {
+ // TODO(nate): figure out if we actually need this line
+ common.error('invalid arguments');
+ }
+
+ var exists = fs.existsSync(dest);
+ var stats = exists && fs.statSync(dest);
+
+ // Dest is not existing dir, but multiple sources given
+ if ((!exists || !stats.isDirectory()) && sources.length > 1) {
+ common.error('dest is not a directory (too many sources)');
+ }
+
+ // Dest is an existing file, but no -f given
+ if (exists && stats.isFile() && options.no_force) {
+ common.error('dest file already exists: ' + dest);
+ }
+
+ sources.forEach(function (src) {
+ if (!fs.existsSync(src)) {
+ common.error('no such file or directory: ' + src, { continue: true });
+ return; // skip file
+ }
+
+ // If here, src exists
+
+ // When copying to '/path/dir':
+ // thisDest = '/path/dir/file1'
+ var thisDest = dest;
+ if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) {
+ thisDest = path.normalize(dest + '/' + path.basename(src));
+ }
+
+ if (fs.existsSync(thisDest) && options.no_force) {
+ common.error('dest file already exists: ' + thisDest, { continue: true });
+ return; // skip file
+ }
+
+ if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
+ common.error('cannot move to self: ' + src, { continue: true });
+ return; // skip file
+ }
+
+ try {
+ fs.renameSync(src, thisDest);
+ } catch (e) {
+ /* istanbul ignore next */
+ if (e.code === 'EXDEV') {
+ // If we're trying to `mv` to an external partition, we'll actually need
+ // to perform a copy and then clean up the original file. If either the
+ // copy or the rm fails with an exception, we should allow this
+ // exception to pass up to the top level.
+ cp('-r', src, thisDest);
+ rm('-rf', src);
+ }
+ }
+ }); // forEach(src)
+ return '';
+} // mv
+module.exports = _mv;