From c0df5cecb3d38a9a86757f0474f6f319ad3cf83a Mon Sep 17 00:00:00 2001 From: undefined Date: Sat, 23 Mar 2024 04:25:45 +0800 Subject: [PATCH] core: allow load from nix store --- packages/hydrooj/src/loader.ts | 24 ++++++++++++++++++++++-- packages/hydrooj/src/service/bus.ts | 2 +- packages/utils/lib/cases.ts | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/hydrooj/src/loader.ts b/packages/hydrooj/src/loader.ts index d08c75768..773e3195a 100644 --- a/packages/hydrooj/src/loader.ts +++ b/packages/hydrooj/src/loader.ts @@ -7,6 +7,7 @@ import './init'; import './interface'; import Schema from 'schemastery'; import path from 'path'; +import child from 'child_process'; // eslint-disable-next-line import/no-duplicates import './utils'; import cac from 'cac'; @@ -26,6 +27,21 @@ logger.debug('%o', argv); process.on('unhandledRejection', logger.error); process.on('uncaughtException', logger.error); +const HYDROPATH = []; + +if (process.env.NIX_PROFILES) { + try { + const result = JSON.parse(child.execSync('nix-env -q --json --out-path --meta').toString()) as Record; + for (const derivation of Object.values(result)) { + if (derivation.name.startsWith('hydro-plugin-') && derivation.outputs?.out) { + HYDROPATH.push(derivation.outputs.out); + } + } + } catch (e) { + logger.error('Nix detected, but failed to list installed derivations.'); + } +} + export function resolveConfig(plugin: any, config: any) { if (config === false) return; if (config === true) config = undefined; @@ -108,8 +124,12 @@ export class Loader { try { this.cache[name] ||= require.resolve(name); } catch (err) { - logger.error(err.message); - return; + try { + this.cache[name] ||= require.resolve(name, { paths: HYDROPATH }); + } catch (e) { + logger.error(err.message); + return; + } } return unwrapExports(require(this.cache[name])); } diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index fecf86a30..25e5f442d 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -94,7 +94,7 @@ export interface EventMap extends LifecycleEvents, HandlerEvents { 'contest/before-add': (payload: Partial) => VoidReturn 'contest/add': (payload: Partial, id: ObjectId) => VoidReturn - 'contest/list': (query: Fileter, handler: any) => VoidReturn + 'contest/list': (query: Filter, handler: any) => VoidReturn 'contest/scoreboard': (tdoc: Tdoc, rows: ScoreboardRow[], udict: BaseUserDict, pdict: ProblemDict) => VoidReturn 'contest/balloon': (domainId: string, tid: ObjectId, bdoc: ContestBalloonDoc) => VoidReturn diff --git a/packages/utils/lib/cases.ts b/packages/utils/lib/cases.ts index 641ae72fd..bfabb7540 100644 --- a/packages/utils/lib/cases.ts +++ b/packages/utils/lib/cases.ts @@ -44,7 +44,7 @@ export function convertIniConfig(ini: string) { const count = parseInt(f[0], 10); const res = { subtasks: [] }; for (let i = 1; i <= count; i++) { - if (!f[i] || !f[i].trim()) throw new Error('Testcada count incorrect.'); + if (!f[i]?.trim()) throw new Error('Testdata count incorrect.'); const [input, output, time, score, memory] = f[i].split('|'); const cur = { cases: [{ input, output }],