feat:添加了多语言编译支持

This commit is contained in:
fly6516 2025-01-03 03:01:39 +08:00
parent 7491e29384
commit 612e36e4ea

View File

@ -0,0 +1,84 @@
import Docker from 'dockerode';
import fs from 'fs';
import path from 'path';
// 创建 Docker 客户端实例
const docker = new Docker();
/**
*
* @param params
* @returns
*/
export const runMultiFileCode = async (params: { files: { name: string; content: string }[]; language: string }) => {
const { files, language } = params;
if (!files || files.length === 0 || !language) {
throw new Error('Files and language are required.');
}
// 支持的编程语言
const supportedLanguages = ['c', 'java', 'python'];
if (!supportedLanguages.includes(language)) {
throw new Error(`Language '${language}' is not supported. Only 'c', 'java', and 'python' are supported.`);
}
// 根据语言设置编译和运行命令
const compileAndRunCmd =
language === 'c'
? 'gcc *.c -o main && ./main'
: language === 'java'
? 'javac *.java && java Main'
: 'python3 script.py';
// 创建临时目录存放代码文件
const tempDir = path.join('/tmp', `${Date.now()}`);
fs.mkdirSync(tempDir, { recursive: true });
try {
// 将所有文件写入临时目录
for (const file of files) {
const filePath = path.join(tempDir, file.name);
fs.writeFileSync(filePath, file.content);
}
// 创建 Docker 容器
const container = await docker.createContainer({
Image: 'fly6516.synology.me:8080/multilang:latest',
Cmd: ['sh', '-c', compileAndRunCmd],
AttachStdout: true,
AttachStderr: true,
Tty: false,
HostConfig: {
Binds: [`${tempDir}:/workspace`], // 挂载临时目录到容器
},
WorkingDir: '/workspace',
});
await container.start();
// 获取容器日志
const logs = await container.logs({ stdout: true, stderr: true, follow: true });
let output = '';
logs.on('data', (data: Buffer) => {
output += data.toString().replace(/[\x00-\x1F\x7F]/g, ''); // 去除不可见字符
});
const exitCode = await container.wait(); // 等待容器执行结束
await container.remove(); // 移除容器
// 返回执行结果或错误信息
if (exitCode.StatusCode === 0) {
return { output };
} else {
return { error: `Execution failed with exit code ${exitCode.StatusCode}. Output: ${output}` };
}
} catch (error) {
// 捕获异常并返回详细错误信息
return { error: `An error occurred: ${(error as Error).message}` };
} finally {
// 清理临时目录
fs.rmSync(tempDir, { recursive: true, force: true });
}
};