enigma-bbs/core/file_util.js

63 lines
1.4 KiB
JavaScript
Raw Normal View History

/* jslint node: true */
'use strict';
// ENiGMA½
// deps
const fse = require('fs-extra');
const paths = require('path');
const async = require('async');
exports.moveFileWithCollisionHandling = moveFileWithCollisionHandling;
exports.pathWithTerminatingSeparator = pathWithTerminatingSeparator;
//
// Move |src| -> |dst| renaming to file(1).ext, file(2).ext, etc.
// in the case of collisions.
//
function moveFileWithCollisionHandling(src, dst, cb) {
const dstPath = paths.dirname(dst);
const dstFileExt = paths.extname(dst);
const dstFileSuffix = paths.basename(dst, dstFileExt);
let renameIndex = 0;
let movedOk = false;
let tryDstPath;
async.until(
() => movedOk, // until moved OK
(cb) => {
if(0 === renameIndex) {
// try originally supplied path first
tryDstPath = dst;
} else {
tryDstPath = paths.join(dstPath, `${dstFileSuffix}(${renameIndex})${dstFileExt}`);
}
fse.move(src, tryDstPath, err => {
if(err) {
if('EEXIST' === err.code) {
renameIndex += 1;
return cb(null); // keep trying
}
return cb(err);
}
movedOk = true;
return cb(null, tryDstPath);
});
},
(err, finalPath) => {
return cb(err, finalPath);
}
);
}
function pathWithTerminatingSeparator(path) {
if(path && paths.sep !== path.charAt(path.length - 1)) {
path = path + paths.sep;
}
return path;
}