mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 15:04:52 +09:00
Add findUnusedName to file_ops.js
Add function to find an unused name in a directory to lib/file_ops and use it for finding an unused instance directory.
This commit is contained in:
1 parent
544d8deb81
commit
0066a06107
3 files changed
+75
-7
No files matched your search
@@ -32,6 +32,44 @@ async function getNewestFile(directory, filter = (name) => true) {
|
||||
return newestFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies name in case it already exisist at the given directory
|
||||
*
|
||||
* Checks the directory passed if it already contains a file or folder with
|
||||
* the given name, if it does not returns name unmodified, otherwise it
|
||||
* returns a modified name that does not exist in the directory.
|
||||
*
|
||||
* Warning: this function should not be relied upon to be accurate for
|
||||
* security sensitive applications. The selection process is inherently
|
||||
* racy and a file or folder may have been created in the folder by the time
|
||||
* this function returns.
|
||||
*
|
||||
* @param {string} directory - directory to check in.
|
||||
* @param {string} name - file name to check for, may have extension.
|
||||
* @param {string} extension - dot extension used for the file name.
|
||||
* @returns {string} modified name with extension that likely does not exist
|
||||
* in the folder
|
||||
*/
|
||||
async function findUnusedName(directory, name, extension = "") {
|
||||
if (extension && name.endsWith(extension)) {
|
||||
name = name.slice(0, -extension.length);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (!await fs.pathExists(path.join(directory, `${name}${extension}`))) {
|
||||
return `${name}${extension}`;
|
||||
}
|
||||
|
||||
let match = /^(.*?)(-(\d+))?$/.exec(name);
|
||||
if (!match[2]) {
|
||||
name = `${match[1]}-2`;
|
||||
} else {
|
||||
name = `${match[1]}-${Number.parseInt(match[3], 10) + 1}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getNewestFile,
|
||||
findUnusedName,
|
||||
};
|
||||
@@ -1102,13 +1102,8 @@ class Slave extends libLink.Link {
|
||||
throw new Error(`Instance name ${err.message}`);
|
||||
}
|
||||
|
||||
// For now add dashes until an unused directory name is found
|
||||
let dir = path.join(this.config.get("slave.instances_directory"), name);
|
||||
while (await fs.pathExists(dir)) {
|
||||
dir += "-";
|
||||
}
|
||||
|
||||
return dir;
|
||||
let instancesDir = this.config.get("slave.instances_directory");
|
||||
return path.join(instancesDir, await libFileOps.findUnusedName(instancesDir, name));
|
||||
}
|
||||
|
||||
async forwardRequestToInstance(message, request) {
|
||||
|
||||
@@ -13,6 +13,13 @@ describe("lib/file_ops", function() {
|
||||
|
||||
await fs.outputFile(path.join(baseDir, "test", "file.txt"), "contents");
|
||||
await fs.outputFile(path.join(baseDir, "test", "another file.txt"), "more contents");
|
||||
|
||||
await fs.outputFile(path.join(baseDir, "find", "file"), "contents");
|
||||
await fs.outputFile(path.join(baseDir, "find", "file.txt"), "contents");
|
||||
await fs.outputFile(path.join(baseDir, "find", "foo-1"), "contents");
|
||||
await fs.outputFile(path.join(baseDir, "find", "foo-2"), "contents");
|
||||
await fs.outputFile(path.join(baseDir, "find", "bar-1.txt"), "contents");
|
||||
await fs.outputFile(path.join(baseDir, "find", "bar-2.txt"), "contents");
|
||||
}
|
||||
|
||||
before(setupTestingEnv);
|
||||
@@ -31,4 +38,32 @@ describe("lib/file_ops", function() {
|
||||
assert.equal(newest, null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findUnusedName()", function() {
|
||||
it("should return named unchanged if it does not exist", async function() {
|
||||
let cases = [
|
||||
[["file"], "file"],
|
||||
[["file", ".txt"], "file.txt"],
|
||||
[["file.txt", ".txt"], "file.txt"],
|
||||
];
|
||||
for (let [args, expected] of cases) {
|
||||
let actual = await libFileOps.findUnusedName(path.join(baseDir, "test", "folder"), ...args);
|
||||
assert.equal(actual, expected);
|
||||
}
|
||||
});
|
||||
it("should return changed name if it does exist", async function() {
|
||||
let cases = [
|
||||
[["file"], "file-2"],
|
||||
[["file", ".txt"], "file-2.txt"],
|
||||
[["file.txt", ".txt"], "file-2.txt"],
|
||||
[["foo-1"], "foo-3"],
|
||||
[["bar-1", ".txt"], "bar-3.txt"],
|
||||
[["bar-1.txt", ".txt"], "bar-3.txt"],
|
||||
];
|
||||
for (let [args, expected] of cases) {
|
||||
let actual = await libFileOps.findUnusedName(path.join(baseDir, "find"), ...args);
|
||||
assert.equal(actual, expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user