mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
judge: use compileInteractor and per file cleanup
This commit is contained in:
1 parent
15ea8232a8
commit
5e113d9c7e
5 files changed
+48
-23
No files matched your search
@@ -43,7 +43,7 @@ export default async function compile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const testlibFile = {
|
const testlibFile = {
|
||||||
src: findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h')
|
src: findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const guessLanguage = (filename: string, getLang: Function) => {
|
const guessLanguage = (filename: string, getLang: Function) => {
|
||||||
@@ -70,6 +70,13 @@ export async function compileChecker(getLang: Function, checkerType: string, che
|
|||||||
return await compile(lang, { src: checker }, copyIn);
|
return await compile(lang, { src: checker }, copyIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function compileInteractor(getLang: Function, interactor: string, copyIn: any): Promise<Execute> {
|
||||||
|
const lang = guessLanguage(interactor, getLang);
|
||||||
|
if (!lang) throw new FormatError('Unknown interactor language.');
|
||||||
|
// TODO cache compiled checker
|
||||||
|
return await compile(lang, { src: interactor }, { ...copyIn, 'testlib.h': testlibFile });
|
||||||
|
}
|
||||||
|
|
||||||
export async function compileValidator(getLang: Function, validator: string, copyIn: any): Promise<Execute> {
|
export async function compileValidator(getLang: Function, validator: string, copyIn: any): Promise<Execute> {
|
||||||
const lang = guessLanguage(validator, getLang);
|
const lang = guessLanguage(validator, getLang);
|
||||||
if (!lang) throw new FormatError('Unknown validator language.');
|
if (!lang) throw new FormatError('Unknown validator language.');
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { STATUS } from '@hydrooj/utils/lib/status';
|
|||||||
import checkers from '../checkers';
|
import checkers from '../checkers';
|
||||||
import compile, { compileChecker } from '../compile';
|
import compile, { compileChecker } from '../compile';
|
||||||
import { runFlow } from '../flow';
|
import { runFlow } from '../flow';
|
||||||
|
import { Execute } from '../interface';
|
||||||
import { Logger } from '../log';
|
import { Logger } from '../log';
|
||||||
import { CmdFile, del, run } from '../sandbox';
|
import { CmdFile, del, run } from '../sandbox';
|
||||||
import signals from '../signals';
|
import signals from '../signals';
|
||||||
@@ -121,6 +122,10 @@ function judgeCase(c: NormalizedCase, sid: string) {
|
|||||||
|
|
||||||
export const judge = async (ctx: Context) => await runFlow(ctx, {
|
export const judge = async (ctx: Context) => await runFlow(ctx, {
|
||||||
compile: async () => {
|
compile: async () => {
|
||||||
|
const markCleanup = (i: Execute) => {
|
||||||
|
ctx.clean.push(i.clean);
|
||||||
|
return i;
|
||||||
|
};
|
||||||
[ctx.execute, ctx.checker] = await Promise.all([
|
[ctx.execute, ctx.checker] = await Promise.all([
|
||||||
compile(
|
compile(
|
||||||
ctx.session.getLang(ctx.lang), ctx.code,
|
ctx.session.getLang(ctx.lang), ctx.code,
|
||||||
@@ -128,7 +133,7 @@ export const judge = async (ctx: Context) => await runFlow(ctx, {
|
|||||||
(ctx.config.user_extra_files || []).map((i) => [i.split('/').pop(), { src: i }]),
|
(ctx.config.user_extra_files || []).map((i) => [i.split('/').pop(), { src: i }]),
|
||||||
),
|
),
|
||||||
ctx.next,
|
ctx.next,
|
||||||
),
|
).then(markCleanup),
|
||||||
compileChecker(
|
compileChecker(
|
||||||
ctx.session.getLang,
|
ctx.session.getLang,
|
||||||
ctx.config.checker_type,
|
ctx.config.checker_type,
|
||||||
@@ -139,9 +144,8 @@ export const judge = async (ctx: Context) => await runFlow(ctx, {
|
|||||||
(ctx.config.judge_extra_files || []).map((i) => [basename(i), { src: i }]),
|
(ctx.config.judge_extra_files || []).map((i) => [basename(i), { src: i }]),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
).then(markCleanup),
|
||||||
]);
|
]);
|
||||||
ctx.clean.push(ctx.execute.clean, ctx.checker.clean);
|
|
||||||
},
|
},
|
||||||
judgeCase,
|
judgeCase,
|
||||||
});
|
});
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import { basename } from 'path';
|
import { basename } from 'path';
|
||||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||||
import compile from '../compile';
|
import compile, { compileInteractor } from '../compile';
|
||||||
import { runFlow } from '../flow';
|
import { runFlow } from '../flow';
|
||||||
|
import { Execute } from '../interface';
|
||||||
import { runPiped } from '../sandbox';
|
import { runPiped } from '../sandbox';
|
||||||
import signals from '../signals';
|
import signals from '../signals';
|
||||||
import { parse } from '../testlib';
|
import { parse } from '../testlib';
|
||||||
@@ -76,28 +77,23 @@ function judgeCase(c: NormalizedCase) {
|
|||||||
|
|
||||||
export const judge = async (ctx: Context) => await runFlow(ctx, {
|
export const judge = async (ctx: Context) => await runFlow(ctx, {
|
||||||
compile: async () => {
|
compile: async () => {
|
||||||
[ctx.executeUser, ctx.executeInteractor] = await Promise.all([
|
const markCleanup = (i: Execute) => {
|
||||||
(() => {
|
ctx.clean.push(i.clean);
|
||||||
const copyIn = {};
|
return i;
|
||||||
for (const file of ctx.config.user_extra_files) {
|
};
|
||||||
copyIn[basename(file)] = { src: file };
|
const userExtraFiles = Object.fromEntries(
|
||||||
}
|
(ctx.config.user_extra_files || []).map((i) => [basename(i), { src: i }]),
|
||||||
return compile(ctx.session.getLang(ctx.lang), ctx.code, copyIn, ctx.next);
|
);
|
||||||
})(),
|
const interactorFiles = {
|
||||||
(() => {
|
|
||||||
const copyIn = {
|
|
||||||
'testlib.h': { src: testlibSrc },
|
'testlib.h': { src: testlibSrc },
|
||||||
user_code: ctx.code,
|
user_code: ctx.code,
|
||||||
};
|
};
|
||||||
for (const file of ctx.config.judge_extra_files) {
|
for (const file of ctx.config.judge_extra_files) {
|
||||||
copyIn[basename(file)] = { src: file };
|
interactorFiles[basename(file)] = { src: file };
|
||||||
}
|
}
|
||||||
return compile(
|
[ctx.executeUser, ctx.executeInteractor] = await Promise.all([
|
||||||
ctx.session.getLang(basename(ctx.config.interactor).split('.')[1].replace('@', '.')),
|
compile(ctx.session.getLang(ctx.lang), ctx.code, userExtraFiles, ctx.next).then(markCleanup),
|
||||||
{ src: ctx.config.interactor },
|
compileInteractor(ctx.session.getLang, ctx.config.interactor, interactorFiles).then(markCleanup),
|
||||||
copyIn,
|
|
||||||
);
|
|
||||||
})(),
|
|
||||||
]);
|
]);
|
||||||
ctx.clean.push(ctx.executeUser.clean, ctx.executeInteractor.clean);
|
ctx.clean.push(ctx.executeUser.clean, ctx.executeInteractor.clean);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
import child from 'child_process';
|
import child, { execSync } from 'child_process';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import cac from 'cac';
|
import cac from 'cac';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
||||||
const argv = cac().parse();
|
const argv = cac().parse();
|
||||||
|
let isGlobal = null;
|
||||||
|
try {
|
||||||
|
isGlobal = __dirname.startsWith(execSync('yarn global dir').toString().trim());
|
||||||
|
} catch (e) {
|
||||||
|
// yarn 2 does not support global dir
|
||||||
|
}
|
||||||
|
|
||||||
const exec = (...args) => {
|
const exec = (...args) => {
|
||||||
console.log('Executing: ', args[0], args[1].join(' '));
|
console.log('Executing: ', args[0], args[1].join(' '));
|
||||||
@@ -115,6 +121,15 @@ if (!argv.args[0] || argv.args[0] === 'cli') {
|
|||||||
console.log('Current Addons: ', addons);
|
console.log('Current Addons: ', addons);
|
||||||
fs.writeFileSync(addonPath, JSON.stringify(addons, null, 2));
|
fs.writeFileSync(addonPath, JSON.stringify(addons, null, 2));
|
||||||
});
|
});
|
||||||
|
cli.command('install [package]').action((name) => {
|
||||||
|
if (!isGlobal) {
|
||||||
|
console.warn('This is not a global installation, unable to install.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO support install from tarball
|
||||||
|
child.execSync(`yarn global install '${name}'`, { stdio: 'inherit' });
|
||||||
|
child.execSync(`hydrooj addon add '${name}'`);
|
||||||
|
});
|
||||||
cli.help();
|
cli.help();
|
||||||
cli.parse();
|
cli.parse();
|
||||||
if (!cli.matchedCommand) console.log('Unknown command.');
|
if (!cli.matchedCommand) console.log('Unknown command.');
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import { sleep } from '@hydrooj/utils/lib/utils';
|
import { sleep } from '@hydrooj/utils/lib/utils';
|
||||||
|
import { writeFileSync } from 'fs-extra';
|
||||||
import * as Judge from 'hydrooj/src/handler/judge';
|
import * as Judge from 'hydrooj/src/handler/judge';
|
||||||
import { Logger } from 'hydrooj/src/logger';
|
import { Logger } from 'hydrooj/src/logger';
|
||||||
import { STATUS } from 'hydrooj/src/model/builtin';
|
import { STATUS } from 'hydrooj/src/model/builtin';
|
||||||
@@ -55,6 +56,8 @@ class Service {
|
|||||||
|
|
||||||
async sync(domainId: string, resync = false, list: string) {
|
async sync(domainId: string, resync = false, list: string) {
|
||||||
let page = 1;
|
let page = 1;
|
||||||
|
const res = await this.api.getProblem('P1721D', {});
|
||||||
|
writeFileSync('a.md', res.content);
|
||||||
let pids = await this.api.listProblem(page, resync, list);
|
let pids = await this.api.listProblem(page, resync, list);
|
||||||
while (pids.length) {
|
while (pids.length) {
|
||||||
logger.info(`${domainId}: Syncing page ${page}`);
|
logger.info(`${domainId}: Syncing page ${page}`);
|
||||||
|
|||||||
Reference in new issue
Block a user