diff --git a/src/commands/uninstall_command.ts b/src/commands/uninstall_command.ts new file mode 100644 index 0000000..51fca6f --- /dev/null +++ b/src/commands/uninstall_command.ts @@ -0,0 +1,20 @@ +import Subcommand from "./subcommand.js"; +import {Command} from "commander"; +import ModManager from "../mod-manager.js"; +import Mods from "../mods/mods.js"; + +export default class UninstallCommand implements Subcommand { + registerCommand(program: Command): void { + program.command("uninstall") + .description("Uninstalls the provided mods") + .argument("") + .action((mods) => { + ModManager.execute(() => { + for (let mod of mods) { + Mods.uninstall(mod); + } + }) + }) + } + +} \ No newline at end of file diff --git a/src/io/file_downloder.ts b/src/io/file_downloder.ts index 26d9b69..6db782e 100644 --- a/src/io/file_downloder.ts +++ b/src/io/file_downloder.ts @@ -2,14 +2,13 @@ import path from "path"; import * as https from "https"; import {createWriteStream} from "fs"; import DownloadError from "../errors/download_error.js"; +import Mods from "../mods/mods.js"; export default class FileDownloader { - private static readonly MODS_FOLDER_PATH: string = path.join("mods"); - static downloadMod(task: DownloadTask): void { https.get(task.url, res => { - const filePath = path.join(this.MODS_FOLDER_PATH, task.fileName); + const filePath = path.join(Mods.MODS_FOLDER_PATH, task.fileName); const writeStream = createWriteStream(filePath); res.pipe(writeStream); writeStream.on("finish", () => writeStream.close()); diff --git a/src/mod-manager.ts b/src/mod-manager.ts index b83696e..7b35610 100644 --- a/src/mod-manager.ts +++ b/src/mod-manager.ts @@ -8,6 +8,7 @@ import PrintUtils from "./util/print_utils.js"; import path from "path"; import {Logger, pino} from "pino" import {ListCommand} from "./commands/list_command.js"; +import UninstallCommand from "./commands/uninstall_command.js"; export default class ModManager { @@ -19,7 +20,8 @@ export default class ModManager { private static subcommands: Array = [ new InitCommand(), new InstallCommand(), - new ListCommand() + new ListCommand(), + new UninstallCommand() ]; static init() { diff --git a/src/mods/mods.ts b/src/mods/mods.ts index 9bb24e0..82e383c 100644 --- a/src/mods/mods.ts +++ b/src/mods/mods.ts @@ -4,12 +4,13 @@ import PrintUtils from "../util/print_utils.js"; import ModrinthSource from "./sources/modrinth_source.js"; import ModSource from "./sources/mod_source.js"; import ModNotFoundError from "../errors/mod_not_found_error.js"; -import {readFileSync, writeFileSync} from "fs"; +import {readFileSync, unlinkSync, writeFileSync} from "fs"; import Util from "../util/util.js"; export default class Mods { public static readonly MOD_FILE = "mods.json"; + public static readonly MODS_FOLDER_PATH: string = path.join("mods"); private static readonly MOD_SOURCES: Array = [ new ModrinthSource() ]; @@ -40,22 +41,23 @@ export default class Mods { // If a mod is found, install it if (id != undefined) { + const projectName = await source.getProjectName(id); // If mod is not already installed if (!this.isModInstalled(id)) { - spinner.updateText(`Installing ${mod}...`) + spinner.updateText(`Installing ${projectName}...`) try { const modObj: Mod = await source.install(id); this.trackMod(modObj); - spinner.succeed(`Successfully installed ${mod}`); + spinner.succeed(`Successfully installed ${projectName}`); success = true; } catch (e) { // Log the error, and continue to next source spinner.error(e); } } else { - spinner.error(`Mod ${mod} is already installed.`) + spinner.error(`Mod ${projectName} is already installed.`) } } } @@ -87,7 +89,43 @@ export default class Mods { } private static isModInstalled(id: string): boolean { - const modsFromSource: Array = this.getTrackedMods().filter(mod => mod.id == id); - return !Util.isArrayEmpty(modsFromSource) + const modsWithId: Array = this.getTrackedMods().filter(mod => mod.id == id); + return !Util.isArrayEmpty(modsWithId) + } + + static uninstall(mod: string) { + let mods: Array = this.getTrackedMods(); + + // Replace underscores with spaces + mod = mod.replaceAll("_", " "); + + // Find mod to uninstall + const spinner = new PrintUtils.Spinner(`Uninstalling ${mod}...`) + let modToUninstall: Mod | undefined = undefined; + for (let modEle of mods) { + const id = modEle.id.toLowerCase(); + const name = modEle.name.toLowerCase(); + + const query = mod.toLowerCase(); + if (id == query || name == query) { + modToUninstall = modEle; + break; + } + } + + // IF a matching mod is found, remove it + if (modToUninstall != undefined) { + // Remove mod from list and uninstall it + unlinkSync(path.join(this.MODS_FOLDER_PATH, modToUninstall.fileName)); + mods = mods.filter(item => item !== modToUninstall); + this.writeFile(mods); + spinner.succeed(`${modToUninstall.name} successfully uninstalled!`) + } else { + spinner.error(`${mod} was not found.`) + } + + + + } } \ No newline at end of file