Reorganise instance save commands

Move create, list, upload and dalete save management commands to its own
'instance save' namespace in the command line interface.
This commit is contained in:
Hornwitser committed 2022-03-27 15:50:42 +02:00
1 parent 7db091d427
commit 0de964ec02
2 files changed
+30 -26

No files matched your search

+14 -10
View File
@@ -533,8 +533,11 @@ async function loadMapSettings(args) {
};
}
instanceCommands.add(new libCommand.Command({
definition: ["list-saves <instance>", "list saves on an instance", (yargs) => {
const instanceSaveCommands = new libCommand.CommandTree({
name: "save", alias: ["s"], description: "Instance save management",
});
instanceSaveCommands.add(new libCommand.Command({
definition: ["list <instance>", "list saves on an instance", (yargs) => {
yargs.positional("instance", { describe: "Instance to list saves on", type: "string" });
}],
handler: async function(args, control) {
@@ -548,8 +551,8 @@ instanceCommands.add(new libCommand.Command({
},
}));
instanceCommands.add(new libCommand.Command({
definition: ["create-save <instance> [name]", "Create a new save on an instance", (yargs) => {
instanceSaveCommands.add(new libCommand.Command({
definition: ["create <instance> [name]", "Create a new save on an instance", (yargs) => {
yargs.positional("instance", { describe: "Instance to create on", type: "string" });
yargs.positional("name", { describe: "Name of save to create.", type: "string", default: "world.zip" });
yargs.options({
@@ -573,8 +576,8 @@ instanceCommands.add(new libCommand.Command({
},
}));
instanceCommands.add(new libCommand.Command({
definition: ["upload-save <instance> <filepath>", "Upload a save to an instance", (yargs) => {
instanceSaveCommands.add(new libCommand.Command({
definition: ["upload <instance> <filepath>", "Upload a save to an instance", (yargs) => {
yargs.positional("instance", { describe: "Instance to upload to", type: "string" });
yargs.positional("filepath", { describe: "Path to save to upload", type: "string" });
yargs.options({
@@ -624,8 +627,8 @@ instanceCommands.add(new libCommand.Command({
},
}));
instanceCommands.add(new libCommand.Command({
definition: ["download-save <instance> <save>", "Download a save from an instance", (yargs) => {
instanceSaveCommands.add(new libCommand.Command({
definition: ["download <instance> <save>", "Download a save from an instance", (yargs) => {
yargs.positional("instance", { describe: "Instance to download save from", type: "string" });
yargs.positional("save", { describe: "Save to download", type: "string" });
}],
@@ -669,8 +672,8 @@ instanceCommands.add(new libCommand.Command({
},
}));
instanceCommands.add(new libCommand.Command({
definition: ["delete-save <instance> <save>", "Delete a save from an instance", (yargs) => {
instanceSaveCommands.add(new libCommand.Command({
definition: ["delete <instance> <save>", "Delete a save from an instance", (yargs) => {
yargs.positional("instance", { describe: "Instance to delete save from", type: "string" });
yargs.positional("save", { describe: "Save to delete", type: "string" });
}],
@@ -682,6 +685,7 @@ instanceCommands.add(new libCommand.Command({
});
},
}));
instanceCommands.add(instanceSaveCommands);
instanceCommands.add(new libCommand.Command({
definition: ["export-data <instance>", "Export item icons and locale from instance", (yargs) => {
+16 -16
View File
@@ -250,11 +250,11 @@ describe("Integration of Clusterio", function() {
});
});
describe("instance create-save", function() {
describe("instance save create", function() {
it("creates a save", async function() {
slowTest(this);
getControl().saveListUpdates = [];
await execCtl("instance create-save test");
await execCtl("instance save create test");
await checkInstanceStatus(44, "stopped");
});
});
@@ -266,10 +266,10 @@ describe("Integration of Clusterio", function() {
});
});
describe("instance list-saves", function() {
describe("instance save list", function() {
it("lists the created save", async function() {
slowTest(this);
let result = await execCtl("instance list-saves test");
let result = await execCtl("instance save list test");
assert(/world\.zip/.test(result.stdout), "world.zip not present in list save output");
});
});
@@ -530,10 +530,10 @@ describe("Integration of Clusterio", function() {
});
});
describe("instance upload-save", function() {
describe("instance save upload", function() {
it("should upload a zip file", async function() {
await fs.outputFile(path.join("temp", "test", "upload.zip"), "a test");
await execCtl("instance upload-save 44 upload.zip");
await execCtl("instance save upload 44 upload.zip");
assert(
await fs.pathExists(path.join("temp", "test", "instances", "test", "saves", "upload.zip")),
"file not uploaded to saves directory"
@@ -541,42 +541,42 @@ describe("Integration of Clusterio", function() {
});
it("should reject non-zip files", async function() {
await fs.outputFile(path.join("temp", "test", "invalid"), "a test");
await assert.rejects(execCtl("instance upload-save 44 invalid"));
await assert.rejects(execCtl("instance save upload 44 invalid"));
});
it("should reject path traversal attacks", async function() {
await fs.outputFile(path.join("temp", "test", "upload.zip"), "a test");
await assert.rejects(execCtl("instance upload-save 44 upload.zip --name ../traversal.zip"));
await assert.rejects(execCtl("instance save upload 44 upload.zip --name ../traversal.zip"));
});
});
describe("instance download-save", function() {
describe("instance save download", function() {
it("should download a save", async function() {
await fs.remove(path.join("temp", "test", "upload.zip"));
await execCtl("instance download-save 44 upload.zip");
await execCtl("instance save download 44 upload.zip");
assert(await fs.pathExists(path.join("temp", "test", "upload.zip")));
});
it("should error if save does not exist", async function() {
await assert.rejects(execCtl("instance download-save 44 invalid"));
await assert.rejects(execCtl("instance save download 44 invalid"));
});
it("should error on path traversal attacks", async function() {
await assert.rejects(execCtl("instance download-save 44 ../factorio-current.log"));
await assert.rejects(execCtl("instance save download 44 ../factorio-current.log"));
});
});
describe("instance delete-save", function() {
describe("instance save delete", function() {
it("should delete a save", async function() {
await execCtl("instance delete-save 44 upload.zip");
await execCtl("instance save delete 44 upload.zip");
assert(
!await fs.pathExists(path.join("temp", "test", "instances", "test", "saves", "upload.zip")),
"file not deleted"
);
});
it("should error if save does not exist", async function() {
await assert.rejects(execCtl("instance delete-save 44 upload.zip"));
await assert.rejects(execCtl("instance save delete 44 upload.zip"));
});
it("should error on path traversal attacks", async function() {
await fs.outputFile(path.join("temp", "test", "upload.zip"), "a test");
await assert.rejects(execCtl("instance delete-save 44 ../../upload.zip"));
await assert.rejects(execCtl("instance save delete 44 ../../upload.zip"));
});
});