Get confirmation for mod installation by default.

This commit is contained in:
Kallum Jones 2022-08-14 14:47:18 +01:00
parent f7be866698
commit 8398afcfb4
No known key found for this signature in database
GPG Key ID: D7F4589C4D7F81A9
3 changed files with 51 additions and 43 deletions

View File

@ -9,10 +9,11 @@ export default class InstallCommand implements Subcommand {
.description("Installs the provided mods") .description("Installs the provided mods")
.argument("<mods...>", "The mods to install") .argument("<mods...>", "The mods to install")
.option("-e, --essential", "Marks these mods as essential", false) .option("-e, --essential", "Marks these mods as essential", false)
.action(function () { .option("-f, --force", "Automatically confirms the confirmation prompt", false)
.action((mods, options) => {
ModManager.execute(async () => { ModManager.execute(async () => {
for (const mod of this.args) { for (const mod of mods) {
await Mods.install(mod, this.opts().essential); await Mods.install(mod, options.essential, options.force);
} }
}) })
}); });

View File

@ -7,7 +7,6 @@ import Util from "../util/util.js";
import ModManager from "../mod-manager.js"; import ModManager from "../mod-manager.js";
import MinecraftUtils from "../util/minecraft_utils.js"; import MinecraftUtils from "../util/minecraft_utils.js";
import MigrateError from "../errors/migrate_error.js"; import MigrateError from "../errors/migrate_error.js";
import inquirer from "inquirer";
import { StringBuilder } from 'typescript-string-operations'; import { StringBuilder } from 'typescript-string-operations';
import chalk from "chalk"; import chalk from "chalk";
@ -24,34 +23,36 @@ export default class Mods {
this.MOD_SOURCES.push(source); this.MOD_SOURCES.push(source);
} }
public static async install(mod: string, essential: boolean): Promise<void> { public static async install(mod: string, essential: boolean, confirm: boolean): Promise<void> {
let success: boolean = false;
// Go through each mod source // Go through each mod source
for (const source of this.MOD_SOURCES) { for (const source of this.MOD_SOURCES) {
// If we have not yet successfully installed the queried mod const spinner = new PrintUtils.Spinner(`Searching for ${mod}...`);
if (!success) { spinner.start();
const spinner = new PrintUtils.Spinner(`Searching for ${mod}...`);
spinner.start();
// Search for the mod // Search for the mod
let id: string | undefined; let id: string | undefined;
try { try {
id = await source.search(mod); id = await source.search(mod);
} catch (e) { } catch (e) {
if (e instanceof ModNotFoundError) { if (e instanceof ModNotFoundError) {
spinner.stop(`Mod ${mod} not found on ${source.getSourceName()}`) spinner.stop(`Mod ${mod} not found on ${source.getSourceName()}`)
} else { } else {
spinner.error(`An error occurred searching for ${mod} on ${source.getSourceName()}. Skipping ${source.getSourceName()}`) spinner.error(`An error occurred searching for ${mod} on ${source.getSourceName()}. Skipping ${source.getSourceName()}`)
// Try the next source }
continue; }
}
// If a mod is found
if (id != undefined) {
const projectName = await source.getProjectName(id);
// Ask user whether this mod is correct
if (!confirm) {
spinner.pause();
confirm = await Util.getYesNoFromUser(`Confirm installation of ${projectName} from ${source.getSourceName()}? (y/n)`)
} }
// If a mod is found, install it // If user has confirmed installation
if (id != undefined) { if (confirm) {
const projectName = await source.getProjectName(id);
// If mod is not already installed // If mod is not already installed
if (!this.isModInstalled(id)) { if (!this.isModInstalled(id)) {
spinner.updateText(`Installing ${projectName}...`) spinner.updateText(`Installing ${projectName}...`)
@ -61,7 +62,7 @@ export default class Mods {
await source.install(latestVersion, essential); await source.install(latestVersion, essential);
spinner.succeed(`Successfully installed ${projectName}`); spinner.succeed(`Successfully installed ${projectName}`);
success = true; return;
} catch (e) { } catch (e) {
// Log the error, and continue to next source // Log the error, and continue to next source
spinner.error(e); spinner.error(e);
@ -120,20 +121,8 @@ export default class Mods {
spinner.pause(); spinner.pause();
const dependantMods = Mods.getDependantMods(modToUninstall.id); const dependantMods = Mods.getDependantMods(modToUninstall.id);
const answer = await inquirer.prompt([{ const question = chalk.yellowBright(`${modToUninstall.name} is depended on by ${Mods.modListToSting(dependantMods)}. Are you sure you would like to uninstall? (y/n)`);
type: "input", del = await Util.getYesNoFromUser(question);
name: "delete",
message: chalk.yellowBright(`${modToUninstall.name} is depended on by ${Mods.modListToSting(dependantMods)}. Are you sure you would like to uninstall? (y/n)`),
async validate(input: any): Promise<string | boolean> {
const lowerInput = input.toLowerCase();
const valid = lowerInput === "y" || lowerInput === "n" ;
if (!valid) {
return "Please answer either y or n"
}
return valid
},
}])
del = Util.getBoolFromYesNo(answer.delete);
} }
// If we are deleting this mod, uninstall it // If we are deleting this mod, uninstall it

View File

@ -1,4 +1,5 @@
import {stringSimilarity} from "string-similarity-js"; import {stringSimilarity} from "string-similarity-js";
import inquirer from "inquirer";
export default class Util { export default class Util {
private static readonly SIMILARITY_THRESHOLD: number = 0.8; private static readonly SIMILARITY_THRESHOLD: number = 0.8;
@ -22,7 +23,24 @@ export default class Util {
return stringSimilarity(master, compare) >= this.SIMILARITY_THRESHOLD; return stringSimilarity(master, compare) >= this.SIMILARITY_THRESHOLD;
} }
static getBoolFromYesNo(answer: string) { static async getYesNoFromUser(question: string) {
const answer = await inquirer.prompt([{
type: "input",
name: "confirm",
message: question,
async validate(input: any): Promise<string | boolean> {
const lowerInput = input.toLowerCase();
const valid = lowerInput === "y" || lowerInput === "n" ;
if (!valid) {
return "Please answer either y or n"
}
return valid
},
}])
return Util.getBoolFromYesNo(answer.confirm);
}
private static getBoolFromYesNo(answer: string) {
if (answer.toLowerCase() === "y") { if (answer.toLowerCase() === "y") {
return true; return true;
} else if (answer.toLowerCase() === "n") { } else if (answer.toLowerCase() === "n") {