feat:优化代码 enhancedmultiFileRunner.ts

This commit is contained in:
fly6516 2025-01-03 03:44:00 +08:00
parent 4d5288ed33
commit 2375707515

View File

@ -1,11 +1,12 @@
'use server'; 'use server';
import Docker from 'dockerode'; import Docker from 'dockerode';
import fs from 'fs'; import fs from 'fs/promises'; // 使用异步版本的 fs 模块
import path from 'path'; import path from 'path';
import axios from 'axios'; import axios from 'axios';
const docker = new Docker(); const docker = new Docker();
const DOCKER_IMAGE_URL = process.env.DOCKER_IMAGE_URL || 'fly6516.synology.me:8080/multilang:latest'; // 使用环境变量
let giteaRepoUrl: string | undefined; let giteaRepoUrl: string | undefined;
let giteaToken: string | undefined; let giteaToken: string | undefined;
@ -55,7 +56,7 @@ const fetchFilesFromGitea = async (dir: string, tempDir: string) => {
} }
const targetDir = path.join(tempDir, dir); const targetDir = path.join(tempDir, dir);
fs.mkdirSync(targetDir, { recursive: true }); await fs.mkdir(targetDir, { recursive: true });
try { try {
const response = await axios.get(`${giteaRepoUrl}/contents/${dir}`, { const response = await axios.get(`${giteaRepoUrl}/contents/${dir}`, {
@ -69,19 +70,18 @@ const fetchFilesFromGitea = async (dir: string, tempDir: string) => {
throw new Error(`Invalid directory structure for ${dir} in repository.`); throw new Error(`Invalid directory structure for ${dir} in repository.`);
} }
for (const file of files) { // 并行下载文件
if (file.type === 'file') { await Promise.all(files.filter(file => file.type === 'file').map(async (file) => {
const fileResponse = await axios.get(file.download_url, { const fileResponse = await axios.get(file.download_url, {
headers: { headers: {
Authorization: `token ${giteaToken}`, Authorization: `token ${giteaToken}`,
}, },
responseType: 'arraybuffer', responseType: 'arraybuffer',
}); });
const filePath = path.join(targetDir, file.name); const filePath = path.join(targetDir, file.name);
fs.writeFileSync(filePath, fileResponse.data); await fs.writeFile(filePath, fileResponse.data);
} }));
}
} catch (error) { } catch (error) {
throw new Error(`Failed to fetch files from '${dir}': ${(error as Error).message}`); throw new Error(`Failed to fetch files from '${dir}': ${(error as Error).message}`);
} }
@ -93,10 +93,14 @@ const fetchFilesFromGitea = async (dir: string, tempDir: string) => {
* @param expectedFilePath * @param expectedFilePath
* @returns * @returns
*/ */
const compareResults = (resultFilePath: string, expectedFilePath: string): boolean => { const compareResults = async (resultFilePath: string, expectedFilePath: string): Promise<boolean> => {
const result = fs.readFileSync(resultFilePath, 'utf-8').trim(); try {
const expected = fs.readFileSync(expectedFilePath, 'utf-8').trim(); const result = (await fs.readFile(resultFilePath, 'utf-8')).trim();
return result === expected; const expected = (await fs.readFile(expectedFilePath, 'utf-8')).trim();
return result === expected;
} catch (error) {
throw new Error(`Failed to read files for comparison: ${(error as Error).message}`);
}
}; };
/** /**
@ -130,14 +134,14 @@ export const runMultiFileCodeWithOptionalTestData = async (params: {
: 'python3 script.py'; : 'python3 script.py';
const tempDir = path.join('/tmp', `${Date.now()}`); const tempDir = path.join('/tmp', `${Date.now()}`);
fs.mkdirSync(tempDir, { recursive: true }); await fs.mkdir(tempDir, { recursive: true });
try { try {
// 写入代码文件 // 写入代码文件
for (const file of files) { await Promise.all(files.map(async (file) => {
const filePath = path.join(tempDir, file.name); const filePath = path.join(tempDir, file.name);
fs.writeFileSync(filePath, file.content); await fs.writeFile(filePath, file.content);
} }));
// 检查是否设置了 Gitea 仓库信息 // 检查是否设置了 Gitea 仓库信息
if (giteaRepoUrl && giteaToken) { if (giteaRepoUrl && giteaToken) {
@ -152,7 +156,7 @@ export const runMultiFileCodeWithOptionalTestData = async (params: {
// 创建 Docker 容器 // 创建 Docker 容器
const container = await docker.createContainer({ const container = await docker.createContainer({
Image: 'fly6516.synology.me:8080/multilang:latest', Image: DOCKER_IMAGE_URL,
Cmd: ['sh', '-c', compileAndRunCmd], Cmd: ['sh', '-c', compileAndRunCmd],
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -180,14 +184,14 @@ export const runMultiFileCodeWithOptionalTestData = async (params: {
} }
// 如果指定了结果输出文件和正确答案文件,执行比较 // 如果指定了结果输出文件和正确答案文件,执行比较
if (resultOutputFile && expectedAnswerFiles) { if (resultOutputFile && expectedAnswerFiles && expectedAnswerFiles.length > 0) {
const resultFilePath = path.join(tempDir, resultOutputFile); const resultFilePath = path.join(tempDir, resultOutputFile);
const comparisonResults = expectedAnswerFiles.map((expectedFile) => { const comparisonResults = await Promise.all(expectedAnswerFiles.map(async (expectedFile) => {
const expectedFilePath = path.join(tempDir, testDataPath, expectedFile); const expectedFilePath = path.join(tempDir, testDataPath, expectedFile);
const isMatch = compareResults(resultFilePath, expectedFilePath); const isMatch = await compareResults(resultFilePath, expectedFilePath);
return { expectedFile, isMatch }; return { expectedFile, isMatch };
}); }));
return { output, comparisonResults }; return { output, comparisonResults };
} }
@ -196,6 +200,6 @@ export const runMultiFileCodeWithOptionalTestData = async (params: {
} catch (error) { } catch (error) {
return { error: `An error occurred: ${(error as Error).message}` }; return { error: `An error occurred: ${(error as Error).message}` };
} finally { } finally {
fs.rmSync(tempDir, { recursive: true, force: true }); await fs.rm(tempDir, { recursive: true, force: true });
} }
}; };