From 5cc4c5a689e124e3951c80f0cfda0de4a797fec7 Mon Sep 17 00:00:00 2001 From: hachem Date: Tue, 9 Dec 2025 23:02:55 +0100 Subject: [add]: merging and refactor --- cli/commands/merge.js | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 cli/commands/merge.js (limited to 'cli/commands/merge.js') diff --git a/cli/commands/merge.js b/cli/commands/merge.js new file mode 100644 index 0000000..138dd54 --- /dev/null +++ b/cli/commands/merge.js @@ -0,0 +1,156 @@ +const fs = require("fs-extra") +const path = require("path") +const { spawn } = require("child_process") +const archiver = require("archiver") + +const { LoadConfig } = require("../../lib/config") +const { serverDir } = require("./generate") + +const config = LoadConfig() + +const +{ + server_location, + backup_location, + merge_pre_command, + merge_post_command +} = config + +const RunCommand = (command) => +{ + return new Promise((resolve) => + { + console.log(` Running: ${command}`) + + const proc = spawn(command, [], { shell: true, stdio: "inherit" }) + + proc.on("close", (code) => + { + if (code === 0) + console.log(" Command completed.") + else + console.log(` Command exited with code ${code}`) + resolve(code) + }) + + proc.on("error", (err) => + { + console.error(" Command failed:", err.message) + resolve(1) + }) + }) +} + +const CreateBackup = (sourceDir, backupDir) => +{ + return new Promise(async (resolve, reject) => + { + const now = new Date() + const timestamp = now.toISOString() + .replace(/[:.]/g, "-") + .replace("T", "_") + .slice(0, 19) + + const zipName = `backup_${timestamp}.zip` + const zipPath = path.join(backupDir, zipName) + + await fs.ensureDir(backupDir) + + const output = fs.createWriteStream(zipPath) + const archive = archiver("zip", { zlib: { level: 9 } }) + + output.on("close", () => + { + console.log(` Created backup: ${zipName} (${archive.pointer()} bytes)`) + resolve(zipPath) + }) + + archive.on("error", err => reject(err)) + + archive.pipe(output) + archive.directory(sourceDir, false) + archive.finalize() + }) +} + +const Merge = async () => +{ + if (!server_location || !backup_location) + { + console.log(" Error: server_location and backup_location must be set in config.") + return + } + + if (!await fs.pathExists(serverDir)) + { + console.log(" Error: No generated files found. Run 'generate' first.") + return + } + + // Run pre-command + if (merge_pre_command) + { + console.log("\n Running pre-merge command...") + await RunCommand(merge_pre_command) + console.log("") + } + + // Check if server location exists and back it up + if (await fs.pathExists(server_location)) + { + console.log(` Backing up ${server_location}...`) + try + { + await CreateBackup(server_location, backup_location) + } + catch (err) + { + console.error(" Failed to create backup:", err.message) + return + } + } + else + { + console.log(" Server location doesn't exist, creating it...") + await fs.ensureDir(server_location) + } + + // Move generated files to server location + console.log(" Moving generated files to server location...") + try + { + const items = await fs.readdir(serverDir) + for (const item of items) + { + const src = path.join(serverDir, item) + const dest = path.join(server_location, item) + + // Remove existing item at destination + if (await fs.pathExists(dest)) + await fs.remove(dest) + + await fs.move(src, dest) + console.log(` Moved: ${item}`) + } + + // Remove the now-empty server directory + await fs.remove(serverDir) + + console.log(" Merge complete!") + } + catch (err) + { + console.error(" Failed to move files:", err.message) + return + } + + // Run post-command + if (merge_post_command) + { + console.log("\n Running post-merge command...") + await RunCommand(merge_post_command) + } +} + +module.exports = { Merge } + -- cgit v1.3