diff --git a/src/commands/install.ts b/src/commands/install.ts index 3f5747c..652b996 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -75,7 +75,9 @@ export default class Install { }); await fs.promises.rm(path.join(makeExtractDir), { recursive: true, force: true }); + console.log(chalk.bold.green`Package %s has been installed!`, getWahInfo.name); + process.exit(0); } } } diff --git a/src/commands/uninstall.ts b/src/commands/uninstall.ts new file mode 100644 index 0000000..a261423 --- /dev/null +++ b/src/commands/uninstall.ts @@ -0,0 +1,62 @@ +import chalk from 'chalk'; +import * as lowdb from 'lowdb'; +import crypto from 'node:crypto'; +import fs from 'node:fs'; + +import { dbData } from './install.js'; + +export default class Uninstall { + public name: string; + public options: UninstallOptions; + + public constructor(name: string, options: UninstallOptions) { + this.name = name; + this.options = options; + } + + public async run(): Promise { + if (this.name) { + const dbFile = '/var/lib/wahpkg/pkgs.json'; + const adapter = new lowdb.JSONFile(dbFile); + const db = new lowdb.Low(adapter); + + await db.read(); + + if (!db.data.pkgs.find((val) => val.name === this.name)) { + console.error(chalk.red.bold`%s is not installed!`, this.name); + process.exit(1); + } + + const md5File = await fs.promises.readFile(`/var/lib/wahpkg/pkgs/${this.name}/MD5HASHES`); + + for (const file of md5File.toString().split('\n')) { + const fileName = file.split(' ')[0]; + const hash = file.split(' ')[1]; + + // Ignore blank or last line + if (fileName === '') continue; + + const verifyHash = crypto.createHash('md5').update(await fs.promises.readFile(fileName)).digest('hex'); + + if (verifyHash !== hash && this.options['ignore-hash']) { + console.error(chalk.red.bold`%s does not match MD5 hash of %s! To ignore this error, please add --ignore-hash in the command`, this.name, hash); + process.exit(1); + } else { + await fs.promises.rm(fileName); + } + } + + await fs.promises.rm(`/var/lib/wahpkg/pkgs/${this.name}`, { force: true, recursive: true }); + + db.data.pkgs = db.data.pkgs.filter((item) => item.name !== this.name); + await db.write(); + + console.log(chalk.green.bold`%s has been successfully removed!`, this.name); + process.exit(0); + } + } +} + +export interface UninstallOptions { + 'ignore-hash': string; +} diff --git a/src/index.ts b/src/index.ts index aeb608c..a021354 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import { Command } from 'commander'; import fs from 'node:fs'; import Install, { InstallOptions } from './commands/install.js'; +import Uninstall, { UninstallOptions } from './commands/uninstall.js'; if (process.getuid() !== 0) { console.log(chalk.red.bold`Please run wahpkg as root!`); @@ -26,7 +27,7 @@ program .version('0.0.1'); program.command('install') - .description('Package to install') + .description('Install package') .argument('[name]', 'Package name to install') .option('-f, --file ', 'Install from file instead from repository') .option('-s, --sysroot ', 'Where to install the package. (Defaults to /)', '/') @@ -34,4 +35,12 @@ program.command('install') await new Install(name, options).run(); }); +program.command('uninstall') + .description('Uninstall package') + .argument('', 'Package name to uninstall') + .option('-i, --ignore-hash', 'Ignore MD5 hash mismatches') + .action(async (name: string, options: UninstallOptions) => { + await new Uninstall(name, options).run(); + }); + program.parse();