blob: 495dc430303099a993ff9268eeeb37a9e6dbbae0 [file] [log] [blame]
var fs = require('fs');
var path = require('path');
var common = require('./common');
//@
//@ ### 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) {
options = common.parseOptions(options, {
'f': '!no_force',
'n': 'no_force'
});
// 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 {
common.error('invalid arguments');
}
var exists = fs.existsSync(dest),
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, 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, true);
return; // skip file
}
if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
common.error('cannot move to self: '+src, true);
return; // skip file
}
fs.renameSync(src, thisDest);
}); // forEach(src)
return new common.ShellString('', common.state.error, common.state.errorCode);
} // mv
module.exports = _mv;