diff --git a/src/actions/enhancedmultiFileRunner.ts b/src/actions/enhancedmultiFileRunner.ts index 686bef4..769f644 100644 --- a/src/actions/enhancedmultiFileRunner.ts +++ b/src/actions/enhancedmultiFileRunner.ts @@ -1,11 +1,12 @@ 'use server'; import Docker from 'dockerode'; -import fs from 'fs'; +import fs from 'fs/promises'; // 使用异步版本的 fs 模块 import path from 'path'; import axios from 'axios'; const docker = new Docker(); +const DOCKER_IMAGE_URL = process.env.DOCKER_IMAGE_URL || 'fly6516.synology.me:8080/multilang:latest'; // 使用环境变量 let giteaRepoUrl: string | undefined; let giteaToken: string | undefined; @@ -55,7 +56,7 @@ const fetchFilesFromGitea = async (dir: string, tempDir: string) => { } const targetDir = path.join(tempDir, dir); - fs.mkdirSync(targetDir, { recursive: true }); + await fs.mkdir(targetDir, { recursive: true }); try { 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.`); } - for (const file of files) { - if (file.type === 'file') { - const fileResponse = await axios.get(file.download_url, { - headers: { - Authorization: `token ${giteaToken}`, - }, - responseType: 'arraybuffer', - }); + // 并行下载文件 + await Promise.all(files.filter(file => file.type === 'file').map(async (file) => { + const fileResponse = await axios.get(file.download_url, { + headers: { + Authorization: `token ${giteaToken}`, + }, + responseType: 'arraybuffer', + }); - const filePath = path.join(targetDir, file.name); - fs.writeFileSync(filePath, fileResponse.data); - } - } + const filePath = path.join(targetDir, file.name); + await fs.writeFile(filePath, fileResponse.data); + })); } catch (error) { 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 正确答案文件路径 * @returns 是否一致的比较结果 */ -const compareResults = (resultFilePath: string, expectedFilePath: string): boolean => { - const result = fs.readFileSync(resultFilePath, 'utf-8').trim(); - const expected = fs.readFileSync(expectedFilePath, 'utf-8').trim(); - return result === expected; +const compareResults = async (resultFilePath: string, expectedFilePath: string): Promise => { + try { + const result = (await fs.readFile(resultFilePath, 'utf-8')).trim(); + 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'; const tempDir = path.join('/tmp', `${Date.now()}`); - fs.mkdirSync(tempDir, { recursive: true }); + await fs.mkdir(tempDir, { recursive: true }); try { // 写入代码文件 - for (const file of files) { + await Promise.all(files.map(async (file) => { const filePath = path.join(tempDir, file.name); - fs.writeFileSync(filePath, file.content); - } + await fs.writeFile(filePath, file.content); + })); // 检查是否设置了 Gitea 仓库信息 if (giteaRepoUrl && giteaToken) { @@ -152,7 +156,7 @@ export const runMultiFileCodeWithOptionalTestData = async (params: { // 创建 Docker 容器 const container = await docker.createContainer({ - Image: 'fly6516.synology.me:8080/multilang:latest', + Image: DOCKER_IMAGE_URL, Cmd: ['sh', '-c', compileAndRunCmd], AttachStdout: 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 comparisonResults = expectedAnswerFiles.map((expectedFile) => { + const comparisonResults = await Promise.all(expectedAnswerFiles.map(async (expectedFile) => { const expectedFilePath = path.join(tempDir, testDataPath, expectedFile); - const isMatch = compareResults(resultFilePath, expectedFilePath); + const isMatch = await compareResults(resultFilePath, expectedFilePath); return { expectedFile, isMatch }; - }); + })); return { output, comparisonResults }; } @@ -196,6 +200,6 @@ export const runMultiFileCodeWithOptionalTestData = async (params: { } catch (error) { return { error: `An error occurred: ${(error as Error).message}` }; } finally { - fs.rmSync(tempDir, { recursive: true, force: true }); + await fs.rm(tempDir, { recursive: true, force: true }); } };