From f006bea20373aa626c87fbf4a32ed61ce28b83ce Mon Sep 17 00:00:00 2001 From: Daryl Ronningen Date: Tue, 30 Aug 2022 00:13:19 -0700 Subject: [PATCH] feat: add simple JSON DB and .WAHINFO spec --- .eslintrc.cjs | 2 +- package.json | 4 +++- rollup.config.js | 7 +++++- src/commands/install.ts | 40 +++++++++++++++++++++++++++---- src/index.ts | 16 +++++++++++++ src/utils.ts | 52 +++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 4 +++- yarn.lock | 25 ++++++++++++++++++++ 8 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 src/utils.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 73afeb4..0d41d32 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -21,7 +21,7 @@ module.exports = { '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', - indent: ['error', 'tab'], + indent: ['error', 'tab', { 'SwitchCase': 1 }], 'linebreak-style': [ 'error', 'unix', diff --git a/package.json b/package.json index b03a13f..b280e6e 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "dependencies": { "chalk": "^5.0.1", "commander": "^9.4.0", + "lowdb": "^3.0.0", "mv": "^2.1.1", - "tar": "^6.1.11" + "tar": "^6.1.11", + "type-fest": "^2.19.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^22.0.2", diff --git a/rollup.config.js b/rollup.config.js index 5bdf877..ac4358a 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -9,5 +9,10 @@ export default { dir: 'dist', format: 'esm', }, - plugins: [commonjs(), nodeResolve({ exportConditions: ['node'] }), typescript(), terser()], + plugins: [ + commonjs(), + nodeResolve({ exportConditions: ['node'] }), + typescript(), + terser(), + ], }; diff --git a/src/commands/install.ts b/src/commands/install.ts index 1c3da59..5d2903a 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -1,10 +1,13 @@ import chalk from 'chalk'; +import * as lowdb from 'lowdb'; import fs from 'node:fs'; import path from 'node:path'; import os from 'node:os'; import tar from 'tar'; import mv from 'mv'; +import { parseWahInfo } from '../utils.js'; + export default class Install { public name: string; public options: InstallOptions; @@ -17,24 +20,45 @@ export default class Install { } public async run(): Promise { - if (!fs.existsSync(path.join(os.tmpdir(), 'wahpkg'))) await fs.promises.mkdir(path.join(os.tmpdir(), 'wahpkg')); - - const makeExtractDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'wahpkg', `${path.basename(this.options.file)}-`)); - if (!this.options.file || this.name) { console.error(chalk.red.bold`Installing packages via repositories are not supported yet! Please do "--file" instead!`); process.exit(1); } + if (!fs.existsSync(path.join(os.tmpdir(), 'wahpkg'))) await fs.promises.mkdir(path.join(os.tmpdir(), 'wahpkg')); + const makeExtractDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'wahpkg', `${path.basename(this.options.file)}-`)); + + if (this.options.file) { this.path = path.join(process.cwd(), this.options.file); await tar.x({ cwd: path.join(makeExtractDir), file: this.path }); + if (!fs.existsSync(path.join(makeExtractDir, '.WAHINFO'))) { + console.error(chalk.red.bold`.WAHINFO file does not exist in the selected package! The selected file is probably not a package.`); + process.exit(1); + } + + const readWahInfo = await fs.promises.readFile(path.join(makeExtractDir, '.WAHINFO')); + const getWahInfo = parseWahInfo(readWahInfo.toString()); + await new Promise((res, rej) => { mv(path.join(makeExtractDir, 'ROOT'), path.join(this.options.sysroot), { mkdirp: true }, (err) => { if (err) rej(err); else res(); }); }); await fs.promises.rm(path.join(makeExtractDir), { recursive: true, force: true }); + + const dbFile = '/var/lib/wahpkg/pkgs.json'; + const adapter = new lowdb.JSONFile(dbFile); + const db = new lowdb.Low(adapter); + + await db.read(); + db.data.pkgs.push({ + name: getWahInfo.name, + version: `${getWahInfo.version.major}.${getWahInfo.version.minor}.${getWahInfo.version.patch}-${getWahInfo.version.rel}`, + }); + await db.write(); + + console.log(chalk.bold.green`Package %s has been installed!`, getWahInfo.name); } } } @@ -43,3 +67,11 @@ export interface InstallOptions { file: string; sysroot: string; } + +export interface dbData { + dbVersion: number; + pkgs: { + name: string; + version: string; + }[]; +} diff --git a/src/index.ts b/src/index.ts index ef763e3..aeb608c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,25 @@ +import chalk from 'chalk'; import { Command } from 'commander'; +import fs from 'node:fs'; import Install, { InstallOptions } from './commands/install.js'; +if (process.getuid() !== 0) { + console.log(chalk.red.bold`Please run wahpkg as root!`); + process.exit(1); +} + const program = new Command(); +if (!fs.existsSync('/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.promises.mkdir('/var/lib/wahpkg', { recursive: true }); + await fs.promises.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') diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..3526bd6 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,52 @@ +import type { PartialDeep, RequireAllOrNone } from 'type-fest'; + +export function parseWahInfo(file: string): WahInfo { + const items = file.split('\n'); + const finalVal: PartialDeep = {}; + finalVal.version = {}; + + for (const item of items) { + const key: WahInfoKeys = WahInfoKeys[item.split('=')[0]]; + const val: string = item.split('=')[1]; + + switch (key) { + case WahInfoKeys.name: + finalVal.name = val; + break; + case WahInfoKeys.major: + finalVal.version.major = val; + break; + case WahInfoKeys.minor: + finalVal.version.minor = val; + break; + case WahInfoKeys.patch: + finalVal.version.patch = val; + break; + case WahInfoKeys.rel: + finalVal.version.rel = val; + break; + default: + break; + } + } + + return finalVal as RequireAllOrNone; +} + +export interface WahInfo { + name: string; + version: { + major: string; + minor: string; + patch: string; + rel: string; + } +} + +export enum WahInfoKeys { + name = 'name', + major = 'major', + minor = 'minor', + patch = 'patch', + rel = 'rel', +} diff --git a/tsconfig.json b/tsconfig.json index bf05ed3..2335ac3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,8 @@ "ES2022", "dom" ], - "allowSyntheticDefaultImports": true + "target": "ES2022", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true } } diff --git a/yarn.lock b/yarn.lock index 032a725..8dd6015 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2182,6 +2182,15 @@ __metadata: languageName: node linkType: hard +"lowdb@npm:^3.0.0": + version: 3.0.0 + resolution: "lowdb@npm:3.0.0" + dependencies: + steno: "npm:^2.1.0" + checksum: dd5e38ef8bccc2d7bf574dfb56b7d89d55732642a2d999e80227f381cbf6c938ac7a082bf3a9b8e70284a7cb9bb732bbc9e2453f5df816f89449e6467d4189b8 + languageName: node + linkType: hard + "lowercase-keys@npm:^2.0.0": version: 2.0.0 resolution: "lowercase-keys@npm:2.0.0" @@ -3101,6 +3110,13 @@ __metadata: languageName: node linkType: hard +"steno@npm:^2.1.0": + version: 2.1.0 + resolution: "steno@npm:2.1.0" + checksum: a9256c2b2430c0e6774e3077527d0636427da834c9cf4d6a8b7a44e576f10e720c4a98eca50e532f75146e8804562289aba4ab68a86041ec5a0282a4a6a31d11 + languageName: node + linkType: hard + "stream-buffers@npm:^3.0.2": version: 3.0.2 resolution: "stream-buffers@npm:3.0.2" @@ -3304,6 +3320,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^2.19.0": + version: 2.19.0 + resolution: "type-fest@npm:2.19.0" + checksum: d63c7c5fd7583cc6d35ccd23e96686eeb1e6f387c83a858625734ea2cf974c6be38bcbc43663da5e10469a1b4119089def1e8def03bf2aee540f0ad4fcd25902 + languageName: node + linkType: hard + "typescript@npm:^4.8.2": version: 4.8.2 resolution: "typescript@npm:4.8.2" @@ -3380,12 +3403,14 @@ __metadata: chalk: "npm:^5.0.1" commander: "npm:^9.4.0" eslint: "npm:^8.23.0" + lowdb: "npm:^3.0.0" mv: "npm:^2.1.1" rollup: "npm:^2.78.1" rollup-plugin-terser: "npm:^7.0.2" rollup-plugin-typescript2: "npm:^0.33.0" tar: "npm:^6.1.11" tslib: "npm:^2.4.0" + type-fest: "npm:^2.19.0" typescript: "npm:^4.8.2" bin: wahpkg: ./dist/index.js