| var fs = require('fs'); |
| var path = require('path'); |
| var common = require('./common'); |
| |
| //@ |
| //@ ### mv(source [, source ...], dest') |
| //@ ### mv(source_array, dest') |
| //@ Available options: |
| //@ |
| //@ + `f`: force |
| //@ |
| //@ Examples: |
| //@ |
| //@ ```javascript |
| //@ mv('-f', 'file', 'dir/'); |
| //@ mv('file1', 'file2', 'dir/'); |
| //@ mv(['file1', 'file2'], 'dir/'); // same as above |
| //@ ``` |
| //@ |
| //@ Moves files. The wildcard `*` is accepted. |
| function _mv(options, sources, dest) { |
| options = common.parseOptions(options, { |
| 'f': '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 if ('length' in sources) { |
| sources = sources; // no-op for array |
| } else { |
| common.error('invalid arguments'); |
| } |
| |
| sources = common.expand(sources); |
| |
| 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.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.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) |
| } // mv |
| module.exports = _mv; |