feat: add simple JSON DB and .WAHINFO spec
This commit is contained in:
parent
1d06c7362b
commit
f006bea203
8 changed files with 142 additions and 8 deletions
|
@ -21,7 +21,7 @@ module.exports = {
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
indent: ['error', 'tab'],
|
indent: ['error', 'tab', { 'SwitchCase': 1 }],
|
||||||
'linebreak-style': [
|
'linebreak-style': [
|
||||||
'error',
|
'error',
|
||||||
'unix',
|
'unix',
|
||||||
|
|
|
@ -13,8 +13,10 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.0.1",
|
"chalk": "^5.0.1",
|
||||||
"commander": "^9.4.0",
|
"commander": "^9.4.0",
|
||||||
|
"lowdb": "^3.0.0",
|
||||||
"mv": "^2.1.1",
|
"mv": "^2.1.1",
|
||||||
"tar": "^6.1.11"
|
"tar": "^6.1.11",
|
||||||
|
"type-fest": "^2.19.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^22.0.2",
|
"@rollup/plugin-commonjs": "^22.0.2",
|
||||||
|
|
|
@ -9,5 +9,10 @@ export default {
|
||||||
dir: 'dist',
|
dir: 'dist',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
},
|
},
|
||||||
plugins: [commonjs(), nodeResolve({ exportConditions: ['node'] }), typescript(), terser()],
|
plugins: [
|
||||||
|
commonjs(),
|
||||||
|
nodeResolve({ exportConditions: ['node'] }),
|
||||||
|
typescript(),
|
||||||
|
terser(),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import * as lowdb from 'lowdb';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import tar from 'tar';
|
import tar from 'tar';
|
||||||
import mv from 'mv';
|
import mv from 'mv';
|
||||||
|
|
||||||
|
import { parseWahInfo } from '../utils.js';
|
||||||
|
|
||||||
export default class Install {
|
export default class Install {
|
||||||
public name: string;
|
public name: string;
|
||||||
public options: InstallOptions;
|
public options: InstallOptions;
|
||||||
|
@ -17,24 +20,45 @@ export default class Install {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
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) {
|
if (!this.options.file || this.name) {
|
||||||
console.error(chalk.red.bold`Installing packages via repositories are not supported yet! Please do "--file" instead!`);
|
console.error(chalk.red.bold`Installing packages via repositories are not supported yet! Please do "--file" instead!`);
|
||||||
process.exit(1);
|
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) {
|
if (this.options.file) {
|
||||||
this.path = path.join(process.cwd(), this.options.file);
|
this.path = path.join(process.cwd(), this.options.file);
|
||||||
await tar.x({ cwd: path.join(makeExtractDir), file: this.path });
|
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<void>((res, rej) => {
|
await new Promise<void>((res, rej) => {
|
||||||
mv(path.join(makeExtractDir, 'ROOT'), path.join(this.options.sysroot), { mkdirp: true }, (err) => { if (err) rej(err); else res(); });
|
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 });
|
await fs.promises.rm(path.join(makeExtractDir), { recursive: true, force: true });
|
||||||
|
|
||||||
|
const dbFile = '/var/lib/wahpkg/pkgs.json';
|
||||||
|
const adapter = new lowdb.JSONFile<dbData>(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;
|
file: string;
|
||||||
sysroot: string;
|
sysroot: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface dbData {
|
||||||
|
dbVersion: number;
|
||||||
|
pkgs: {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
16
src/index.ts
16
src/index.ts
|
@ -1,9 +1,25 @@
|
||||||
|
import chalk from 'chalk';
|
||||||
import { Command } from 'commander';
|
import { Command } from 'commander';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
|
||||||
import Install, { InstallOptions } from './commands/install.js';
|
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();
|
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
|
program
|
||||||
.name('wahpkg')
|
.name('wahpkg')
|
||||||
.description('Package Manager for WahOS')
|
.description('Package Manager for WahOS')
|
||||||
|
|
52
src/utils.ts
Normal file
52
src/utils.ts
Normal file
|
@ -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<WahInfo> = {};
|
||||||
|
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<WahInfo>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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',
|
||||||
|
}
|
|
@ -6,6 +6,8 @@
|
||||||
"ES2022",
|
"ES2022",
|
||||||
"dom"
|
"dom"
|
||||||
],
|
],
|
||||||
"allowSyntheticDefaultImports": true
|
"target": "ES2022",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"esModuleInterop": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
yarn.lock
25
yarn.lock
|
@ -2182,6 +2182,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"lowercase-keys@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "lowercase-keys@npm:2.0.0"
|
resolution: "lowercase-keys@npm:2.0.0"
|
||||||
|
@ -3101,6 +3110,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"stream-buffers@npm:^3.0.2":
|
||||||
version: 3.0.2
|
version: 3.0.2
|
||||||
resolution: "stream-buffers@npm:3.0.2"
|
resolution: "stream-buffers@npm:3.0.2"
|
||||||
|
@ -3304,6 +3320,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"typescript@npm:^4.8.2":
|
||||||
version: 4.8.2
|
version: 4.8.2
|
||||||
resolution: "typescript@npm:4.8.2"
|
resolution: "typescript@npm:4.8.2"
|
||||||
|
@ -3380,12 +3403,14 @@ __metadata:
|
||||||
chalk: "npm:^5.0.1"
|
chalk: "npm:^5.0.1"
|
||||||
commander: "npm:^9.4.0"
|
commander: "npm:^9.4.0"
|
||||||
eslint: "npm:^8.23.0"
|
eslint: "npm:^8.23.0"
|
||||||
|
lowdb: "npm:^3.0.0"
|
||||||
mv: "npm:^2.1.1"
|
mv: "npm:^2.1.1"
|
||||||
rollup: "npm:^2.78.1"
|
rollup: "npm:^2.78.1"
|
||||||
rollup-plugin-terser: "npm:^7.0.2"
|
rollup-plugin-terser: "npm:^7.0.2"
|
||||||
rollup-plugin-typescript2: "npm:^0.33.0"
|
rollup-plugin-typescript2: "npm:^0.33.0"
|
||||||
tar: "npm:^6.1.11"
|
tar: "npm:^6.1.11"
|
||||||
tslib: "npm:^2.4.0"
|
tslib: "npm:^2.4.0"
|
||||||
|
type-fest: "npm:^2.19.0"
|
||||||
typescript: "npm:^4.8.2"
|
typescript: "npm:^4.8.2"
|
||||||
bin:
|
bin:
|
||||||
wahpkg: ./dist/index.js
|
wahpkg: ./dist/index.js
|
||||||
|
|
Reference in a new issue