From 78d2a1e560fe1c6b25b3755abdd6f4f53df43287 Mon Sep 17 00:00:00 2001 From: Daryl Ronningen Date: Sat, 10 Sep 2022 18:33:27 -0700 Subject: [PATCH] feat: make sysroot a global option and make package details install to sysroot too --- src/commands/install.ts | 27 ++++++++++++++------------- src/commands/list.ts | 13 ++++++++++++- src/commands/uninstall.ts | 17 +++++++++++------ src/index.ts | 26 +++++++++++--------------- src/utils.ts | 12 ++++++++++++ 5 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/commands/install.ts b/src/commands/install.ts index 439a5f9..b7fa96c 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -6,7 +6,8 @@ import path from 'node:path'; import os from 'node:os'; import tar from 'tar'; -import { parseWahInfo, walk } from '../utils.js'; +import { GlobalOptions } from '../index.js'; +import { makeDbFile, parseWahInfo, walk } from '../utils.js'; export default class Install { public name: string; @@ -25,8 +26,10 @@ export default class Install { process.exit(1); } - if (!await fs.pathExists(path.join(os.tmpdir(), 'wahpkg'))) await fs.mkdir(path.join(os.tmpdir(), 'wahpkg')); - const makeExtractDir = await fs.mkdtemp(path.join(os.tmpdir(), 'wahpkg', `${path.basename(this.options.file)}-`)); + await makeDbFile(this.options.sysroot); + + if (!await fs.pathExists(path.join(this.options.sysroot, os.tmpdir(), 'wahpkg'))) await fs.mkdirp(path.join(this.options.sysroot, os.tmpdir(), 'wahpkg')); + const makeExtractDir = await fs.mkdtemp(path.join(this.options.sysroot, os.tmpdir(), 'wahpkg', `${path.basename(this.options.file)}-`)); if (this.options.file) { this.path = path.join(process.cwd(), this.options.file); @@ -40,7 +43,7 @@ export default class Install { const readWahInfo = await fs.readFile(path.join(makeExtractDir, '.WAHINFO')); const getWahInfo = parseWahInfo(readWahInfo.toString()); - const dbFile = '/var/lib/wahpkg/pkgs.json'; + const dbFile = `${this.options.sysroot}/var/lib/wahpkg/pkgs.json`; const adapter = new lowdb.JSONFile(dbFile); const db = new lowdb.Low(adapter); @@ -57,10 +60,9 @@ export default class Install { }); await db.write(); - if (!await fs.pathExists('/var/lib/wahpkg/pkgs')) await fs.mkdir('/var/lib/wahpkg/pkgs'); - await fs.mkdir(`/var/lib/wahpkg/pkgs/${getWahInfo.name}`); - await fs.writeFile(`/var/lib/wahpkg/pkgs/${getWahInfo.name}/MD5HASHES`, ''); - const md5Adapter = new lowdb.TextFile(`/var/lib/wahpkg/pkgs/${getWahInfo.name}/MD5HASHES`); + await fs.mkdirp(`${this.options.sysroot}/var/lib/wahpkg/pkgs/${getWahInfo.name}`); + await fs.writeFile(`${this.options.sysroot}/var/lib/wahpkg/pkgs/${getWahInfo.name}/MD5HASHES`, ''); + const md5Adapter = new lowdb.TextFile(`${this.options.sysroot}/var/lib/wahpkg/pkgs/${getWahInfo.name}/MD5HASHES`); await md5Adapter.read(); @@ -68,14 +70,14 @@ export default class Install { for (const file of await walk(makeExtractDir)) { if (file.endsWith('.WAHINFO')) continue; - const readFile = await fs.readFile(file); + const readFile = await fs.readFile(path.join(file)); const hash = crypto.createHash('md5').update(readFile).digest('hex'); - toWriteToFile += `${file.replace(`${makeExtractDir}/ROOT`, this.options.sysroot)} ${hash}\n`; + toWriteToFile += `${file.replace(`${makeExtractDir}/ROOT`, '')} ${hash}\n`; } await md5Adapter.write(toWriteToFile); - await fs.move(path.join(makeExtractDir, 'ROOT'), path.join(this.options.sysroot), { overwrite: true }); + await fs.copy(path.join(makeExtractDir, 'ROOT'), path.join(this.options.sysroot), { overwrite: true, dereference: false, preserveTimestamps: true, recursive: true }); await fs.rm(path.join(makeExtractDir), { recursive: true, force: true }); console.log(chalk.bold.green`Package %s has been installed!`, getWahInfo.name); @@ -84,9 +86,8 @@ export default class Install { } } -export interface InstallOptions { +export interface InstallOptions extends GlobalOptions { file: string; - sysroot: string; } export interface dbData { diff --git a/src/commands/list.ts b/src/commands/list.ts index 85c6b62..cde2bea 100644 --- a/src/commands/list.ts +++ b/src/commands/list.ts @@ -1,10 +1,21 @@ import * as lowdb from 'lowdb'; +import { GlobalOptions } from '../index.js'; +import { makeDbFile } from '../utils.js'; import { dbData } from './install.js'; export default class List { + public options: GlobalOptions; + + public constructor(options: GlobalOptions) { + this.options = options; + } + + public async run(): Promise { - const dbFile = '/var/lib/wahpkg/pkgs.json'; + await makeDbFile(this.options.sysroot); + + const dbFile = `${this.options.sysroot}/var/lib/wahpkg/pkgs.json`; const adapter = new lowdb.JSONFile(dbFile); const db = new lowdb.Low(adapter); diff --git a/src/commands/uninstall.ts b/src/commands/uninstall.ts index 531212b..c7c43c9 100644 --- a/src/commands/uninstall.ts +++ b/src/commands/uninstall.ts @@ -2,7 +2,10 @@ import chalk from 'chalk'; import fs from 'fs-extra'; import * as lowdb from 'lowdb'; import crypto from 'node:crypto'; +import path from 'node:path'; +import { GlobalOptions } from '../index.js'; +import { makeDbFile } from '../utils.js'; import { dbData } from './install.js'; export default class Uninstall { @@ -15,8 +18,10 @@ export default class Uninstall { } public async run(): Promise { + await makeDbFile(this.options.sysroot); + if (this.name) { - const dbFile = '/var/lib/wahpkg/pkgs.json'; + const dbFile = `${this.options.sysroot}/var/lib/wahpkg/pkgs.json`; const adapter = new lowdb.JSONFile(dbFile); const db = new lowdb.Low(adapter); @@ -27,7 +32,7 @@ export default class Uninstall { process.exit(1); } - const md5File = await fs.readFile(`/var/lib/wahpkg/pkgs/${this.name}/MD5HASHES`); + const md5File = await fs.readFile(`${this.options.sysroot}/var/lib/wahpkg/pkgs/${this.name}/MD5HASHES`); for (const file of md5File.toString().split('\n')) { const fileName = file.split(' ')[0]; @@ -36,17 +41,17 @@ export default class Uninstall { // Ignore blank or last line if (fileName === '') continue; - const verifyHash = crypto.createHash('md5').update(await fs.readFile(fileName)).digest('hex'); + const verifyHash = crypto.createHash('md5').update(await fs.readFile(path.join(this.options.sysroot, 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.rm(fileName); + await fs.rm(path.join(this.options.sysroot, fileName)); } } - await fs.rm(`/var/lib/wahpkg/pkgs/${this.name}`, { force: true, recursive: true }); + await fs.rm(`${this.options.sysroot}/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(); @@ -57,6 +62,6 @@ export default class Uninstall { } } -export interface UninstallOptions { +export interface UninstallOptions extends GlobalOptions { 'ignore-hash': string; } diff --git a/src/index.ts b/src/index.ts index f891eb2..5456b36 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,5 @@ import chalk from 'chalk'; import { Command } from 'commander'; -import fs from 'fs-extra'; import Install, { InstallOptions } from './commands/install.js'; import List from './commands/list.js'; @@ -13,27 +12,18 @@ if (process.getuid() !== 0) { const program = new Command(); -if (!await fs.pathExists('/var/lib/wahpkg/pkgs.json')) { - console.log(chalk.green.bold`It looks like this is your first time using wahpkg! Setting up database for first use...`); - - await fs.mkdir('/var/lib/wahpkg', { recursive: true }); - await fs.writeFile('/var/lib/wahpkg/pkgs.json', Buffer.from('{"dbVersion": 1, "pkgs": []}', 'utf8')); - - console.log(chalk.green.bold`wahpkg was successfully setup!`); -} - program .name('wahpkg') .description('Package Manager for WahOS') - .version('0.0.1'); + .version('0.0.1') + .option('-s, --sysroot ', 'Where to install the package', '/'); program.command('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 /)', '/') .action(async (name: string, options: InstallOptions) => { - await new Install(name, options).run(); + await new Install(name, { ...options, ...program.optsWithGlobals() }).run(); }); program.command('uninstall') @@ -41,13 +31,19 @@ program.command('uninstall') .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(); + await new Uninstall(name, { ...options, ...program.optsWithGlobals() }).run(); }); program.command('list') .description('List installed packages') .action(async () => { - await new List().run(); + await new List(program.optsWithGlobals()).run(); }); program.parse(); + +export interface GlobalOptions { + sysroot: string; +} + +export { program }; diff --git a/src/utils.ts b/src/utils.ts index a65f84d..9c282b5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,4 @@ +import chalk from 'chalk'; import fs from 'fs-extra'; import path from 'node:path'; import type { PartialDeep, RequireAllOrNone } from 'type-fest'; @@ -60,6 +61,17 @@ export const walk = async (dir: string): Promise => { }); }; +export const makeDbFile = async (sysroot: string): Promise => { + if (!await fs.pathExists(`${sysroot}/var/lib/wahpkg/pkgs.json`)) { + console.log(chalk.green.bold`It looks like this is your first time using wahpkg! Setting up database for first use...`); + + await fs.mkdirp(`${sysroot}/var/lib/wahpkg`); + await fs.writeFile(`${sysroot}/var/lib/wahpkg/pkgs.json`, Buffer.from('{"dbVersion": 1, "pkgs": []}', 'utf8')); + + console.log(chalk.green.bold`wahpkg was successfully setup!`); + } +}; + export interface WahInfo { name: string; version: {