mirror of
https://git.bits.team/Bits/mod-manager.git
synced 2024-12-21 20:08:21 -05:00
Require confirmation when uninstalling mods that are depended on
This commit is contained in:
parent
76f6c2c475
commit
f7be866698
13
package-lock.json
generated
13
package-lock.json
generated
@ -19,7 +19,8 @@
|
||||
"ora": "^6.1.2",
|
||||
"pino": "^8.3.1",
|
||||
"string-format": "^2.0.0",
|
||||
"string-similarity-js": "^2.1.4"
|
||||
"string-similarity-js": "^2.1.4",
|
||||
"typescript-string-operations": "^1.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.6.3",
|
||||
@ -835,6 +836,11 @@
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript-string-operations": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript-string-operations/-/typescript-string-operations-1.4.1.tgz",
|
||||
"integrity": "sha512-c+q+Tb0hxeebohdT9KpGUAm5zwxhU8pHeNOeuLCGFMXKN0OrldoAxtufrGLR3xSPCXDA4A3IBCEdRNNscVqLQg=="
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
@ -1416,6 +1422,11 @@
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript-string-operations": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript-string-operations/-/typescript-string-operations-1.4.1.tgz",
|
||||
"integrity": "sha512-c+q+Tb0hxeebohdT9KpGUAm5zwxhU8pHeNOeuLCGFMXKN0OrldoAxtufrGLR3xSPCXDA4A3IBCEdRNNscVqLQg=="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
@ -21,7 +21,8 @@
|
||||
"ora": "^6.1.2",
|
||||
"pino": "^8.3.1",
|
||||
"string-format": "^2.0.0",
|
||||
"string-similarity-js": "^2.1.4"
|
||||
"string-similarity-js": "^2.1.4",
|
||||
"typescript-string-operations": "^1.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.6.3",
|
||||
|
@ -9,9 +9,9 @@ export default class UninstallCommand implements Subcommand {
|
||||
.description("Uninstalls the provided mods")
|
||||
.argument("<mods...>", "The mods to uninstall (as names or ids)")
|
||||
.action((mods) => {
|
||||
ModManager.execute(() => {
|
||||
ModManager.execute(async () => {
|
||||
for (let mod of mods) {
|
||||
Mods.uninstall(mod);
|
||||
await Mods.uninstall(mod);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -7,6 +7,9 @@ import Util from "../util/util.js";
|
||||
import ModManager from "../mod-manager.js";
|
||||
import MinecraftUtils from "../util/minecraft_utils.js";
|
||||
import MigrateError from "../errors/migrate_error.js";
|
||||
import inquirer from "inquirer";
|
||||
import { StringBuilder } from 'typescript-string-operations';
|
||||
import chalk from "chalk";
|
||||
|
||||
export default class Mods {
|
||||
private static readonly MOD_SOURCES: Array<ModSource> = [];
|
||||
@ -97,26 +100,60 @@ export default class Mods {
|
||||
return !Util.isArrayEmpty(modsWithId)
|
||||
}
|
||||
|
||||
static uninstall(mod: string) {
|
||||
private static getDependantMods(dependency: string) {
|
||||
return this.getTrackedMods().filter(mod => mod.dependencies.includes(dependency))
|
||||
}
|
||||
|
||||
static async uninstall(mod: string) {
|
||||
// Find mod to uninstall
|
||||
const modToUninstall = this.findMod(mod);
|
||||
|
||||
const spinner = new PrintUtils.Spinner(`Uninstalling ${mod}...`)
|
||||
spinner.start();
|
||||
|
||||
const modToUninstall = this.findMod(mod);
|
||||
// IF a matching mod is found, remove it
|
||||
// If a matching mod is found, remove it
|
||||
if (modToUninstall != undefined) {
|
||||
this.silentUninstall(modToUninstall);
|
||||
|
||||
for (let dependency of modToUninstall.dependencies) {
|
||||
if (!this.isDependedOn(dependency)) {
|
||||
const dependencyMod = this.findMod(dependency);
|
||||
if (dependencyMod != undefined) {
|
||||
this.silentUninstall(dependencyMod)
|
||||
}
|
||||
}
|
||||
// Ensure the user wants to delete this mod
|
||||
let del = true;
|
||||
if (Mods.isDependedOn(modToUninstall.id)) {
|
||||
spinner.pause();
|
||||
|
||||
const dependantMods = Mods.getDependantMods(modToUninstall.id);
|
||||
const answer = await inquirer.prompt([{
|
||||
type: "input",
|
||||
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 (del) {
|
||||
spinner.start()
|
||||
this.silentUninstall(modToUninstall);
|
||||
|
||||
// Remove any left over dependencies that are not depended on by any other mod
|
||||
for (let dependency of modToUninstall.dependencies) {
|
||||
if (!this.isDependedOn(dependency)) {
|
||||
const dependencyMod = this.findMod(dependency);
|
||||
if (dependencyMod != undefined) {
|
||||
this.silentUninstall(dependencyMod)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spinner.succeed(`${modToUninstall.name} successfully uninstalled!`)
|
||||
}
|
||||
|
||||
spinner.succeed(`${modToUninstall.name} successfully uninstalled!`)
|
||||
} else {
|
||||
spinner.error(`${mod} was not found.`)
|
||||
}
|
||||
@ -366,13 +403,14 @@ export default class Mods {
|
||||
}
|
||||
|
||||
private static isDependedOn(dependency: string) {
|
||||
const trackedMods = this.getTrackedMods();
|
||||
return Mods.getDependantMods(dependency).length != 0
|
||||
}
|
||||
|
||||
for (let trackedMod of trackedMods) {
|
||||
if (trackedMod.dependencies.includes(dependency)) {
|
||||
return true;
|
||||
}
|
||||
private static modListToSting(dependantMods: TrackedMod[]) {
|
||||
const builder = new StringBuilder();
|
||||
for (let dependantMod of dependantMods) {
|
||||
builder.Append(dependantMod.name)
|
||||
}
|
||||
return false;
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
@ -24,6 +24,10 @@ export default class PrintUtils {
|
||||
this.spinner.stopAndPersist();
|
||||
}
|
||||
|
||||
public pause() {
|
||||
this.spinner.stop();
|
||||
}
|
||||
|
||||
public error(print: string | Error) {
|
||||
if (print instanceof Error) {
|
||||
this.spinner.fail(print.message)
|
||||
|
@ -21,4 +21,14 @@ export default class Util {
|
||||
compare = compare.toLowerCase();
|
||||
return stringSimilarity(master, compare) >= this.SIMILARITY_THRESHOLD;
|
||||
}
|
||||
|
||||
static getBoolFromYesNo(answer: string) {
|
||||
if (answer.toLowerCase() === "y") {
|
||||
return true;
|
||||
} else if (answer.toLowerCase() === "n") {
|
||||
return false
|
||||
} else {
|
||||
throw new Error("Invalid answer to get a boolean value from")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user