@exercode/problem-utils 1.16.5 → 1.16.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/helpers/checkProblemDirIsolation.cjs +2 -2
- package/dist/helpers/checkProblemDirIsolation.cjs.map +1 -1
- package/dist/helpers/checkProblemDirIsolation.js +2 -2
- package/dist/helpers/checkProblemDirIsolation.js.map +1 -1
- package/dist/helpers/cleanWorkingDirectory.cjs +2 -2
- package/dist/helpers/cleanWorkingDirectory.cjs.map +1 -1
- package/dist/helpers/cleanWorkingDirectory.js +2 -2
- package/dist/helpers/cleanWorkingDirectory.js.map +1 -1
- package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.cjs +2 -2
- package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.cjs.map +1 -1
- package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.js +2 -2
- package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.js.map +1 -1
- package/dist/helpers/copyTestCaseFileInput.cjs +2 -2
- package/dist/helpers/copyTestCaseFileInput.cjs.map +1 -1
- package/dist/helpers/copyTestCaseFileInput.js +2 -2
- package/dist/helpers/copyTestCaseFileInput.js.map +1 -1
- package/dist/helpers/findEntryPointFile.cjs +2 -2
- package/dist/helpers/findEntryPointFile.cjs.map +1 -1
- package/dist/helpers/findEntryPointFile.js +2 -2
- package/dist/helpers/findEntryPointFile.js.map +1 -1
- package/dist/helpers/findLanguageDefinitionByPath.cjs +2 -2
- package/dist/helpers/findLanguageDefinitionByPath.cjs.map +1 -1
- package/dist/helpers/findLanguageDefinitionByPath.js +2 -2
- package/dist/helpers/findLanguageDefinitionByPath.js.map +1 -1
- package/dist/helpers/findModelAnswerDirs.cjs +2 -2
- package/dist/helpers/findModelAnswerDirs.cjs.map +1 -1
- package/dist/helpers/findModelAnswerDirs.js +2 -2
- package/dist/helpers/findModelAnswerDirs.js.map +1 -1
- package/dist/helpers/judgeByStaticAnalysis.cjs +19 -2
- package/dist/helpers/judgeByStaticAnalysis.cjs.map +1 -1
- package/dist/helpers/judgeByStaticAnalysis.js +19 -2
- package/dist/helpers/judgeByStaticAnalysis.js.map +1 -1
- package/dist/helpers/parseArgs.cjs +2 -2
- package/dist/helpers/parseArgs.cjs.map +1 -1
- package/dist/helpers/parseArgs.js +2 -2
- package/dist/helpers/parseArgs.js.map +1 -1
- package/dist/helpers/printDebugBanner.cjs +3 -2
- package/dist/helpers/printDebugBanner.cjs.map +1 -1
- package/dist/helpers/printDebugBanner.js +3 -2
- package/dist/helpers/printDebugBanner.js.map +1 -1
- package/dist/helpers/printTestCaseResult.cjs +2 -2
- package/dist/helpers/printTestCaseResult.cjs.map +1 -1
- package/dist/helpers/printTestCaseResult.js +2 -2
- package/dist/helpers/printTestCaseResult.js.map +1 -1
- package/dist/helpers/readOutputFiles.cjs +2 -2
- package/dist/helpers/readOutputFiles.cjs.map +1 -1
- package/dist/helpers/readOutputFiles.js +2 -2
- package/dist/helpers/readOutputFiles.js.map +1 -1
- package/dist/helpers/readProblemMarkdownFrontMatter.cjs +2 -2
- package/dist/helpers/readProblemMarkdownFrontMatter.cjs.map +1 -1
- package/dist/helpers/readProblemMarkdownFrontMatter.js +2 -2
- package/dist/helpers/readProblemMarkdownFrontMatter.js.map +1 -1
- package/dist/helpers/readTestCases.cjs +2 -2
- package/dist/helpers/readTestCases.cjs.map +1 -1
- package/dist/helpers/readTestCases.js +2 -2
- package/dist/helpers/readTestCases.js.map +1 -1
- package/dist/helpers/removeCommentsInSourceCode.cjs +6 -2
- package/dist/helpers/removeCommentsInSourceCode.cjs.map +1 -1
- package/dist/helpers/removeCommentsInSourceCode.js +6 -2
- package/dist/helpers/removeCommentsInSourceCode.js.map +1 -1
- package/dist/helpers/resolveCwds.cjs +2 -2
- package/dist/helpers/resolveCwds.cjs.map +1 -1
- package/dist/helpers/resolveCwds.js +2 -2
- package/dist/helpers/resolveCwds.js.map +1 -1
- package/dist/helpers/runCommandInTemporaryPackageManagerProject.cjs +2 -2
- package/dist/helpers/runCommandInTemporaryPackageManagerProject.cjs.map +1 -1
- package/dist/helpers/runCommandInTemporaryPackageManagerProject.js +2 -2
- package/dist/helpers/runCommandInTemporaryPackageManagerProject.js.map +1 -1
- package/dist/helpers/runPythonInTemporaryUvProject.cjs +2 -2
- package/dist/helpers/runPythonInTemporaryUvProject.cjs.map +1 -1
- package/dist/helpers/runPythonInTemporaryUvProject.js +2 -2
- package/dist/helpers/runPythonInTemporaryUvProject.js.map +1 -1
- package/dist/helpers/sourceCodeGrammars.cjs +2 -2
- package/dist/helpers/sourceCodeGrammars.cjs.map +1 -1
- package/dist/helpers/sourceCodeGrammars.js +2 -2
- package/dist/helpers/sourceCodeGrammars.js.map +1 -1
- package/dist/helpers/spawnSyncWithTimeout.cjs +2 -2
- package/dist/helpers/spawnSyncWithTimeout.cjs.map +1 -1
- package/dist/helpers/spawnSyncWithTimeout.js +2 -2
- package/dist/helpers/spawnSyncWithTimeout.js.map +1 -1
- package/dist/helpers/startHttpServer.cjs +2 -2
- package/dist/helpers/startHttpServer.cjs.map +1 -1
- package/dist/helpers/startHttpServer.js +2 -2
- package/dist/helpers/startHttpServer.js.map +1 -1
- package/dist/index.cjs +1 -2
- package/dist/index.js +1 -2
- package/dist/presets/command.cjs +2 -2
- package/dist/presets/command.cjs.map +1 -1
- package/dist/presets/command.js +2 -2
- package/dist/presets/command.js.map +1 -1
- package/dist/presets/guiCommand.cjs +4 -2
- package/dist/presets/guiCommand.cjs.map +1 -1
- package/dist/presets/guiCommand.js +4 -2
- package/dist/presets/guiCommand.js.map +1 -1
- package/dist/presets/llm.cjs +2 -2
- package/dist/presets/llm.cjs.map +1 -1
- package/dist/presets/llm.js +2 -2
- package/dist/presets/llm.js.map +1 -1
- package/dist/presets/stdio.cjs +2 -2
- package/dist/presets/stdio.cjs.map +1 -1
- package/dist/presets/stdio.js +2 -2
- package/dist/presets/stdio.js.map +1 -1
- package/dist/types/decisionCode.cjs +2 -2
- package/dist/types/decisionCode.cjs.map +1 -1
- package/dist/types/decisionCode.js +2 -2
- package/dist/types/decisionCode.js.map +1 -1
- package/dist/types/language.cjs +11 -2
- package/dist/types/language.cjs.map +1 -1
- package/dist/types/language.js +11 -2
- package/dist/types/language.js.map +1 -1
- package/dist/types/problem.cjs +2 -2
- package/dist/types/problem.cjs.map +1 -1
- package/dist/types/problem.js +2 -2
- package/dist/types/problem.js.map +1 -1
- package/dist/types/testCaseResult.cjs +2 -2
- package/dist/types/testCaseResult.cjs.map +1 -1
- package/dist/types/testCaseResult.js +2 -2
- package/dist/types/testCaseResult.js.map +1 -1
- package/package.json +14 -14
- package/dist/_virtual/_rollupPluginBabelHelpers.cjs +0 -4
- package/dist/_virtual/_rollupPluginBabelHelpers.cjs.map +0 -1
- package/dist/_virtual/_rollupPluginBabelHelpers.js +0 -4
- package/dist/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startHttpServer.cjs","sources":["../../src/helpers/startHttpServer.ts"],"sourcesContent":["import fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\n\nexport interface HttpServer {\n [Symbol.asyncDispose](): Promise<void>;\n url: string;\n port: number | undefined;\n}\n\n/**\n * Start a HTTP server for testing web pages.\n */\nexport function startHttpServer(dir: string): HttpServer {\n const server = http.createServer((request, response) => {\n let pathname = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;\n\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n const pathnameWithIndexHtml = pathname.endsWith('/') ? path.join(pathname, 'index.html') : pathname;\n\n const filePath = path.join(dir, pathnameWithIndexHtml);\n\n if (fs.existsSync(filePath)) {\n try {\n const buffer = fs.readFileSync(filePath);\n response.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n Pragma: 'no-cache',\n 'Cache-Control': 'no-cache',\n 'Content-Type': getContentType(pathnameWithIndexHtml),\n });\n response.end(buffer);\n } catch {\n response.statusCode = 500;\n response.end();\n }\n } else {\n response.statusCode = 404;\n response.end();\n }\n });\n\n server.listen();\n\n const address = server.address();\n if (!address) throw new Error('server has been unexpectedly closed');\n\n return {\n [Symbol.asyncDispose]: async () => {\n server.closeAllConnections();\n await new Promise<void>((resolve) => {\n server.close(() => {\n resolve();\n });\n });\n },\n url: typeof address === 'string' ? address : `http://127.0.0.1:${address.port}`,\n port: typeof address === 'object' ? address.port : undefined,\n };\n}\n\nconst CONTENT_TYPE_BY_SUFFIX: Record<string, string> = {\n '.css': 'text/css',\n '.html': 'text/html',\n '.js': 'text/javascript',\n '.gif': 'image/gif',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n};\n\nfunction getContentType(pathname: string): string {\n for (const [suffix, contentType] of Object.entries(CONTENT_TYPE_BY_SUFFIX)) {\n if (pathname.endsWith(suffix)) return contentType;\n }\n return 'text/plain';\n}\n"],"
|
|
1
|
+
{"version":3,"file":"startHttpServer.cjs","names":["http","path","fs"],"sources":["../../src/helpers/startHttpServer.ts"],"sourcesContent":["import fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\n\nexport interface HttpServer {\n [Symbol.asyncDispose](): Promise<void>;\n url: string;\n port: number | undefined;\n}\n\n/**\n * Start a HTTP server for testing web pages.\n */\nexport function startHttpServer(dir: string): HttpServer {\n const server = http.createServer((request, response) => {\n let pathname = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;\n\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n const pathnameWithIndexHtml = pathname.endsWith('/') ? path.join(pathname, 'index.html') : pathname;\n\n const filePath = path.join(dir, pathnameWithIndexHtml);\n\n if (fs.existsSync(filePath)) {\n try {\n const buffer = fs.readFileSync(filePath);\n response.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n Pragma: 'no-cache',\n 'Cache-Control': 'no-cache',\n 'Content-Type': getContentType(pathnameWithIndexHtml),\n });\n response.end(buffer);\n } catch {\n response.statusCode = 500;\n response.end();\n }\n } else {\n response.statusCode = 404;\n response.end();\n }\n });\n\n server.listen();\n\n const address = server.address();\n if (!address) throw new Error('server has been unexpectedly closed');\n\n return {\n [Symbol.asyncDispose]: async () => {\n server.closeAllConnections();\n await new Promise<void>((resolve) => {\n server.close(() => {\n resolve();\n });\n });\n },\n url: typeof address === 'string' ? address : `http://127.0.0.1:${address.port}`,\n port: typeof address === 'object' ? address.port : undefined,\n };\n}\n\nconst CONTENT_TYPE_BY_SUFFIX: Record<string, string> = {\n '.css': 'text/css',\n '.html': 'text/html',\n '.js': 'text/javascript',\n '.gif': 'image/gif',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n};\n\nfunction getContentType(pathname: string): string {\n for (const [suffix, contentType] of Object.entries(CONTENT_TYPE_BY_SUFFIX)) {\n if (pathname.endsWith(suffix)) return contentType;\n }\n return 'text/plain';\n}\n"],"mappings":"oMAaA,SAAgB,EAAgB,EAAyB,CACvD,IAAM,EAASA,EAAAA,QAAK,cAAc,EAAS,IAAa,CACtD,IAAI,EAAW,IAAI,IAAI,EAAQ,KAAO,IAAK,kBAAkB,CAAC,CAAC,SAE3D,IAAa,MACf,EAAW,eAGb,IAAM,EAAwB,EAAS,SAAS,GAAG,EAAIC,EAAAA,QAAK,KAAK,EAAU,YAAY,EAAI,EAErF,EAAWA,EAAAA,QAAK,KAAK,EAAK,CAAqB,EAErD,GAAIC,EAAAA,QAAG,WAAW,CAAQ,EACxB,GAAI,CACF,IAAM,EAASA,EAAAA,QAAG,aAAa,CAAQ,EACvC,EAAS,UAAU,IAAK,CACtB,8BAA+B,IAC/B,OAAQ,WACR,gBAAiB,WACjB,eAAgB,EAAe,CAAqB,CACtD,CAAC,EACD,EAAS,IAAI,CAAM,CACrB,MAAQ,CACN,EAAS,WAAa,IACtB,EAAS,IAAI,CACf,KAEA,GAAS,WAAa,IACtB,EAAS,IAAI,CAEjB,CAAC,EAED,EAAO,OAAO,EAEd,IAAM,EAAU,EAAO,QAAQ,EAC/B,GAAI,CAAC,EAAS,MAAU,MAAM,qCAAqC,EAEnE,MAAO,EACJ,OAAO,cAAe,SAAY,CACjC,EAAO,oBAAoB,EAC3B,MAAM,IAAI,QAAe,GAAY,CACnC,EAAO,UAAY,CACjB,EAAQ,CACV,CAAC,CACH,CAAC,CACH,EACA,IAAK,OAAO,GAAY,SAAW,EAAU,oBAAoB,EAAQ,OACzE,KAAM,OAAO,GAAY,SAAW,EAAQ,KAAO,IAAA,EACrD,CACF,CAEA,MAAM,EAAiD,CACrD,OAAQ,WACR,QAAS,YACT,MAAO,kBACP,OAAQ,YACR,OAAQ,aACR,OAAQ,YACR,OAAQ,eACV,EAEA,SAAS,EAAe,EAA0B,CAChD,IAAK,GAAM,CAAC,EAAQ,KAAgB,OAAO,QAAQ,CAAsB,EACvE,GAAI,EAAS,SAAS,CAAM,EAAG,OAAO,EAExC,MAAO,YACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
//# sourceMappingURL=startHttpServer.js.map
|
|
1
|
+
import e from"node:path";import t from"node:fs";import n from"node:http";function r(r){let i=n.createServer((n,i)=>{let o=new URL(n.url??`/`,`http://127.0.0.1`).pathname;o===`/`&&(o=`/index.html`);let s=o.endsWith(`/`)?e.join(o,`index.html`):o,c=e.join(r,s);if(t.existsSync(c))try{let e=t.readFileSync(c);i.writeHead(200,{"Access-Control-Allow-Origin":`*`,Pragma:`no-cache`,"Cache-Control":`no-cache`,"Content-Type":a(s)}),i.end(e)}catch{i.statusCode=500,i.end()}else i.statusCode=404,i.end()});i.listen();let o=i.address();if(!o)throw Error(`server has been unexpectedly closed`);return{[Symbol.asyncDispose]:async()=>{i.closeAllConnections(),await new Promise(e=>{i.close(()=>{e()})})},url:typeof o==`string`?o:`http://127.0.0.1:${o.port}`,port:typeof o==`object`?o.port:void 0}}const i={".css":`text/css`,".html":`text/html`,".js":`text/javascript`,".gif":`image/gif`,".jpg":`image/jpeg`,".png":`image/png`,".svg":`image/svg+xml`};function a(e){for(let[t,n]of Object.entries(i))if(e.endsWith(t))return n;return`text/plain`}export{r as startHttpServer};
|
|
2
|
+
//# sourceMappingURL=startHttpServer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startHttpServer.js","sources":["../../src/helpers/startHttpServer.ts"],"sourcesContent":["import fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\n\nexport interface HttpServer {\n [Symbol.asyncDispose](): Promise<void>;\n url: string;\n port: number | undefined;\n}\n\n/**\n * Start a HTTP server for testing web pages.\n */\nexport function startHttpServer(dir: string): HttpServer {\n const server = http.createServer((request, response) => {\n let pathname = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;\n\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n const pathnameWithIndexHtml = pathname.endsWith('/') ? path.join(pathname, 'index.html') : pathname;\n\n const filePath = path.join(dir, pathnameWithIndexHtml);\n\n if (fs.existsSync(filePath)) {\n try {\n const buffer = fs.readFileSync(filePath);\n response.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n Pragma: 'no-cache',\n 'Cache-Control': 'no-cache',\n 'Content-Type': getContentType(pathnameWithIndexHtml),\n });\n response.end(buffer);\n } catch {\n response.statusCode = 500;\n response.end();\n }\n } else {\n response.statusCode = 404;\n response.end();\n }\n });\n\n server.listen();\n\n const address = server.address();\n if (!address) throw new Error('server has been unexpectedly closed');\n\n return {\n [Symbol.asyncDispose]: async () => {\n server.closeAllConnections();\n await new Promise<void>((resolve) => {\n server.close(() => {\n resolve();\n });\n });\n },\n url: typeof address === 'string' ? address : `http://127.0.0.1:${address.port}`,\n port: typeof address === 'object' ? address.port : undefined,\n };\n}\n\nconst CONTENT_TYPE_BY_SUFFIX: Record<string, string> = {\n '.css': 'text/css',\n '.html': 'text/html',\n '.js': 'text/javascript',\n '.gif': 'image/gif',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n};\n\nfunction getContentType(pathname: string): string {\n for (const [suffix, contentType] of Object.entries(CONTENT_TYPE_BY_SUFFIX)) {\n if (pathname.endsWith(suffix)) return contentType;\n }\n return 'text/plain';\n}\n"],"
|
|
1
|
+
{"version":3,"file":"startHttpServer.js","names":[],"sources":["../../src/helpers/startHttpServer.ts"],"sourcesContent":["import fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\n\nexport interface HttpServer {\n [Symbol.asyncDispose](): Promise<void>;\n url: string;\n port: number | undefined;\n}\n\n/**\n * Start a HTTP server for testing web pages.\n */\nexport function startHttpServer(dir: string): HttpServer {\n const server = http.createServer((request, response) => {\n let pathname = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;\n\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n const pathnameWithIndexHtml = pathname.endsWith('/') ? path.join(pathname, 'index.html') : pathname;\n\n const filePath = path.join(dir, pathnameWithIndexHtml);\n\n if (fs.existsSync(filePath)) {\n try {\n const buffer = fs.readFileSync(filePath);\n response.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n Pragma: 'no-cache',\n 'Cache-Control': 'no-cache',\n 'Content-Type': getContentType(pathnameWithIndexHtml),\n });\n response.end(buffer);\n } catch {\n response.statusCode = 500;\n response.end();\n }\n } else {\n response.statusCode = 404;\n response.end();\n }\n });\n\n server.listen();\n\n const address = server.address();\n if (!address) throw new Error('server has been unexpectedly closed');\n\n return {\n [Symbol.asyncDispose]: async () => {\n server.closeAllConnections();\n await new Promise<void>((resolve) => {\n server.close(() => {\n resolve();\n });\n });\n },\n url: typeof address === 'string' ? address : `http://127.0.0.1:${address.port}`,\n port: typeof address === 'object' ? address.port : undefined,\n };\n}\n\nconst CONTENT_TYPE_BY_SUFFIX: Record<string, string> = {\n '.css': 'text/css',\n '.html': 'text/html',\n '.js': 'text/javascript',\n '.gif': 'image/gif',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n};\n\nfunction getContentType(pathname: string): string {\n for (const [suffix, contentType] of Object.entries(CONTENT_TYPE_BY_SUFFIX)) {\n if (pathname.endsWith(suffix)) return contentType;\n }\n return 'text/plain';\n}\n"],"mappings":"yEAaA,SAAgB,EAAgB,EAAyB,CACvD,IAAM,EAAS,EAAK,cAAc,EAAS,IAAa,CACtD,IAAI,EAAW,IAAI,IAAI,EAAQ,KAAO,IAAK,kBAAkB,CAAC,CAAC,SAE3D,IAAa,MACf,EAAW,eAGb,IAAM,EAAwB,EAAS,SAAS,GAAG,EAAI,EAAK,KAAK,EAAU,YAAY,EAAI,EAErF,EAAW,EAAK,KAAK,EAAK,CAAqB,EAErD,GAAI,EAAG,WAAW,CAAQ,EACxB,GAAI,CACF,IAAM,EAAS,EAAG,aAAa,CAAQ,EACvC,EAAS,UAAU,IAAK,CACtB,8BAA+B,IAC/B,OAAQ,WACR,gBAAiB,WACjB,eAAgB,EAAe,CAAqB,CACtD,CAAC,EACD,EAAS,IAAI,CAAM,CACrB,MAAQ,CACN,EAAS,WAAa,IACtB,EAAS,IAAI,CACf,KAEA,GAAS,WAAa,IACtB,EAAS,IAAI,CAEjB,CAAC,EAED,EAAO,OAAO,EAEd,IAAM,EAAU,EAAO,QAAQ,EAC/B,GAAI,CAAC,EAAS,MAAU,MAAM,qCAAqC,EAEnE,MAAO,EACJ,OAAO,cAAe,SAAY,CACjC,EAAO,oBAAoB,EAC3B,MAAM,IAAI,QAAe,GAAY,CACnC,EAAO,UAAY,CACjB,EAAQ,CACV,CAAC,CACH,CAAC,CACH,EACA,IAAK,OAAO,GAAY,SAAW,EAAU,oBAAoB,EAAQ,OACzE,KAAM,OAAO,GAAY,SAAW,EAAQ,KAAO,IAAA,EACrD,CACF,CAEA,MAAM,EAAiD,CACrD,OAAQ,WACR,QAAS,YACT,MAAO,kBACP,OAAQ,YACR,OAAQ,aACR,OAAQ,YACR,OAAQ,eACV,EAEA,SAAS,EAAe,EAA0B,CAChD,IAAK,GAAM,CAAC,EAAQ,KAAgB,OAAO,QAAQ,CAAsB,EACvE,GAAI,EAAS,SAAS,CAAM,EAAG,OAAO,EAExC,MAAO,YACT"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
//# sourceMappingURL=index.cjs.map
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./helpers/parseArgs.cjs"),t=require("./types/testCaseResult.cjs"),n=require("./helpers/printTestCaseResult.cjs"),r=require("./helpers/removeCommentsInSourceCode.cjs"),i=require("./helpers/runCommandInTemporaryPackageManagerProject.cjs"),a=require("./helpers/runPythonInTemporaryUvProject.cjs"),o=require("./helpers/sourceCodeGrammars.cjs"),s=require("./helpers/startHttpServer.cjs"),c=require("./types/decisionCode.cjs");exports.DecisionCode=c.DecisionCode,exports.TEST_CASE_RESULT_PREFIX=t.TEST_CASE_RESULT_PREFIX,exports.copyPackageManagerProjectFiles=i.copyPackageManagerProjectFiles,exports.encodeFileForTestCaseResult=n.encodeFileForTestCaseResult,exports.languageIdToSourceCodeGrammar=o.languageIdToSourceCodeGrammar,exports.parseArgs=e.parseArgs,exports.printTestCaseResult=n.printTestCaseResult,exports.removeCommentsAndStringsInSourceCode=r.removeCommentsAndStringsInSourceCode,exports.removeCommentsInSourceCode=r.removeCommentsInSourceCode,exports.runCommandInTemporaryPackageManagerProject=i.runCommandInTemporaryPackageManagerProject,exports.runPythonInTemporaryUvProject=a.runPythonInTemporaryUvProject,exports.startHttpServer=s.startHttpServer,exports.testCaseResultSchema=t.testCaseResultSchema;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import{parseArgs as e}from"./helpers/parseArgs.js";import{TEST_CASE_RESULT_PREFIX as t,testCaseResultSchema as n}from"./types/testCaseResult.js";import{encodeFileForTestCaseResult as r,printTestCaseResult as i}from"./helpers/printTestCaseResult.js";import{removeCommentsAndStringsInSourceCode as a,removeCommentsInSourceCode as o}from"./helpers/removeCommentsInSourceCode.js";import{copyPackageManagerProjectFiles as s,runCommandInTemporaryPackageManagerProject as c}from"./helpers/runCommandInTemporaryPackageManagerProject.js";import{runPythonInTemporaryUvProject as l}from"./helpers/runPythonInTemporaryUvProject.js";import{languageIdToSourceCodeGrammar as u}from"./helpers/sourceCodeGrammars.js";import{startHttpServer as d}from"./helpers/startHttpServer.js";import{DecisionCode as f}from"./types/decisionCode.js";export{f as DecisionCode,t as TEST_CASE_RESULT_PREFIX,s as copyPackageManagerProjectFiles,r as encodeFileForTestCaseResult,u as languageIdToSourceCodeGrammar,e as parseArgs,i as printTestCaseResult,a as removeCommentsAndStringsInSourceCode,o as removeCommentsInSourceCode,c as runCommandInTemporaryPackageManagerProject,l as runPythonInTemporaryUvProject,d as startHttpServer,n as testCaseResultSchema};
|
package/dist/presets/command.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
//# sourceMappingURL=command.cjs.map
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../helpers/parseArgs.cjs"),n=require("../helpers/printTestCaseResult.cjs"),r=require("../types/decisionCode.cjs"),i=require("../helpers/printDebugBanner.cjs"),a=require("../helpers/checkProblemDirIsolation.cjs"),o=require("../helpers/cleanWorkingDirectory.cjs"),s=require("../helpers/copyTestCaseFileInput.cjs"),c=require("../helpers/findEntryPointFile.cjs"),l=require("../helpers/findLanguageDefinitionByPath.cjs"),u=require("../helpers/judgeByStaticAnalysis.cjs"),d=require("../helpers/readOutputFiles.cjs"),f=require("../helpers/readProblemMarkdownFrontMatter.cjs"),p=require("../helpers/readTestCases.cjs"),m=require("../helpers/resolveCwds.cjs"),h=require("../helpers/spawnSyncWithTimeout.cjs");let g=require("zod"),_=require("node:path");_=e.__toESM(_,1);const v=g.z.object({language:g.z.union([g.z.string(),g.z.array(g.z.string())]).optional()});async function y(e,n){let r=t.parseArgs(process.argv),o=v.parse(r.params),{cwds:s,isDebugMode:c}=await m.resolveCwds(e,r.cwd);if(c){let t=s.find(e=>e.expectedResult===`accepted`);if(t){if(!(await a.checkProblemDirIsolation(e,t,o)).passed){process.exitCode=1;return}}else i.printDebugBanner([`[DEBUG MODE] isolated problem directory check skipped`,``,`No accepted model answer is available for checking that the copied judge still accepts a valid submission.`])}for(let t of s){c&&m.printDebugCwdBanner(e,t);let r=await b(e,t.cwd,o,n);c&&!x(t,r)&&(process.exitCode=1,m.printDebugExpectationFailureBanner(e,t))}}async function b(e,t,i,a){let p=await f.readProblemMarkdownFrontMatter(e),m=await(a.readTestCases??T)(e),h=m[0]?.id??`prebuild`,g={buildTimeoutSeconds:a.limits?.buildTimeoutSeconds??10,maxOutputLength:a.limits?.maxOutputLength??5e4},_=a.runTimeoutSeconds??2,v=await u.judgeByStaticAnalysis(t,p);if(v)return n.printTestCaseResult({testCaseId:h,...v}),{allAccepted:!1};let y=await c.findEntryPointFile(t,i.language);if(!y)return n.printTestCaseResult({testCaseId:h,decisionCode:r.DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:`main file not found${i.language?`: language: ${i.language}`:``}`}),{allAccepted:!1};let b=l.findLanguageDefinitionByPath(y);if(!b)return n.printTestCaseResult({testCaseId:h,decisionCode:r.DecisionCode.WRONG_ANSWER,stderr:`unsupported language`}),{allAccepted:!1};let x={...process.env,CI:``,FORCE_COLOR:`0`},w=y;if(b.prebuild)try{await b.prebuild(t);let e=await c.findEntryPointFile(t,i.language);e&&(w=e)}catch(e){return n.printTestCaseResult({testCaseId:h,decisionCode:r.DecisionCode.BUILD_ERROR,stderr:e instanceof Error?e.message:String(e)}),{allAccepted:!1}}let O=b.buildCommand?.(w);if(O){let e=S(O,{cwd:t,env:x,testCaseId:h,limits:g});if(e)return n.printTestCaseResult(e),{allAccepted:!1}}let k=await o.snapshotWorkingDirectory(t);if(m.length===0)return n.printTestCaseResult({testCaseId:`default`,decisionCode:r.DecisionCode.ACCEPTED}),{allAccepted:!0};let A=m.shared?.fileInputPath;for(let e of m){A&&await s.copyTestCaseFileInput(A,t),e.fileInputPath&&await s.copyTestCaseFileInput(e.fileInputPath,t);let i=typeof p.timeLimitMs==`number`?p.timeLimitMs/1e3:_,c=b.command(w),l=e.input??``,u;try{a.resolveInput&&(l=await a.resolveInput({testCase:e,cwd:t,env:x})),u=a.runCommand?await a.runCommand({testCase:e,command:c,stdin:l,cwd:t,env:x,timeLimitSeconds:i}):E(c,{stdin:l,cwd:t,env:x,timeLimitSeconds:i})}catch(i){return n.printTestCaseResult({testCaseId:e.id,decisionCode:r.DecisionCode.RUNTIME_ERROR,stdin:l,stderr:C(i)}),await o.cleanWorkingDirectory(t,k),{allAccepted:!1}}let f=await d.readOutputFiles(t,p.requiredOutputFilePaths??[]),m={timeLimitSeconds:i,outputLimitLength:g.maxOutputLength,problemMarkdownFrontMatter:{memoryLimitByte:p.memoryLimitByte,requiredOutputFilePaths:p.requiredOutputFilePaths}},h=D({runResult:u,outputFiles:f,context:m}),v=h;if(h.decisionCode===r.DecisionCode.ACCEPTED)try{let t=await a.test?.({testCase:e,runResult:u,outputFiles:f,context:m});t&&(v={decisionCode:t.decisionCode??h.decisionCode,feedbackMarkdown:t.feedbackMarkdown,stderr:t.stderr})}catch(e){v={decisionCode:r.DecisionCode.RUNTIME_ERROR,stderr:C(e)}}if(n.printTestCaseResult({testCaseId:e.id,...v,exitStatus:u.status,stdin:u.stdin,stdout:u.stdout.slice(0,g.maxOutputLength)||void 0,stderr:(v.stderr??u.stderr).slice(0,g.maxOutputLength)||void 0,timeSeconds:u.timeSeconds,memoryBytes:u.memoryBytes,outputFiles:f.length>0?f:void 0}),await o.cleanWorkingDirectory(t,k),v.decisionCode!==r.DecisionCode.ACCEPTED)return{allAccepted:!1}}return{allAccepted:!0}}function x(e,t){return t.allAccepted===(e.expectedResult===`accepted`)}function S(e,t){let n=h.spawnSyncWithTimeout(e[0],e.slice(1),{cwd:t.cwd,encoding:`utf8`,env:t.env},t.limits.buildTimeoutSeconds),i=n.status??void 0;if(n.status!==0)return{testCaseId:t.testCaseId,decisionCode:r.DecisionCode.BUILD_ERROR,exitStatus:i,stdout:n.stdout.slice(0,t.limits.maxOutputLength),stderr:n.stderr.slice(0,t.limits.maxOutputLength),timeSeconds:n.timeSeconds,memoryBytes:n.memoryBytes};if(n.timeSeconds>t.limits.buildTimeoutSeconds)return{testCaseId:t.testCaseId,decisionCode:r.DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,exitStatus:i,stdout:n.stdout.slice(0,t.limits.maxOutputLength),stderr:n.stderr.slice(0,t.limits.maxOutputLength),timeSeconds:n.timeSeconds,memoryBytes:n.memoryBytes};if(n.stdout.length>t.limits.maxOutputLength||n.stderr.length>t.limits.maxOutputLength)return{testCaseId:t.testCaseId,decisionCode:r.DecisionCode.BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED,exitStatus:i,stdout:n.stdout.slice(0,t.limits.maxOutputLength),stderr:n.stderr.slice(0,t.limits.maxOutputLength),timeSeconds:n.timeSeconds,memoryBytes:n.memoryBytes}}function C(e){return e instanceof Error?e.message:String(e)}function w(e){return{id:e.id,input:e.input,fileInputPath:e.fileInputPath}}async function T(e){let t=await p.readTestCases(_.default.join(e,`test_cases`)),n=t.map(e=>w(e));return t.shared?.fileInputPath?Object.assign(n,{shared:{fileInputPath:t.shared.fileInputPath}}):n}function E(e,t){let n=h.spawnSyncWithTimeout(e[0],e.slice(1),{cwd:t.cwd,encoding:`utf8`,input:t.stdin,env:t.env},t.timeLimitSeconds);return{stdin:t.stdin,stdout:n.stdout,stderr:n.stderr,status:n.status??void 0,timeSeconds:n.timeSeconds,memoryBytes:n.memoryBytes}}function D(e){if(e.runResult.status!==0)return{decisionCode:r.DecisionCode.RUNTIME_ERROR,stderr:e.runResult.stderr};if(e.runResult.timeSeconds>e.context.timeLimitSeconds)return{decisionCode:r.DecisionCode.TIME_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(e.runResult.memoryBytes>(e.context.problemMarkdownFrontMatter.memoryLimitByte??1/0))return{decisionCode:r.DecisionCode.MEMORY_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(e.runResult.outputLimitExceeded||e.runResult.stdout.length>e.context.outputLimitLength||e.runResult.stderr.length>e.context.outputLimitLength)return{decisionCode:r.DecisionCode.OUTPUT_SIZE_LIMIT_EXCEEDED,stderr:e.runResult.stderr};let t=e.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length??0;return e.outputFiles.length<t?{decisionCode:r.DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR}:{decisionCode:r.DecisionCode.ACCEPTED}}exports.commandJudgePreset=y;
|
|
2
|
+
//# sourceMappingURL=command.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.cjs","sources":["../../src/presets/command.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { z } from 'zod';\n\nimport { checkProblemDirIsolation } from '../helpers/checkProblemDirIsolation.js';\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printDebugBanner } from '../helpers/printDebugBanner.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport {\n printDebugCwdBanner,\n printDebugExpectationFailureBanner,\n resolveCwds,\n type ResolvedCwd,\n} from '../helpers/resolveCwds.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 2;\nconst MAX_STDOUT_LENGTH = 50_000;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ntype JudgeParams = z.infer<typeof judgeParamsSchema>;\n\ninterface BaseCommandTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\ntype CommandJudgeCaseResult = Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown' | 'stderr'>;\n\nexport interface CommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n outputLimitExceeded?: boolean;\n}\n\ninterface CommandJudgeContext {\n timeLimitSeconds: number;\n outputLimitLength: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\nexport interface CommandJudgeLimits {\n buildTimeoutSeconds: number;\n maxOutputLength: number;\n}\n\nexport interface CommandJudgePresetOptions<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n> {\n limits?: CommandJudgeLimits;\n runTimeoutSeconds?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }) => Promise<TRunResult> | TRunResult;\n test?: (context: {\n testCase: TTestCase;\n runResult: TRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n }) => Promise<Partial<CommandJudgeCaseResult>> | Partial<CommandJudgeCaseResult> | undefined;\n}\n\n/**\n * A preset function for judging by executable command.\n *\n * Keep problem-specific logic in `resolveInput` and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { commandJudgePreset } from '@exercode/problem-utils/presets/command';\n * import { DecisionCode } from '@exercode/problem-utils';\n *\n * await commandJudgePreset(import.meta.dirname, {\n * readTestCases: async () => [\n * { id: '01', input: '1 2' },\n * ],\n * test: ({ runResult }) => {\n * return runResult.stdout.trim() === '3'\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n *\n * Run with the required parameters:\n * ```bash\n * bun judge.ts model_answers/python '{ \"language\": \"python\" }'\n * ```\n *\n * Run without a cwd argument to judge each `<problemDir>/model_answers/*` directory\n * for debugging. A prominent banner is printed for each run.\n * ```bash\n * bun judge.ts\n * ```\n */\nexport async function commandJudgePreset<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(problemDir: string, options: CommandJudgePresetOptions<TTestCase, TRunResult>): Promise<void> {\n const args = parseArgs(process.argv);\n const params = judgeParamsSchema.parse(args.params);\n\n const { cwds, isDebugMode } = await resolveCwds(problemDir, args.cwd);\n\n if (isDebugMode) {\n const acceptedCwd = cwds.find((cwd) => cwd.expectedResult === 'accepted');\n if (acceptedCwd) {\n const isolationCheckResult = await checkProblemDirIsolation(problemDir, acceptedCwd, params);\n if (!isolationCheckResult.passed) {\n process.exitCode = 1;\n return;\n }\n } else {\n printDebugBanner([\n '[DEBUG MODE] isolated problem directory check skipped',\n '',\n 'No accepted model answer is available for checking that the copied judge still accepts a valid submission.',\n ]);\n }\n }\n\n for (const resolvedCwd of cwds) {\n if (isDebugMode) printDebugCwdBanner(problemDir, resolvedCwd);\n const result = await runCommandJudgeForCwd<TTestCase, TRunResult>(problemDir, resolvedCwd.cwd, params, options);\n if (isDebugMode && !matchesExpectedResult(resolvedCwd, result)) {\n process.exitCode = 1;\n printDebugExpectationFailureBanner(problemDir, resolvedCwd);\n }\n }\n}\n\nasync function runCommandJudgeForCwd<\n TTestCase extends BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(\n problemDir: string,\n cwd: string,\n params: JudgeParams,\n options: CommandJudgePresetOptions<TTestCase, TRunResult>\n): Promise<{ allAccepted: boolean }> {\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const testCases = await (options.readTestCases ?? readCommandTestCases)(problemDir);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n const limits = {\n buildTimeoutSeconds: options.limits?.buildTimeoutSeconds ?? BUILD_TIMEOUT_SECONDS,\n maxOutputLength: options.limits?.maxOutputLength ?? MAX_STDOUT_LENGTH,\n };\n const runTimeoutSeconds = options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS;\n\n const staticAnalysisResult = await judgeByStaticAnalysis(cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return { allAccepted: false };\n }\n\n const originalMainFilePath = await findEntryPointFile(cwd, params.language);\n if (!originalMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return { allAccepted: false };\n }\n\n const languageDefinition = findLanguageDefinitionByPath(originalMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return { allAccepted: false };\n }\n\n // `CI` changes affects Chainlit. `FORCE_COLOR` affects Bun.\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let mainFilePath = originalMainFilePath;\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(cwd);\n const prebuiltMainFilePath = await findEntryPointFile(cwd, params.language);\n if (prebuiltMainFilePath) mainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: error instanceof Error ? error.message : String(error),\n });\n return { allAccepted: false };\n }\n }\n\n const buildCommand = languageDefinition.buildCommand?.(mainFilePath);\n if (buildCommand) {\n const buildResult = runBuild(buildCommand, {\n cwd,\n env,\n testCaseId: prebuildTestCaseId,\n limits,\n });\n if (buildResult) {\n printTestCaseResult(buildResult);\n return { allAccepted: false };\n }\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(cwd);\n\n if (testCases.length === 0) {\n printTestCaseResult({ testCaseId: 'default', decisionCode: DecisionCode.ACCEPTED });\n return { allAccepted: true };\n }\n\n const sharedFileInputPath = (testCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n\n for (const testCase of testCases) {\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : runTimeoutSeconds;\n\n const command = languageDefinition.command(mainFilePath);\n let stdin = testCase.input ?? '';\n let runResult: TRunResult;\n try {\n if (options.resolveInput) {\n stdin = await options.resolveInput({ testCase, cwd, env });\n }\n\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n })\n : (runCommand(command, {\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n }) as TRunResult);\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n return { allAccepted: false };\n }\n\n const outputFiles = await readOutputFiles(cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: CommandJudgeContext = {\n timeLimitSeconds,\n outputLimitLength: limits.maxOutputLength,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateByLimits({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test?.({ testCase, runResult, outputFiles, context: judgeContext });\n if (extendedJudgeResult) {\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n };\n }\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n printTestCaseResult({\n testCaseId: testCase.id,\n ...judgeResult,\n exitStatus: runResult.status,\n stdin: runResult.stdin,\n stdout: runResult.stdout.slice(0, limits.maxOutputLength) || undefined,\n stderr: (judgeResult.stderr ?? runResult.stderr).slice(0, limits.maxOutputLength) || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n outputFiles: outputFiles.length > 0 ? outputFiles : undefined,\n });\n\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n if (judgeResult.decisionCode !== DecisionCode.ACCEPTED) return { allAccepted: false };\n }\n\n return { allAccepted: true };\n}\n\nfunction matchesExpectedResult(resolvedCwd: ResolvedCwd, result: { allAccepted: boolean }): boolean {\n return result.allAccepted === (resolvedCwd.expectedResult === 'accepted');\n}\n\nfunction runBuild(\n buildCommand: readonly [string, ...string[]],\n context: { cwd: string; env: NodeJS.ProcessEnv; testCaseId: string; limits: CommandJudgeLimits }\n): (Omit<TestCaseResult, 'testCaseId'> & { testCaseId: string }) | undefined {\n const spawnResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n context.limits.buildTimeoutSeconds\n );\n const exitStatus = spawnResult.status ?? undefined;\n\n if (spawnResult.status !== 0) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (spawnResult.timeSeconds > context.limits.buildTimeoutSeconds) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (\n spawnResult.stdout.length > context.limits.maxOutputLength ||\n spawnResult.stderr.length > context.limits.maxOutputLength\n ) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n return;\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toCommandTestCase(value: {\n id: string;\n input?: string;\n fileInputPath?: string;\n fileOutputPath?: string;\n output?: string;\n}): BaseCommandTestCase {\n return { id: value.id, input: value.input, fileInputPath: value.fileInputPath };\n}\n\nasync function readCommandTestCases<TTestCase extends BaseCommandTestCase = BaseCommandTestCase>(\n problemDir: string\n): Promise<readonly TTestCase[]> {\n const fileTestCases = await readFileTestCases(path.join(problemDir, 'test_cases'));\n const commandTestCases = fileTestCases.map((testCase) => toCommandTestCase(testCase) as TTestCase);\n if (fileTestCases.shared?.fileInputPath) {\n return Object.assign(commandTestCases, { shared: { fileInputPath: fileTestCases.shared.fileInputPath } });\n }\n return commandTestCases;\n}\n\nfunction runCommand(\n command: readonly [string, ...string[]],\n context: {\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }\n): CommandRunResult {\n const spawnResult = spawnSyncWithTimeout(\n command[0],\n command.slice(1),\n { cwd: context.cwd, encoding: 'utf8', input: context.stdin, env: context.env },\n context.timeLimitSeconds\n );\n\n return {\n stdin: context.stdin,\n stdout: spawnResult.stdout,\n stderr: spawnResult.stderr,\n status: spawnResult.status ?? undefined,\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n}\n\nfunction evaluateByLimits(context: {\n runResult: CommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n}): CommandJudgeCaseResult {\n if (context.runResult.status !== 0) {\n return { decisionCode: DecisionCode.RUNTIME_ERROR, stderr: context.runResult.stderr };\n }\n\n if (context.runResult.timeSeconds > context.context.timeLimitSeconds) {\n return { decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return { decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.outputLimitExceeded ||\n context.runResult.stdout.length > context.context.outputLimitLength ||\n context.runResult.stderr.length > context.context.outputLimitLength\n ) {\n return { decisionCode: DecisionCode.OUTPUT_SIZE_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n const requiredOutputFileCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFileCount) {\n return { decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n"],"names":["judgeParamsSchema","z","object","language","union","string","array","optional","_commandJudgePreset","_asyncToGenerator","_regenerator","m","_callee","problemDir","options","args","params","_yield$resolveCwds","cwds","isDebugMode","acceptedCwd","_iterator","_step","resolvedCwd","result","_t","w","_context","p","n","parseArgs","process","argv","parse","resolveCwds","cwd","v","find","expectedResult","checkProblemDirIsolation","passed","exitCode","a","printDebugBanner","_createForOfIteratorHelper","s","done","value","printDebugCwdBanner","runCommandJudgeForCwd","matchesExpectedResult","printDebugExpectationFailureBanner","e","f","apply","this","arguments","_x3","_x4","_x5","_x6","_runCommandJudgeForCwd","_callee2","_options$readTestCase","_testCases$0$id","_testCases$","_options$limits$build","_options$limits","_options$limits$maxOu","_options$limits2","_options$runTimeoutSe","_languageDefinition$b","_shared","problemMarkdownFrontMatter","testCases","prebuildTestCaseId","limits","runTimeoutSeconds","staticAnalysisResult","originalMainFilePath","languageDefinition","env","mainFilePath","prebuiltMainFilePath","buildCommand","buildResult","cwdSnapshot","sharedFileInputPath","_iterator2","_step2","_testCase$input","_problemMarkdownFront","_judgeResult$stderr","testCase","timeLimitSeconds","command","stdin","runResult","outputFiles","judgeContext","baseJudgeResult","judgeResult","_options$test","extendedJudgeResult","_extendedJudgeResult$","_t2","_t3","_t4","_t5","_t6","_context2","readProblemMarkdownFrontMatter","readTestCases","readCommandTestCases","id","buildTimeoutSeconds","maxOutputLength","judgeByStaticAnalysis","printTestCaseResult","_objectSpread","testCaseId","allAccepted","findEntryPointFile","decisionCode","DecisionCode","MISSING_REQUIRED_SUBMISSION_FILE_ERROR","stderr","concat","findLanguageDefinitionByPath","WRONG_ANSWER","CI","FORCE_COLOR","prebuild","BUILD_ERROR","Error","message","String","call","runBuild","snapshotWorkingDirectory","length","ACCEPTED","shared","fileInputPath","copyTestCaseFileInput","timeLimitMs","input","resolveInput","runCommand","RUNTIME_ERROR","errorToMessage","cleanWorkingDirectory","readOutputFiles","requiredOutputFilePaths","outputLimitLength","memoryLimitByte","evaluateByLimits","context","test","feedbackMarkdown","exitStatus","status","stdout","slice","undefined","timeSeconds","memoryBytes","_spawnResult$status","spawnResult","spawnSyncWithTimeout","encoding","BUILD_TIME_LIMIT_EXCEEDED","BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED","error","_x7","_readCommandTestCases","_callee3","_fileTestCases$shared","fileTestCases","commandTestCases","_context3","readFileTestCases","path","join","map","Object","assign","_spawnResult$status2","_context$context$prob","_context$context$prob2","_context$context$prob3","TIME_LIMIT_EXCEEDED","Number","POSITIVE_INFINITY","MEMORY_LIMIT_EXCEEDED","outputLimitExceeded","OUTPUT_SIZE_LIMIT_EXCEEDED","requiredOutputFileCount","MISSING_REQUIRED_OUTPUT_FILE_ERROR","_x","_x2"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"command.cjs","names":["z","parseArgs","resolveCwds","checkProblemDirIsolation","readProblemMarkdownFrontMatter","judgeByStaticAnalysis","findEntryPointFile","DecisionCode","findLanguageDefinitionByPath","snapshotWorkingDirectory","copyTestCaseFileInput","cleanWorkingDirectory","readOutputFiles","spawnSyncWithTimeout","readFileTestCases","path"],"sources":["../../src/presets/command.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { z } from 'zod';\n\nimport { checkProblemDirIsolation } from '../helpers/checkProblemDirIsolation.js';\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printDebugBanner } from '../helpers/printDebugBanner.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport {\n printDebugCwdBanner,\n printDebugExpectationFailureBanner,\n resolveCwds,\n type ResolvedCwd,\n} from '../helpers/resolveCwds.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 2;\nconst MAX_STDOUT_LENGTH = 50_000;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ntype JudgeParams = z.infer<typeof judgeParamsSchema>;\n\ninterface BaseCommandTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\ntype CommandJudgeCaseResult = Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown' | 'stderr'>;\n\nexport interface CommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n outputLimitExceeded?: boolean;\n}\n\ninterface CommandJudgeContext {\n timeLimitSeconds: number;\n outputLimitLength: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\nexport interface CommandJudgeLimits {\n buildTimeoutSeconds: number;\n maxOutputLength: number;\n}\n\nexport interface CommandJudgePresetOptions<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n> {\n limits?: CommandJudgeLimits;\n runTimeoutSeconds?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }) => Promise<TRunResult> | TRunResult;\n test?: (context: {\n testCase: TTestCase;\n runResult: TRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n }) => Promise<Partial<CommandJudgeCaseResult>> | Partial<CommandJudgeCaseResult> | undefined;\n}\n\n/**\n * A preset function for judging by executable command.\n *\n * Keep problem-specific logic in `resolveInput` and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { commandJudgePreset } from '@exercode/problem-utils/presets/command';\n * import { DecisionCode } from '@exercode/problem-utils';\n *\n * await commandJudgePreset(import.meta.dirname, {\n * readTestCases: async () => [\n * { id: '01', input: '1 2' },\n * ],\n * test: ({ runResult }) => {\n * return runResult.stdout.trim() === '3'\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n *\n * Run with the required parameters:\n * ```bash\n * bun judge.ts model_answers/python '{ \"language\": \"python\" }'\n * ```\n *\n * Run without a cwd argument to judge each `<problemDir>/model_answers/*` directory\n * for debugging. A prominent banner is printed for each run.\n * ```bash\n * bun judge.ts\n * ```\n */\nexport async function commandJudgePreset<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(problemDir: string, options: CommandJudgePresetOptions<TTestCase, TRunResult>): Promise<void> {\n const args = parseArgs(process.argv);\n const params = judgeParamsSchema.parse(args.params);\n\n const { cwds, isDebugMode } = await resolveCwds(problemDir, args.cwd);\n\n if (isDebugMode) {\n const acceptedCwd = cwds.find((cwd) => cwd.expectedResult === 'accepted');\n if (acceptedCwd) {\n const isolationCheckResult = await checkProblemDirIsolation(problemDir, acceptedCwd, params);\n if (!isolationCheckResult.passed) {\n process.exitCode = 1;\n return;\n }\n } else {\n printDebugBanner([\n '[DEBUG MODE] isolated problem directory check skipped',\n '',\n 'No accepted model answer is available for checking that the copied judge still accepts a valid submission.',\n ]);\n }\n }\n\n for (const resolvedCwd of cwds) {\n if (isDebugMode) printDebugCwdBanner(problemDir, resolvedCwd);\n const result = await runCommandJudgeForCwd<TTestCase, TRunResult>(problemDir, resolvedCwd.cwd, params, options);\n if (isDebugMode && !matchesExpectedResult(resolvedCwd, result)) {\n process.exitCode = 1;\n printDebugExpectationFailureBanner(problemDir, resolvedCwd);\n }\n }\n}\n\nasync function runCommandJudgeForCwd<\n TTestCase extends BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(\n problemDir: string,\n cwd: string,\n params: JudgeParams,\n options: CommandJudgePresetOptions<TTestCase, TRunResult>\n): Promise<{ allAccepted: boolean }> {\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const testCases = await (options.readTestCases ?? readCommandTestCases)(problemDir);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n const limits = {\n buildTimeoutSeconds: options.limits?.buildTimeoutSeconds ?? BUILD_TIMEOUT_SECONDS,\n maxOutputLength: options.limits?.maxOutputLength ?? MAX_STDOUT_LENGTH,\n };\n const runTimeoutSeconds = options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS;\n\n const staticAnalysisResult = await judgeByStaticAnalysis(cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return { allAccepted: false };\n }\n\n const originalMainFilePath = await findEntryPointFile(cwd, params.language);\n if (!originalMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return { allAccepted: false };\n }\n\n const languageDefinition = findLanguageDefinitionByPath(originalMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return { allAccepted: false };\n }\n\n // `CI` changes affects Chainlit. `FORCE_COLOR` affects Bun.\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let mainFilePath = originalMainFilePath;\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(cwd);\n const prebuiltMainFilePath = await findEntryPointFile(cwd, params.language);\n if (prebuiltMainFilePath) mainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: error instanceof Error ? error.message : String(error),\n });\n return { allAccepted: false };\n }\n }\n\n const buildCommand = languageDefinition.buildCommand?.(mainFilePath);\n if (buildCommand) {\n const buildResult = runBuild(buildCommand, {\n cwd,\n env,\n testCaseId: prebuildTestCaseId,\n limits,\n });\n if (buildResult) {\n printTestCaseResult(buildResult);\n return { allAccepted: false };\n }\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(cwd);\n\n if (testCases.length === 0) {\n printTestCaseResult({ testCaseId: 'default', decisionCode: DecisionCode.ACCEPTED });\n return { allAccepted: true };\n }\n\n const sharedFileInputPath = (testCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n\n for (const testCase of testCases) {\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : runTimeoutSeconds;\n\n const command = languageDefinition.command(mainFilePath);\n let stdin = testCase.input ?? '';\n let runResult: TRunResult;\n try {\n if (options.resolveInput) {\n stdin = await options.resolveInput({ testCase, cwd, env });\n }\n\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n })\n : (runCommand(command, {\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n }) as TRunResult);\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n return { allAccepted: false };\n }\n\n const outputFiles = await readOutputFiles(cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: CommandJudgeContext = {\n timeLimitSeconds,\n outputLimitLength: limits.maxOutputLength,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateByLimits({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test?.({ testCase, runResult, outputFiles, context: judgeContext });\n if (extendedJudgeResult) {\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n };\n }\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n printTestCaseResult({\n testCaseId: testCase.id,\n ...judgeResult,\n exitStatus: runResult.status,\n stdin: runResult.stdin,\n stdout: runResult.stdout.slice(0, limits.maxOutputLength) || undefined,\n stderr: (judgeResult.stderr ?? runResult.stderr).slice(0, limits.maxOutputLength) || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n outputFiles: outputFiles.length > 0 ? outputFiles : undefined,\n });\n\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n if (judgeResult.decisionCode !== DecisionCode.ACCEPTED) return { allAccepted: false };\n }\n\n return { allAccepted: true };\n}\n\nfunction matchesExpectedResult(resolvedCwd: ResolvedCwd, result: { allAccepted: boolean }): boolean {\n return result.allAccepted === (resolvedCwd.expectedResult === 'accepted');\n}\n\nfunction runBuild(\n buildCommand: readonly [string, ...string[]],\n context: { cwd: string; env: NodeJS.ProcessEnv; testCaseId: string; limits: CommandJudgeLimits }\n): (Omit<TestCaseResult, 'testCaseId'> & { testCaseId: string }) | undefined {\n const spawnResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n context.limits.buildTimeoutSeconds\n );\n const exitStatus = spawnResult.status ?? undefined;\n\n if (spawnResult.status !== 0) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (spawnResult.timeSeconds > context.limits.buildTimeoutSeconds) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (\n spawnResult.stdout.length > context.limits.maxOutputLength ||\n spawnResult.stderr.length > context.limits.maxOutputLength\n ) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n return;\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toCommandTestCase(value: {\n id: string;\n input?: string;\n fileInputPath?: string;\n fileOutputPath?: string;\n output?: string;\n}): BaseCommandTestCase {\n return { id: value.id, input: value.input, fileInputPath: value.fileInputPath };\n}\n\nasync function readCommandTestCases<TTestCase extends BaseCommandTestCase = BaseCommandTestCase>(\n problemDir: string\n): Promise<readonly TTestCase[]> {\n const fileTestCases = await readFileTestCases(path.join(problemDir, 'test_cases'));\n const commandTestCases = fileTestCases.map((testCase) => toCommandTestCase(testCase) as TTestCase);\n if (fileTestCases.shared?.fileInputPath) {\n return Object.assign(commandTestCases, { shared: { fileInputPath: fileTestCases.shared.fileInputPath } });\n }\n return commandTestCases;\n}\n\nfunction runCommand(\n command: readonly [string, ...string[]],\n context: {\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }\n): CommandRunResult {\n const spawnResult = spawnSyncWithTimeout(\n command[0],\n command.slice(1),\n { cwd: context.cwd, encoding: 'utf8', input: context.stdin, env: context.env },\n context.timeLimitSeconds\n );\n\n return {\n stdin: context.stdin,\n stdout: spawnResult.stdout,\n stderr: spawnResult.stderr,\n status: spawnResult.status ?? undefined,\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n}\n\nfunction evaluateByLimits(context: {\n runResult: CommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n}): CommandJudgeCaseResult {\n if (context.runResult.status !== 0) {\n return { decisionCode: DecisionCode.RUNTIME_ERROR, stderr: context.runResult.stderr };\n }\n\n if (context.runResult.timeSeconds > context.context.timeLimitSeconds) {\n return { decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return { decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.outputLimitExceeded ||\n context.runResult.stdout.length > context.context.outputLimitLength ||\n context.runResult.stderr.length > context.context.outputLimitLength\n ) {\n return { decisionCode: DecisionCode.OUTPUT_SIZE_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n const requiredOutputFileCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFileCount) {\n return { decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n"],"mappings":"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"}
|
package/dist/presets/command.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
//# sourceMappingURL=command.js.map
|
|
1
|
+
import{parseArgs as e}from"../helpers/parseArgs.js";import{printTestCaseResult as t}from"../helpers/printTestCaseResult.js";import{DecisionCode as n}from"../types/decisionCode.js";import{printDebugBanner as r}from"../helpers/printDebugBanner.js";import{checkProblemDirIsolation as i}from"../helpers/checkProblemDirIsolation.js";import{cleanWorkingDirectory as a,snapshotWorkingDirectory as o}from"../helpers/cleanWorkingDirectory.js";import{copyTestCaseFileInput as s}from"../helpers/copyTestCaseFileInput.js";import{findEntryPointFile as c}from"../helpers/findEntryPointFile.js";import{findLanguageDefinitionByPath as l}from"../helpers/findLanguageDefinitionByPath.js";import{judgeByStaticAnalysis as u}from"../helpers/judgeByStaticAnalysis.js";import{readOutputFiles as d}from"../helpers/readOutputFiles.js";import{readProblemMarkdownFrontMatter as f}from"../helpers/readProblemMarkdownFrontMatter.js";import{readTestCases as p}from"../helpers/readTestCases.js";import{printDebugCwdBanner as m,printDebugExpectationFailureBanner as h,resolveCwds as g}from"../helpers/resolveCwds.js";import{spawnSyncWithTimeout as _}from"../helpers/spawnSyncWithTimeout.js";import{z as v}from"zod";import y from"node:path";const b=v.object({language:v.union([v.string(),v.array(v.string())]).optional()});async function x(t,n){let a=e(process.argv),o=b.parse(a.params),{cwds:s,isDebugMode:c}=await g(t,a.cwd);if(c){let e=s.find(e=>e.expectedResult===`accepted`);if(e){if(!(await i(t,e,o)).passed){process.exitCode=1;return}}else r([`[DEBUG MODE] isolated problem directory check skipped`,``,`No accepted model answer is available for checking that the copied judge still accepts a valid submission.`])}for(let e of s){c&&m(t,e);let r=await S(t,e.cwd,o,n);c&&!C(e,r)&&(process.exitCode=1,h(t,e))}}async function S(e,r,i,p){let m=await f(e),h=await(p.readTestCases??D)(e),g=h[0]?.id??`prebuild`,_={buildTimeoutSeconds:p.limits?.buildTimeoutSeconds??10,maxOutputLength:p.limits?.maxOutputLength??5e4},v=p.runTimeoutSeconds??2,y=await u(r,m);if(y)return t({testCaseId:g,...y}),{allAccepted:!1};let b=await c(r,i.language);if(!b)return t({testCaseId:g,decisionCode:n.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:`main file not found${i.language?`: language: ${i.language}`:``}`}),{allAccepted:!1};let x=l(b);if(!x)return t({testCaseId:g,decisionCode:n.WRONG_ANSWER,stderr:`unsupported language`}),{allAccepted:!1};let S={...process.env,CI:``,FORCE_COLOR:`0`},C=b;if(x.prebuild)try{await x.prebuild(r);let e=await c(r,i.language);e&&(C=e)}catch(e){return t({testCaseId:g,decisionCode:n.BUILD_ERROR,stderr:e instanceof Error?e.message:String(e)}),{allAccepted:!1}}let E=x.buildCommand?.(C);if(E){let e=w(E,{cwd:r,env:S,testCaseId:g,limits:_});if(e)return t(e),{allAccepted:!1}}let A=await o(r);if(h.length===0)return t({testCaseId:`default`,decisionCode:n.ACCEPTED}),{allAccepted:!0};let j=h.shared?.fileInputPath;for(let e of h){j&&await s(j,r),e.fileInputPath&&await s(e.fileInputPath,r);let i=typeof m.timeLimitMs==`number`?m.timeLimitMs/1e3:v,o=x.command(C),c=e.input??``,l;try{p.resolveInput&&(c=await p.resolveInput({testCase:e,cwd:r,env:S})),l=p.runCommand?await p.runCommand({testCase:e,command:o,stdin:c,cwd:r,env:S,timeLimitSeconds:i}):O(o,{stdin:c,cwd:r,env:S,timeLimitSeconds:i})}catch(i){return t({testCaseId:e.id,decisionCode:n.RUNTIME_ERROR,stdin:c,stderr:T(i)}),await a(r,A),{allAccepted:!1}}let u=await d(r,m.requiredOutputFilePaths??[]),f={timeLimitSeconds:i,outputLimitLength:_.maxOutputLength,problemMarkdownFrontMatter:{memoryLimitByte:m.memoryLimitByte,requiredOutputFilePaths:m.requiredOutputFilePaths}},h=k({runResult:l,outputFiles:u,context:f}),g=h;if(h.decisionCode===n.ACCEPTED)try{let t=await p.test?.({testCase:e,runResult:l,outputFiles:u,context:f});t&&(g={decisionCode:t.decisionCode??h.decisionCode,feedbackMarkdown:t.feedbackMarkdown,stderr:t.stderr})}catch(e){g={decisionCode:n.RUNTIME_ERROR,stderr:T(e)}}if(t({testCaseId:e.id,...g,exitStatus:l.status,stdin:l.stdin,stdout:l.stdout.slice(0,_.maxOutputLength)||void 0,stderr:(g.stderr??l.stderr).slice(0,_.maxOutputLength)||void 0,timeSeconds:l.timeSeconds,memoryBytes:l.memoryBytes,outputFiles:u.length>0?u:void 0}),await a(r,A),g.decisionCode!==n.ACCEPTED)return{allAccepted:!1}}return{allAccepted:!0}}function C(e,t){return t.allAccepted===(e.expectedResult===`accepted`)}function w(e,t){let r=_(e[0],e.slice(1),{cwd:t.cwd,encoding:`utf8`,env:t.env},t.limits.buildTimeoutSeconds),i=r.status??void 0;if(r.status!==0)return{testCaseId:t.testCaseId,decisionCode:n.BUILD_ERROR,exitStatus:i,stdout:r.stdout.slice(0,t.limits.maxOutputLength),stderr:r.stderr.slice(0,t.limits.maxOutputLength),timeSeconds:r.timeSeconds,memoryBytes:r.memoryBytes};if(r.timeSeconds>t.limits.buildTimeoutSeconds)return{testCaseId:t.testCaseId,decisionCode:n.BUILD_TIME_LIMIT_EXCEEDED,exitStatus:i,stdout:r.stdout.slice(0,t.limits.maxOutputLength),stderr:r.stderr.slice(0,t.limits.maxOutputLength),timeSeconds:r.timeSeconds,memoryBytes:r.memoryBytes};if(r.stdout.length>t.limits.maxOutputLength||r.stderr.length>t.limits.maxOutputLength)return{testCaseId:t.testCaseId,decisionCode:n.BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED,exitStatus:i,stdout:r.stdout.slice(0,t.limits.maxOutputLength),stderr:r.stderr.slice(0,t.limits.maxOutputLength),timeSeconds:r.timeSeconds,memoryBytes:r.memoryBytes}}function T(e){return e instanceof Error?e.message:String(e)}function E(e){return{id:e.id,input:e.input,fileInputPath:e.fileInputPath}}async function D(e){let t=await p(y.join(e,`test_cases`)),n=t.map(e=>E(e));return t.shared?.fileInputPath?Object.assign(n,{shared:{fileInputPath:t.shared.fileInputPath}}):n}function O(e,t){let n=_(e[0],e.slice(1),{cwd:t.cwd,encoding:`utf8`,input:t.stdin,env:t.env},t.timeLimitSeconds);return{stdin:t.stdin,stdout:n.stdout,stderr:n.stderr,status:n.status??void 0,timeSeconds:n.timeSeconds,memoryBytes:n.memoryBytes}}function k(e){if(e.runResult.status!==0)return{decisionCode:n.RUNTIME_ERROR,stderr:e.runResult.stderr};if(e.runResult.timeSeconds>e.context.timeLimitSeconds)return{decisionCode:n.TIME_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(e.runResult.memoryBytes>(e.context.problemMarkdownFrontMatter.memoryLimitByte??1/0))return{decisionCode:n.MEMORY_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(e.runResult.outputLimitExceeded||e.runResult.stdout.length>e.context.outputLimitLength||e.runResult.stderr.length>e.context.outputLimitLength)return{decisionCode:n.OUTPUT_SIZE_LIMIT_EXCEEDED,stderr:e.runResult.stderr};let t=e.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length??0;return e.outputFiles.length<t?{decisionCode:n.MISSING_REQUIRED_OUTPUT_FILE_ERROR}:{decisionCode:n.ACCEPTED}}export{x as commandJudgePreset};
|
|
2
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sources":["../../src/presets/command.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { z } from 'zod';\n\nimport { checkProblemDirIsolation } from '../helpers/checkProblemDirIsolation.js';\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printDebugBanner } from '../helpers/printDebugBanner.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport {\n printDebugCwdBanner,\n printDebugExpectationFailureBanner,\n resolveCwds,\n type ResolvedCwd,\n} from '../helpers/resolveCwds.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 2;\nconst MAX_STDOUT_LENGTH = 50_000;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ntype JudgeParams = z.infer<typeof judgeParamsSchema>;\n\ninterface BaseCommandTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\ntype CommandJudgeCaseResult = Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown' | 'stderr'>;\n\nexport interface CommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n outputLimitExceeded?: boolean;\n}\n\ninterface CommandJudgeContext {\n timeLimitSeconds: number;\n outputLimitLength: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\nexport interface CommandJudgeLimits {\n buildTimeoutSeconds: number;\n maxOutputLength: number;\n}\n\nexport interface CommandJudgePresetOptions<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n> {\n limits?: CommandJudgeLimits;\n runTimeoutSeconds?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }) => Promise<TRunResult> | TRunResult;\n test?: (context: {\n testCase: TTestCase;\n runResult: TRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n }) => Promise<Partial<CommandJudgeCaseResult>> | Partial<CommandJudgeCaseResult> | undefined;\n}\n\n/**\n * A preset function for judging by executable command.\n *\n * Keep problem-specific logic in `resolveInput` and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { commandJudgePreset } from '@exercode/problem-utils/presets/command';\n * import { DecisionCode } from '@exercode/problem-utils';\n *\n * await commandJudgePreset(import.meta.dirname, {\n * readTestCases: async () => [\n * { id: '01', input: '1 2' },\n * ],\n * test: ({ runResult }) => {\n * return runResult.stdout.trim() === '3'\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n *\n * Run with the required parameters:\n * ```bash\n * bun judge.ts model_answers/python '{ \"language\": \"python\" }'\n * ```\n *\n * Run without a cwd argument to judge each `<problemDir>/model_answers/*` directory\n * for debugging. A prominent banner is printed for each run.\n * ```bash\n * bun judge.ts\n * ```\n */\nexport async function commandJudgePreset<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(problemDir: string, options: CommandJudgePresetOptions<TTestCase, TRunResult>): Promise<void> {\n const args = parseArgs(process.argv);\n const params = judgeParamsSchema.parse(args.params);\n\n const { cwds, isDebugMode } = await resolveCwds(problemDir, args.cwd);\n\n if (isDebugMode) {\n const acceptedCwd = cwds.find((cwd) => cwd.expectedResult === 'accepted');\n if (acceptedCwd) {\n const isolationCheckResult = await checkProblemDirIsolation(problemDir, acceptedCwd, params);\n if (!isolationCheckResult.passed) {\n process.exitCode = 1;\n return;\n }\n } else {\n printDebugBanner([\n '[DEBUG MODE] isolated problem directory check skipped',\n '',\n 'No accepted model answer is available for checking that the copied judge still accepts a valid submission.',\n ]);\n }\n }\n\n for (const resolvedCwd of cwds) {\n if (isDebugMode) printDebugCwdBanner(problemDir, resolvedCwd);\n const result = await runCommandJudgeForCwd<TTestCase, TRunResult>(problemDir, resolvedCwd.cwd, params, options);\n if (isDebugMode && !matchesExpectedResult(resolvedCwd, result)) {\n process.exitCode = 1;\n printDebugExpectationFailureBanner(problemDir, resolvedCwd);\n }\n }\n}\n\nasync function runCommandJudgeForCwd<\n TTestCase extends BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(\n problemDir: string,\n cwd: string,\n params: JudgeParams,\n options: CommandJudgePresetOptions<TTestCase, TRunResult>\n): Promise<{ allAccepted: boolean }> {\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const testCases = await (options.readTestCases ?? readCommandTestCases)(problemDir);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n const limits = {\n buildTimeoutSeconds: options.limits?.buildTimeoutSeconds ?? BUILD_TIMEOUT_SECONDS,\n maxOutputLength: options.limits?.maxOutputLength ?? MAX_STDOUT_LENGTH,\n };\n const runTimeoutSeconds = options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS;\n\n const staticAnalysisResult = await judgeByStaticAnalysis(cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return { allAccepted: false };\n }\n\n const originalMainFilePath = await findEntryPointFile(cwd, params.language);\n if (!originalMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return { allAccepted: false };\n }\n\n const languageDefinition = findLanguageDefinitionByPath(originalMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return { allAccepted: false };\n }\n\n // `CI` changes affects Chainlit. `FORCE_COLOR` affects Bun.\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let mainFilePath = originalMainFilePath;\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(cwd);\n const prebuiltMainFilePath = await findEntryPointFile(cwd, params.language);\n if (prebuiltMainFilePath) mainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: error instanceof Error ? error.message : String(error),\n });\n return { allAccepted: false };\n }\n }\n\n const buildCommand = languageDefinition.buildCommand?.(mainFilePath);\n if (buildCommand) {\n const buildResult = runBuild(buildCommand, {\n cwd,\n env,\n testCaseId: prebuildTestCaseId,\n limits,\n });\n if (buildResult) {\n printTestCaseResult(buildResult);\n return { allAccepted: false };\n }\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(cwd);\n\n if (testCases.length === 0) {\n printTestCaseResult({ testCaseId: 'default', decisionCode: DecisionCode.ACCEPTED });\n return { allAccepted: true };\n }\n\n const sharedFileInputPath = (testCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n\n for (const testCase of testCases) {\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : runTimeoutSeconds;\n\n const command = languageDefinition.command(mainFilePath);\n let stdin = testCase.input ?? '';\n let runResult: TRunResult;\n try {\n if (options.resolveInput) {\n stdin = await options.resolveInput({ testCase, cwd, env });\n }\n\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n })\n : (runCommand(command, {\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n }) as TRunResult);\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n return { allAccepted: false };\n }\n\n const outputFiles = await readOutputFiles(cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: CommandJudgeContext = {\n timeLimitSeconds,\n outputLimitLength: limits.maxOutputLength,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateByLimits({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test?.({ testCase, runResult, outputFiles, context: judgeContext });\n if (extendedJudgeResult) {\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n };\n }\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n printTestCaseResult({\n testCaseId: testCase.id,\n ...judgeResult,\n exitStatus: runResult.status,\n stdin: runResult.stdin,\n stdout: runResult.stdout.slice(0, limits.maxOutputLength) || undefined,\n stderr: (judgeResult.stderr ?? runResult.stderr).slice(0, limits.maxOutputLength) || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n outputFiles: outputFiles.length > 0 ? outputFiles : undefined,\n });\n\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n if (judgeResult.decisionCode !== DecisionCode.ACCEPTED) return { allAccepted: false };\n }\n\n return { allAccepted: true };\n}\n\nfunction matchesExpectedResult(resolvedCwd: ResolvedCwd, result: { allAccepted: boolean }): boolean {\n return result.allAccepted === (resolvedCwd.expectedResult === 'accepted');\n}\n\nfunction runBuild(\n buildCommand: readonly [string, ...string[]],\n context: { cwd: string; env: NodeJS.ProcessEnv; testCaseId: string; limits: CommandJudgeLimits }\n): (Omit<TestCaseResult, 'testCaseId'> & { testCaseId: string }) | undefined {\n const spawnResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n context.limits.buildTimeoutSeconds\n );\n const exitStatus = spawnResult.status ?? undefined;\n\n if (spawnResult.status !== 0) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (spawnResult.timeSeconds > context.limits.buildTimeoutSeconds) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (\n spawnResult.stdout.length > context.limits.maxOutputLength ||\n spawnResult.stderr.length > context.limits.maxOutputLength\n ) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n return;\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toCommandTestCase(value: {\n id: string;\n input?: string;\n fileInputPath?: string;\n fileOutputPath?: string;\n output?: string;\n}): BaseCommandTestCase {\n return { id: value.id, input: value.input, fileInputPath: value.fileInputPath };\n}\n\nasync function readCommandTestCases<TTestCase extends BaseCommandTestCase = BaseCommandTestCase>(\n problemDir: string\n): Promise<readonly TTestCase[]> {\n const fileTestCases = await readFileTestCases(path.join(problemDir, 'test_cases'));\n const commandTestCases = fileTestCases.map((testCase) => toCommandTestCase(testCase) as TTestCase);\n if (fileTestCases.shared?.fileInputPath) {\n return Object.assign(commandTestCases, { shared: { fileInputPath: fileTestCases.shared.fileInputPath } });\n }\n return commandTestCases;\n}\n\nfunction runCommand(\n command: readonly [string, ...string[]],\n context: {\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }\n): CommandRunResult {\n const spawnResult = spawnSyncWithTimeout(\n command[0],\n command.slice(1),\n { cwd: context.cwd, encoding: 'utf8', input: context.stdin, env: context.env },\n context.timeLimitSeconds\n );\n\n return {\n stdin: context.stdin,\n stdout: spawnResult.stdout,\n stderr: spawnResult.stderr,\n status: spawnResult.status ?? undefined,\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n}\n\nfunction evaluateByLimits(context: {\n runResult: CommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n}): CommandJudgeCaseResult {\n if (context.runResult.status !== 0) {\n return { decisionCode: DecisionCode.RUNTIME_ERROR, stderr: context.runResult.stderr };\n }\n\n if (context.runResult.timeSeconds > context.context.timeLimitSeconds) {\n return { decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return { decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.outputLimitExceeded ||\n context.runResult.stdout.length > context.context.outputLimitLength ||\n context.runResult.stderr.length > context.context.outputLimitLength\n ) {\n return { decisionCode: DecisionCode.OUTPUT_SIZE_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n const requiredOutputFileCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFileCount) {\n return { decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n"],"names":["judgeParamsSchema","z","object","language","union","string","array","optional","commandJudgePreset","_x","_x2","_commandJudgePreset","apply","this","arguments","_asyncToGenerator","_regenerator","m","_callee","problemDir","options","args","params","_yield$resolveCwds","cwds","isDebugMode","acceptedCwd","_iterator","_step","resolvedCwd","result","_t","w","_context","p","n","parseArgs","process","argv","parse","resolveCwds","cwd","v","find","expectedResult","checkProblemDirIsolation","passed","exitCode","a","printDebugBanner","_createForOfIteratorHelper","s","done","value","printDebugCwdBanner","runCommandJudgeForCwd","matchesExpectedResult","printDebugExpectationFailureBanner","e","f","_x3","_x4","_x5","_x6","_runCommandJudgeForCwd","_callee2","_options$readTestCase","_testCases$0$id","_testCases$","_options$limits$build","_options$limits","_options$limits$maxOu","_options$limits2","_options$runTimeoutSe","_languageDefinition$b","_shared","problemMarkdownFrontMatter","testCases","prebuildTestCaseId","limits","runTimeoutSeconds","staticAnalysisResult","originalMainFilePath","languageDefinition","env","mainFilePath","prebuiltMainFilePath","buildCommand","buildResult","cwdSnapshot","sharedFileInputPath","_iterator2","_step2","_testCase$input","_problemMarkdownFront","_judgeResult$stderr","testCase","timeLimitSeconds","command","stdin","runResult","outputFiles","judgeContext","baseJudgeResult","judgeResult","_options$test","extendedJudgeResult","_extendedJudgeResult$","_t2","_t3","_t4","_t5","_t6","_context2","readProblemMarkdownFrontMatter","readTestCases","readCommandTestCases","id","buildTimeoutSeconds","maxOutputLength","judgeByStaticAnalysis","printTestCaseResult","_objectSpread","testCaseId","allAccepted","findEntryPointFile","decisionCode","DecisionCode","MISSING_REQUIRED_SUBMISSION_FILE_ERROR","stderr","concat","findLanguageDefinitionByPath","WRONG_ANSWER","CI","FORCE_COLOR","prebuild","BUILD_ERROR","Error","message","String","call","runBuild","snapshotWorkingDirectory","length","ACCEPTED","shared","fileInputPath","copyTestCaseFileInput","timeLimitMs","input","resolveInput","runCommand","RUNTIME_ERROR","errorToMessage","cleanWorkingDirectory","readOutputFiles","requiredOutputFilePaths","outputLimitLength","memoryLimitByte","evaluateByLimits","context","test","feedbackMarkdown","exitStatus","status","stdout","slice","undefined","timeSeconds","memoryBytes","_spawnResult$status","spawnResult","spawnSyncWithTimeout","encoding","BUILD_TIME_LIMIT_EXCEEDED","BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED","error","_x7","_readCommandTestCases","_callee3","_fileTestCases$shared","fileTestCases","commandTestCases","_context3","readFileTestCases","path","join","map","Object","assign","_spawnResult$status2","_context$context$prob","_context$context$prob2","_context$context$prob3","TIME_LIMIT_EXCEEDED","Number","POSITIVE_INFINITY","MEMORY_LIMIT_EXCEEDED","outputLimitExceeded","OUTPUT_SIZE_LIMIT_EXCEEDED","requiredOutputFileCount","MISSING_REQUIRED_OUTPUT_FILE_ERROR"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"command.js","names":["readFileTestCases"],"sources":["../../src/presets/command.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { z } from 'zod';\n\nimport { checkProblemDirIsolation } from '../helpers/checkProblemDirIsolation.js';\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printDebugBanner } from '../helpers/printDebugBanner.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport {\n printDebugCwdBanner,\n printDebugExpectationFailureBanner,\n resolveCwds,\n type ResolvedCwd,\n} from '../helpers/resolveCwds.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 2;\nconst MAX_STDOUT_LENGTH = 50_000;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ntype JudgeParams = z.infer<typeof judgeParamsSchema>;\n\ninterface BaseCommandTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\ntype CommandJudgeCaseResult = Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown' | 'stderr'>;\n\nexport interface CommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n outputLimitExceeded?: boolean;\n}\n\ninterface CommandJudgeContext {\n timeLimitSeconds: number;\n outputLimitLength: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\nexport interface CommandJudgeLimits {\n buildTimeoutSeconds: number;\n maxOutputLength: number;\n}\n\nexport interface CommandJudgePresetOptions<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n> {\n limits?: CommandJudgeLimits;\n runTimeoutSeconds?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }) => Promise<TRunResult> | TRunResult;\n test?: (context: {\n testCase: TTestCase;\n runResult: TRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n }) => Promise<Partial<CommandJudgeCaseResult>> | Partial<CommandJudgeCaseResult> | undefined;\n}\n\n/**\n * A preset function for judging by executable command.\n *\n * Keep problem-specific logic in `resolveInput` and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { commandJudgePreset } from '@exercode/problem-utils/presets/command';\n * import { DecisionCode } from '@exercode/problem-utils';\n *\n * await commandJudgePreset(import.meta.dirname, {\n * readTestCases: async () => [\n * { id: '01', input: '1 2' },\n * ],\n * test: ({ runResult }) => {\n * return runResult.stdout.trim() === '3'\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n *\n * Run with the required parameters:\n * ```bash\n * bun judge.ts model_answers/python '{ \"language\": \"python\" }'\n * ```\n *\n * Run without a cwd argument to judge each `<problemDir>/model_answers/*` directory\n * for debugging. A prominent banner is printed for each run.\n * ```bash\n * bun judge.ts\n * ```\n */\nexport async function commandJudgePreset<\n TTestCase extends BaseCommandTestCase = BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(problemDir: string, options: CommandJudgePresetOptions<TTestCase, TRunResult>): Promise<void> {\n const args = parseArgs(process.argv);\n const params = judgeParamsSchema.parse(args.params);\n\n const { cwds, isDebugMode } = await resolveCwds(problemDir, args.cwd);\n\n if (isDebugMode) {\n const acceptedCwd = cwds.find((cwd) => cwd.expectedResult === 'accepted');\n if (acceptedCwd) {\n const isolationCheckResult = await checkProblemDirIsolation(problemDir, acceptedCwd, params);\n if (!isolationCheckResult.passed) {\n process.exitCode = 1;\n return;\n }\n } else {\n printDebugBanner([\n '[DEBUG MODE] isolated problem directory check skipped',\n '',\n 'No accepted model answer is available for checking that the copied judge still accepts a valid submission.',\n ]);\n }\n }\n\n for (const resolvedCwd of cwds) {\n if (isDebugMode) printDebugCwdBanner(problemDir, resolvedCwd);\n const result = await runCommandJudgeForCwd<TTestCase, TRunResult>(problemDir, resolvedCwd.cwd, params, options);\n if (isDebugMode && !matchesExpectedResult(resolvedCwd, result)) {\n process.exitCode = 1;\n printDebugExpectationFailureBanner(problemDir, resolvedCwd);\n }\n }\n}\n\nasync function runCommandJudgeForCwd<\n TTestCase extends BaseCommandTestCase,\n TRunResult extends CommandRunResult = CommandRunResult,\n>(\n problemDir: string,\n cwd: string,\n params: JudgeParams,\n options: CommandJudgePresetOptions<TTestCase, TRunResult>\n): Promise<{ allAccepted: boolean }> {\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const testCases = await (options.readTestCases ?? readCommandTestCases)(problemDir);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n const limits = {\n buildTimeoutSeconds: options.limits?.buildTimeoutSeconds ?? BUILD_TIMEOUT_SECONDS,\n maxOutputLength: options.limits?.maxOutputLength ?? MAX_STDOUT_LENGTH,\n };\n const runTimeoutSeconds = options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS;\n\n const staticAnalysisResult = await judgeByStaticAnalysis(cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return { allAccepted: false };\n }\n\n const originalMainFilePath = await findEntryPointFile(cwd, params.language);\n if (!originalMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return { allAccepted: false };\n }\n\n const languageDefinition = findLanguageDefinitionByPath(originalMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return { allAccepted: false };\n }\n\n // `CI` changes affects Chainlit. `FORCE_COLOR` affects Bun.\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let mainFilePath = originalMainFilePath;\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(cwd);\n const prebuiltMainFilePath = await findEntryPointFile(cwd, params.language);\n if (prebuiltMainFilePath) mainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: error instanceof Error ? error.message : String(error),\n });\n return { allAccepted: false };\n }\n }\n\n const buildCommand = languageDefinition.buildCommand?.(mainFilePath);\n if (buildCommand) {\n const buildResult = runBuild(buildCommand, {\n cwd,\n env,\n testCaseId: prebuildTestCaseId,\n limits,\n });\n if (buildResult) {\n printTestCaseResult(buildResult);\n return { allAccepted: false };\n }\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(cwd);\n\n if (testCases.length === 0) {\n printTestCaseResult({ testCaseId: 'default', decisionCode: DecisionCode.ACCEPTED });\n return { allAccepted: true };\n }\n\n const sharedFileInputPath = (testCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n\n for (const testCase of testCases) {\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : runTimeoutSeconds;\n\n const command = languageDefinition.command(mainFilePath);\n let stdin = testCase.input ?? '';\n let runResult: TRunResult;\n try {\n if (options.resolveInput) {\n stdin = await options.resolveInput({ testCase, cwd, env });\n }\n\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n })\n : (runCommand(command, {\n stdin,\n cwd,\n env,\n timeLimitSeconds,\n }) as TRunResult);\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n return { allAccepted: false };\n }\n\n const outputFiles = await readOutputFiles(cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: CommandJudgeContext = {\n timeLimitSeconds,\n outputLimitLength: limits.maxOutputLength,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateByLimits({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test?.({ testCase, runResult, outputFiles, context: judgeContext });\n if (extendedJudgeResult) {\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n };\n }\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n printTestCaseResult({\n testCaseId: testCase.id,\n ...judgeResult,\n exitStatus: runResult.status,\n stdin: runResult.stdin,\n stdout: runResult.stdout.slice(0, limits.maxOutputLength) || undefined,\n stderr: (judgeResult.stderr ?? runResult.stderr).slice(0, limits.maxOutputLength) || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n outputFiles: outputFiles.length > 0 ? outputFiles : undefined,\n });\n\n await cleanWorkingDirectory(cwd, cwdSnapshot);\n if (judgeResult.decisionCode !== DecisionCode.ACCEPTED) return { allAccepted: false };\n }\n\n return { allAccepted: true };\n}\n\nfunction matchesExpectedResult(resolvedCwd: ResolvedCwd, result: { allAccepted: boolean }): boolean {\n return result.allAccepted === (resolvedCwd.expectedResult === 'accepted');\n}\n\nfunction runBuild(\n buildCommand: readonly [string, ...string[]],\n context: { cwd: string; env: NodeJS.ProcessEnv; testCaseId: string; limits: CommandJudgeLimits }\n): (Omit<TestCaseResult, 'testCaseId'> & { testCaseId: string }) | undefined {\n const spawnResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n context.limits.buildTimeoutSeconds\n );\n const exitStatus = spawnResult.status ?? undefined;\n\n if (spawnResult.status !== 0) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (spawnResult.timeSeconds > context.limits.buildTimeoutSeconds) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n if (\n spawnResult.stdout.length > context.limits.maxOutputLength ||\n spawnResult.stderr.length > context.limits.maxOutputLength\n ) {\n return {\n testCaseId: context.testCaseId,\n decisionCode: DecisionCode.BUILD_OUTPUT_SIZE_LIMIT_EXCEEDED,\n exitStatus,\n stdout: spawnResult.stdout.slice(0, context.limits.maxOutputLength),\n stderr: spawnResult.stderr.slice(0, context.limits.maxOutputLength),\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n }\n\n return;\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toCommandTestCase(value: {\n id: string;\n input?: string;\n fileInputPath?: string;\n fileOutputPath?: string;\n output?: string;\n}): BaseCommandTestCase {\n return { id: value.id, input: value.input, fileInputPath: value.fileInputPath };\n}\n\nasync function readCommandTestCases<TTestCase extends BaseCommandTestCase = BaseCommandTestCase>(\n problemDir: string\n): Promise<readonly TTestCase[]> {\n const fileTestCases = await readFileTestCases(path.join(problemDir, 'test_cases'));\n const commandTestCases = fileTestCases.map((testCase) => toCommandTestCase(testCase) as TTestCase);\n if (fileTestCases.shared?.fileInputPath) {\n return Object.assign(commandTestCases, { shared: { fileInputPath: fileTestCases.shared.fileInputPath } });\n }\n return commandTestCases;\n}\n\nfunction runCommand(\n command: readonly [string, ...string[]],\n context: {\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n }\n): CommandRunResult {\n const spawnResult = spawnSyncWithTimeout(\n command[0],\n command.slice(1),\n { cwd: context.cwd, encoding: 'utf8', input: context.stdin, env: context.env },\n context.timeLimitSeconds\n );\n\n return {\n stdin: context.stdin,\n stdout: spawnResult.stdout,\n stderr: spawnResult.stderr,\n status: spawnResult.status ?? undefined,\n timeSeconds: spawnResult.timeSeconds,\n memoryBytes: spawnResult.memoryBytes,\n };\n}\n\nfunction evaluateByLimits(context: {\n runResult: CommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: CommandJudgeContext;\n}): CommandJudgeCaseResult {\n if (context.runResult.status !== 0) {\n return { decisionCode: DecisionCode.RUNTIME_ERROR, stderr: context.runResult.stderr };\n }\n\n if (context.runResult.timeSeconds > context.context.timeLimitSeconds) {\n return { decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return { decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n if (\n context.runResult.outputLimitExceeded ||\n context.runResult.stdout.length > context.context.outputLimitLength ||\n context.runResult.stderr.length > context.context.outputLimitLength\n ) {\n return { decisionCode: DecisionCode.OUTPUT_SIZE_LIMIT_EXCEEDED, stderr: context.runResult.stderr };\n }\n\n const requiredOutputFileCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFileCount) {\n return { decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
"use strict";var e=require("../_virtual/_rollupPluginBabelHelpers.cjs"),n=require("node:child_process"),r=require("node:fs/promises"),t=require("node:os"),i=require("node:path"),s=require("node:timers/promises"),a=require("zod"),o=require("../helpers/cleanWorkingDirectory.cjs"),c=require("../helpers/copyTestCaseFileInput.cjs"),u=require("../helpers/findEntryPointFile.cjs"),d=require("../helpers/findLanguageDefinitionByPath.cjs"),l=require("../helpers/judgeByStaticAnalysis.cjs"),p=require("../helpers/parseArgs.cjs"),f=require("../helpers/printTestCaseResult.cjs"),m=require("../helpers/readOutputFiles.cjs"),h=require("../helpers/readProblemMarkdownFrontMatter.cjs"),g=require("../helpers/readTestCases.cjs"),v=require("../helpers/spawnSyncWithTimeout.cjs"),w=require("../types/decisionCode.cjs"),b=require("../types/language.cjs"),C=["darwin"===t.platform()?"gtime":"/usr/bin/time","--format","%e %M"],y=a.z.object({language:a.z.union([a.z.string(),a.z.array(a.z.string())]).optional()});function k(){return(k=e.asyncToGenerator(e.regenerator().m(function n(r,t){var i,s,a,g,v,b,C,k,R,F,P,_,L,j,q,x,B,N,A,G,W,z,X,Y,H,Q,V,K,J,$,Z,ee,ne,re,te,ie,se,ae,oe,ce,ue,de,le,pe,fe,me,he,ge,ve,we,be,Ce,ye,ke,Ie,Re,Ee,Se,Te,De,Fe,Me,Pe,_e,Le,Oe,je,qe,xe,Be,Ne,Ae;return e.regenerator().w(function(n){for(;;)switch(n.p=n.n){case 0:if((C=p.parseArgs(process.argv)).cwd){n.n=1;break}throw new Error("cwd argument required");case 1:return k=y.parse(C.params),n.n=2,h.readProblemMarkdownFrontMatter(r);case 2:return R=n.v,n.n=3,(null!=(i=t.readTestCases)?i:D)(r);case 3:return F=n.v,P=F.length>0?F:[{id:"default"}],_=null!=(s=null==(a=P[0])?void 0:a.id)?s:"prebuild",n.n=4,l.judgeByStaticAnalysis(C.cwd,R);case 4:if(!(L=n.v)){n.n=5;break}return f.printTestCaseResult(e.objectSpread2({testCaseId:_},L)),n.a(2);case 5:if(null==(g=t.mainFilePath)){n.n=6;break}Fe=g,n.n=8;break;case 6:return n.n=7,u.findEntryPointFile(C.cwd,k.language);case 7:Fe=n.v;case 8:if(j=Fe){n.n=9;break}return f.printTestCaseResult({testCaseId:_,decisionCode:w.DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:t.mainFilePath?"required main file not found: ".concat(t.mainFilePath):"main file not found".concat(k.language?": language: ".concat(k.language):"")}),n.a(2);case 9:if(q=d.findLanguageDefinitionByPath(j)){n.n=10;break}return f.printTestCaseResult({testCaseId:_,decisionCode:w.DecisionCode.WRONG_ANSWER,stderr:"unsupported language"}),n.a(2);case 10:return x=e.objectSpread2(e.objectSpread2({},process.env),{},{CI:"",FORCE_COLOR:"0"}),n.n=11,I({cwd:C.cwd,language:k.language,configuredMainFilePath:t.mainFilePath});case 11:if(B=n.v,!q.prebuild){n.n=16;break}return n.p=12,n.n=13,q.prebuild(C.cwd);case 13:return n.n=14,I({cwd:C.cwd,language:null!=(N=k.language)?N:E(j),configuredMainFilePath:t.mainFilePath,allowConfiguredPathFallback:!0});case 14:(A=n.v)&&(B=A),n.n=16;break;case 15:return n.p=15,Me=n.v,f.printTestCaseResult({testCaseId:_,decisionCode:w.DecisionCode.BUILD_ERROR,stderr:U(Me)}),n.a(2);case 16:if(B){n.n=17;break}return f.printTestCaseResult({testCaseId:_,decisionCode:w.DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:t.mainFilePath?"required main file not found: ".concat(t.mainFilePath):"main file not found".concat(k.language?": language: ".concat(k.language):"")}),n.a(2);case 17:return n.n=18,null==(b=t.prepare)?void 0:b.call(t,{cwd:C.cwd,env:x,mainFilePath:B,problemMarkdownFrontMatter:R});case 18:if(null==(v=n.v)){n.n=19;break}Pe=v,n.n=20;break;case 19:Pe=S({cwd:C.cwd,env:x,mainFilePath:B,languageDefinition:q});case 20:if(!(G=Pe)){n.n=21;break}return f.printTestCaseResult({testCaseId:_,decisionCode:null!=(W=G.decisionCode)?W:w.DecisionCode.BUILD_ERROR,feedbackMarkdown:G.feedbackMarkdown,stderr:G.stderr,stdout:G.stdout,outputFiles:G.outputFiles}),n.a(2);case 21:return n.n=22,o.snapshotWorkingDirectory(C.cwd);case 22:if(z=n.v,Y=_,n.p=23,!t.runCommand){n.n=24;break}_e=void 0,n.n=26;break;case 24:return n.n=25,O();case 25:_e=n.v;case 26:X=_e,V=null==(Q=F.shared)?void 0:Q.fileInputPath,K=e.createForOfIteratorHelper(P),n.p=27,K.s();case 28:if((J=K.n()).done){n.n=54;break}if(ue=J.value,Y=ue.id,!V){n.n=29;break}return n.n=29,c.copyTestCaseFileInput(V,C.cwd);case 29:if(!ue.fileInputPath){n.n=30;break}return n.n=30,c.copyTestCaseFileInput(ue.fileInputPath,C.cwd);case 30:return de="number"==typeof R.timeLimitMs?R.timeLimitMs/1e3:null!=($=t.runTimeoutSeconds)?$:5,le=X?e.objectSpread2(e.objectSpread2({},x),{},{DISPLAY:X.display}):x,n.n=31,null==(ne=t.resolveInput)?void 0:ne.call(t,{testCase:ue,cwd:C.cwd,env:le});case 31:if(null==(ee=n.v)){n.n=32;break}Le=ee,n.n=33;break;case 32:Le=ue.input;case 33:if(null==(Z=Le)){n.n=34;break}Oe=Z,n.n=35;break;case 34:Oe="";case 35:return H=pe=Oe,n.n=36,null==(te=t.command)?void 0:te.call(t,{testCase:ue,cwd:C.cwd,env:le,mainFilePath:B});case 36:if(null==(re=n.v)){n.n=37;break}je=re,n.n=38;break;case 37:je=q.command(B);case 38:if(fe=je,me=void 0,n.p=39,!t.runCommand){n.n=41;break}return n.n=40,t.runCommand({testCase:ue,command:fe,stdin:pe,cwd:C.cwd,env:le,timeLimitSeconds:de,screenshotWaitSeconds:null!=(he=t.screenshotWaitSeconds)?he:.3,stopDetectionThreshold:null!=(ge=t.stopDetectionThreshold)?ge:5});case 40:qe=n.v,n.n=43;break;case 41:return n.n=42,M({command:fe,stdin:pe,cwd:C.cwd,env:le,timeLimitSeconds:de,screenshotWaitSeconds:null!=(ve=t.screenshotWaitSeconds)?ve:.3,stopDetectionThreshold:null!=(we=t.stopDetectionThreshold)?we:5});case 42:qe=n.v;case 43:me=qe,n.n=46;break;case 44:return n.p=44,xe=n.v,f.printTestCaseResult({testCaseId:ue.id,decisionCode:w.DecisionCode.RUNTIME_ERROR,stdin:pe,stderr:U(xe)}),n.n=45,o.cleanWorkingDirectory(C.cwd,z);case 45:return n.a(2);case 46:return n.n=47,m.readOutputFiles(C.cwd,null!=(ie=R.requiredOutputFilePaths)?ie:[]);case 47:if(be=n.v,Ce={timeLimitSeconds:de,problemMarkdownFrontMatter:{memoryLimitByte:R.memoryLimitByte,requiredOutputFilePaths:R.requiredOutputFilePaths}},ye=T({runResult:me,outputFiles:be,context:Ce}),ke=ye,ye.decisionCode!==w.DecisionCode.ACCEPTED){n.n=51;break}return n.p=48,n.n=49,t.test({testCase:ue,runResult:me,outputFiles:be,context:Ce});case 49:Re=n.v,ke={decisionCode:null!=(Ie=Re.decisionCode)?Ie:ye.decisionCode,feedbackMarkdown:Re.feedbackMarkdown,stderr:Re.stderr,stdout:Re.stdout,outputFiles:Re.outputFiles},n.n=51;break;case 50:n.p=50,Be=n.v,ke={decisionCode:w.DecisionCode.RUNTIME_ERROR,stderr:U(Be)};case 51:return Ee=null!=(se=ke.decisionCode)?se:w.DecisionCode.ACCEPTED,Se=null!=(ae=ke.stdout)?ae:me.stdout,Te=null!=(oe=ke.stderr)?oe:me.stderr,f.printTestCaseResult({testCaseId:ue.id,decisionCode:Ee,exitStatus:me.status,stdin:me.stdin||void 0,stdout:Se||void 0,stderr:Te||void 0,timeSeconds:me.timeSeconds,memoryBytes:me.memoryBytes,feedbackMarkdown:ke.feedbackMarkdown,outputFiles:null!=(ce=ke.outputFiles)?ce:be.length>0?be:void 0}),n.n=52,o.cleanWorkingDirectory(C.cwd,z);case 52:if(Ee===w.DecisionCode.ACCEPTED){n.n=53;break}return n.a(3,54);case 53:n.n=28;break;case 54:n.n=56;break;case 55:n.p=55,Ne=n.v,K.e(Ne);case 56:return n.p=56,K.f(),n.f(56);case 57:n.n=59;break;case 58:return n.p=58,Ae=n.v,f.printTestCaseResult({testCaseId:Y,decisionCode:w.DecisionCode.RUNTIME_ERROR,stdin:H,stderr:U(Ae)}),n.n=59,o.cleanWorkingDirectory(C.cwd,z);case 59:return n.p=59,n.n=60,null==(De=X)?void 0:De.dispose();case 60:return n.f(59);case 61:return n.a(2)}},n,null,[[48,50],[39,44],[27,55,56,57],[23,58,59,61],[12,15]])}))).apply(this,arguments)}function I(e){return R.apply(this,arguments)}function R(){return(R=e.asyncToGenerator(e.regenerator().m(function n(r){var t;return e.regenerator().w(function(e){for(;;)switch(e.n){case 0:if(!r.configuredMainFilePath){e.n=3;break}return t=i.join(r.cwd,r.configuredMainFilePath),e.n=1,A(t);case 1:if(!e.v){e.n=2;break}return e.a(2,r.configuredMainFilePath);case 2:if(r.allowConfiguredPathFallback){e.n=3;break}return e.a(2,void 0);case 3:return e.n=4,u.findEntryPointFile(r.cwd,r.language);case 4:return e.a(2,e.v)}},n)}))).apply(this,arguments)}function E(n){var r=Object.entries(b.languageIdToDefinition).filter(function(r){return e.slicedToArray(r,2)[1].fileExtensions.some(function(e){return n.endsWith(e)})}).map(function(n){return e.slicedToArray(n,1)[0]});return r.length>0?r:void 0}function S(e){var n,r,t=null==(n=(r=e.languageDefinition).buildCommand)?void 0:n.call(r,e.mainFilePath);if(t){var i=v.spawnSyncWithTimeout(t[0],t.slice(1),{cwd:e.cwd,encoding:"utf8",env:e.env},10);return i.timeSeconds>10?{decisionCode:w.DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,stderr:i.stderr||void 0}:0!==i.status?{decisionCode:w.DecisionCode.BUILD_ERROR,stderr:i.stderr||i.stdout||void 0}:void 0}}function T(e){var n,r,t;if("timeout"===e.runResult.stopReason)return{decisionCode:w.DecisionCode.TIME_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(0!==e.runResult.status)return{decisionCode:w.DecisionCode.RUNTIME_ERROR,stderr:e.runResult.stderr};if(e.runResult.memoryBytes>(null!=(n=e.context.problemMarkdownFrontMatter.memoryLimitByte)?n:Number.POSITIVE_INFINITY))return{decisionCode:w.DecisionCode.MEMORY_LIMIT_EXCEEDED,stderr:e.runResult.stderr};var i=null!=(r=null==(t=e.context.problemMarkdownFrontMatter.requiredOutputFilePaths)?void 0:t.length)?r:0;return e.outputFiles.length<i?{decisionCode:w.DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR}:{decisionCode:w.DecisionCode.ACCEPTED}}function D(e){return F.apply(this,arguments)}function F(){return(F=e.asyncToGenerator(e.regenerator().m(function n(r){return e.regenerator().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,g.readTestCases(i.join(r,"test_cases"));case 1:return e.a(2,e.v)}},n)}))).apply(this,arguments)}function M(e){return P.apply(this,arguments)}function P(){return(P=e.asyncToGenerator(e.regenerator().m(function r(t){var i,a,o,c,u,d,l,p,f,m,h,g,v,w,b,y;return e.regenerator().w(function(r){for(;;)switch(r.n){case 0:i=["timeout",t.timeLimitSeconds.toFixed(3)].concat(C,e.toConsumableArray(t.command)),(a=n.spawn(i[0],i.slice(1),{cwd:t.cwd,env:t.env,detached:"win32"!==process.platform,stdio:["pipe","pipe","pipe"]})).stdout.setEncoding("utf8"),a.stderr.setEncoding("utf8"),o="",c="",l="process_exit",p=[],f=[],m=Date.now()/1e3,h=0,a.stdout.on("data",function(e){o+=e}),a.stderr.on("data",function(e){c+=e}),a.on("error",function(e){d=e,u=1}),a.on("close",function(e,n){return 124===e?(l="timeout",void(u=0)):n?(u=1,void(c=c?"".concat(c,"\nprocess terminated by signal: ").concat(n):"process terminated by signal: ".concat(n))):void(u=null!=e?e:1)}),t.stdin&&a.stdin.write(t.stdin),a.stdin.end(),g=e.regenerator().m(function n(){var r,i;return e.regenerator().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,s.setTimeout(1e3*t.screenshotWaitSeconds);case 1:if(h=Math.max(h,B(a.pid)),r=_(t.env.DISPLAY),!((f=r.toSorted(function(e,n){return e.data.length-n.data.length})).length>0)){e.n=2;break}if(i=f.map(function(e){return e.data}).toSorted(),p.unshift(i),p.length=Math.min(p.length,t.stopDetectionThreshold),p.length!==t.stopDetectionThreshold||!p.every(function(e){return e.length===i.length&&e.every(function(e,n){return e===i[n]})})){e.n=2;break}return l="stable_screenshot",u=0,e.a(2,0);case 2:if(!(Date.now()/1e3-m>t.timeLimitSeconds)){e.n=3;break}return l="timeout",u=0,e.a(2,0);case 3:return e.a(2)}},n)});case 1:if(void 0!==u){r.n=4;break}return r.d(e.regeneratorValues(g()),2);case 2:if(0!==r.v){r.n=3;break}return r.a(3,4);case 3:r.n=1;break;case 4:return"process_exit"!==l&&null===a.exitCode&&(a.removeAllListeners("close"),a.removeAllListeners("error")),r.n=5,q(a);case 5:if(!d){r.n=6;break}throw d;case 6:return v=L(c,m,h),w=v.memoryBytes,b=v.stderr,y=v.timeSeconds,r.a(2,{stdin:t.stdin,stdout:o.trimEnd(),stderr:b,status:u,timeSeconds:y,memoryBytes:w,screenshots:f,stopReason:l})}},r)}))).apply(this,arguments)}function _(r){var t=r?e.objectSpread2(e.objectSpread2({},process.env),{},{DISPLAY:r}):process.env,i=n.spawnSync("xwininfo",["-root","-tree"],{encoding:"utf8",env:t});if(i.error)throw i.error;if(0!==i.status||!i.stdout)return[];for(var s=[],a=0,o=function(n){var r,t=[],i=n.split("\n"),s=e.createForOfIteratorHelper(i);try{for(s.s();!(r=s.n()).done;){var a=r.value;if(!(a.includes("Root window id:")||a.includes("Parent window id:")||a.includes("()"))){var o=/^\s{5}(0x[\da-f]+) /.exec(a);null!=o&&o[1]&&t.push(Number.parseInt(o[1],16).toString())}}}catch(e){s.e(e)}finally{s.f()}return t}(i.stdout);a<o.length;a++){var c=o[a],u=n.spawnSync("maim",["-i",c],{env:t});if(u.error)throw u.error;if(0===u.status&&0!==u.stdout.length){var d=n.spawnSync("xdotool",["getwindowname",c],{encoding:"utf8",env:t});if(d.error)throw d.error;var l=d.stdout.trim().replaceAll(/[\s/]/g,"_");s.push({path:"".concat(l||"window","_").concat(c,".png"),data:u.stdout.toString("base64"),encoding:"base64"})}}return s}function L(e,n,r){var t=/(?:^|\n)(\d+\.\d+) (\d+)\s*$/.exec(e),i=t?e.slice(0,t.index).trimEnd():e.trimEnd(),s=1024*Number(null==t?void 0:t[2])||0;return{stderr:i,timeSeconds:Number(null==t?void 0:t[1])||Date.now()/1e3-n,memoryBytes:Math.max(s,r)}}function O(){return j.apply(this,arguments)}function j(){return j=e.asyncToGenerator(e.regenerator().m(function r(){var t,i,a;return e.regenerator().w(function(r){for(;;)switch(r.n){case 0:if("linux"===process.platform){r.n=1;break}throw new Error("GUI screenshot capture is supported only on Linux.");case 1:t=e.regenerator().m(function r(){var t,i,o;return e.regenerator().w(function(r){for(;;)switch(r.n){case 0:return t=":".concat(a),(o=n.spawn("Xvfb",[t,"-screen","0","1280x1024x24","-ac"],{stdio:"ignore"})).on("error",function(e){i=e}),r.n=1,s.setTimeout(300);case 1:if(!i){r.n=2;break}throw i;case 2:if(null===o.exitCode){r.n=3;break}return r.a(2,0);case 3:return r.a(2,{v:{display:t,dispose:function(){var n=e.asyncToGenerator(e.regenerator().m(function n(){return e.regenerator().w(function(e){for(;;)switch(e.n){case 0:if(o.killed){e.n=2;break}return o.kill("SIGTERM"),e.n=1,s.setTimeout(100);case 1:null===o.exitCode&&o.kill("SIGKILL");case 2:return e.a(2)}},n)}));return function(){return n.apply(this,arguments)}}()}})}},r)}),a=90;case 2:if(!(a<100)){r.n=6;break}return r.d(e.regeneratorValues(t()),3);case 3:if(0!==(i=r.v)){r.n=4;break}return r.a(3,5);case 4:if(!i){r.n=5;break}return r.a(2,i.v);case 5:a++,r.n=2;break;case 6:throw new Error("Xvfb could not be started.");case 7:return r.a(2)}},r)})),j.apply(this,arguments)}function q(e){return x.apply(this,arguments)}function x(){return(x=e.asyncToGenerator(e.regenerator().m(function n(r){return e.regenerator().w(function(e){for(;;)switch(e.n){case 0:if(r.pid){e.n=1;break}return e.a(2);case 1:return N(r.pid,"SIGTERM"),e.n=2,s.setTimeout(200);case 2:null===r.exitCode&&N(r.pid,"SIGKILL");case 3:return e.a(2)}},n)}))).apply(this,arguments)}function B(e){if(!e||"linux"!==process.platform)return 0;var r=n.spawnSync("ps",["-o","rss=","--no-headers","--pgroup",String(e)],{encoding:"utf8"});return r.error||0!==r.status||!r.stdout?0:r.stdout.split("\n").map(function(e){return Number(e.trim())}).filter(function(e){return Number.isFinite(e)&&e>0}).reduce(function(e,n){return e+1024*n},0)}function N(e,n){try{if("win32"!==process.platform)return void process.kill(-e,n)}catch(e){}try{process.kill(e,n)}catch(e){}}function A(e){return G.apply(this,arguments)}function G(){return(G=e.asyncToGenerator(e.regenerator().m(function n(t){return e.regenerator().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,e.n=1,r.access(t);case 1:return e.a(2,!0);case 2:return e.p=2,e.v,e.a(2,!1)}},n,null,[[0,2]])}))).apply(this,arguments)}function U(e){return e instanceof Error?e.message:String(e)}exports.guiCommandJudgePreset=function(e,n){return k.apply(this,arguments)};
|
|
2
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../helpers/parseArgs.cjs"),n=require("../helpers/printTestCaseResult.cjs"),r=require("../types/language.cjs"),i=require("../types/decisionCode.cjs"),a=require("../helpers/cleanWorkingDirectory.cjs"),o=require("../helpers/copyTestCaseFileInput.cjs"),s=require("../helpers/findEntryPointFile.cjs"),c=require("../helpers/findLanguageDefinitionByPath.cjs"),l=require("../helpers/judgeByStaticAnalysis.cjs"),u=require("../helpers/readOutputFiles.cjs"),d=require("../helpers/readProblemMarkdownFrontMatter.cjs"),f=require("../helpers/readTestCases.cjs"),p=require("../helpers/spawnSyncWithTimeout.cjs");let m=require("zod"),h=require("node:child_process");h=e.__toESM(h,1);let g=require("node:fs/promises");g=e.__toESM(g,1);let _=require("node:os");_=e.__toESM(_,1);let v=require("node:path");v=e.__toESM(v,1);let y=require("node:timers/promises");const b=.3,x=[_.default.platform()===`darwin`?`gtime`:`/usr/bin/time`,`--format`,`%e %M`],S=m.z.object({language:m.z.union([m.z.string(),m.z.array(m.z.string())]).optional()});async function C(e,r){let f=t.parseArgs(process.argv);if(!f.cwd)throw Error(`cwd argument required`);let p=S.parse(f.params),m=await d.readProblemMarkdownFrontMatter(e),h=await(r.readTestCases??O)(e),g=h.length>0?h:[{id:`default`}],_=g[0]?.id??`prebuild`,v=await l.judgeByStaticAnalysis(f.cwd,m);if(v){n.printTestCaseResult({testCaseId:_,...v});return}let y=r.mainFilePath??await s.findEntryPointFile(f.cwd,p.language);if(!y){n.printTestCaseResult({testCaseId:_,decisionCode:i.DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:r.mainFilePath?`required main file not found: ${r.mainFilePath}`:`main file not found${p.language?`: language: ${p.language}`:``}`});return}let x=c.findLanguageDefinitionByPath(y);if(!x){n.printTestCaseResult({testCaseId:_,decisionCode:i.DecisionCode.WRONG_ANSWER,stderr:`unsupported language`});return}let C={...process.env,CI:``,FORCE_COLOR:`0`},A=await w({cwd:f.cwd,language:p.language,configuredMainFilePath:r.mainFilePath});if(x.prebuild)try{await x.prebuild(f.cwd);let e=await w({cwd:f.cwd,language:p.language??T(y),configuredMainFilePath:r.mainFilePath,allowConfiguredPathFallback:!0});e&&(A=e)}catch(e){n.printTestCaseResult({testCaseId:_,decisionCode:i.DecisionCode.BUILD_ERROR,stderr:R(e)});return}if(!A){n.printTestCaseResult({testCaseId:_,decisionCode:i.DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:r.mainFilePath?`required main file not found: ${r.mainFilePath}`:`main file not found${p.language?`: language: ${p.language}`:``}`});return}let j=await r.prepare?.({cwd:f.cwd,env:C,mainFilePath:A,problemMarkdownFrontMatter:m})??E({cwd:f.cwd,env:C,mainFilePath:A,languageDefinition:x});if(j){n.printTestCaseResult({testCaseId:_,decisionCode:j.decisionCode??i.DecisionCode.BUILD_ERROR,feedbackMarkdown:j.feedbackMarkdown,stderr:j.stderr,stdout:j.stdout,outputFiles:j.outputFiles});return}let M=await a.snapshotWorkingDirectory(f.cwd),P,F=_,I;try{P=r.runCommand?void 0:await N();let e=h.shared?.fileInputPath;for(let t of g){F=t.id,e&&await o.copyTestCaseFileInput(e,f.cwd),t.fileInputPath&&await o.copyTestCaseFileInput(t.fileInputPath,f.cwd);let s=typeof m.timeLimitMs==`number`?m.timeLimitMs/1e3:r.runTimeoutSeconds??5,c=P?{...C,DISPLAY:P.display}:C,l=await r.resolveInput?.({testCase:t,cwd:f.cwd,env:c})??t.input??``;I=l;let d=await r.command?.({testCase:t,cwd:f.cwd,env:c,mainFilePath:A})??x.command(A),p;try{p=r.runCommand?await r.runCommand({testCase:t,command:d,stdin:l,cwd:f.cwd,env:c,timeLimitSeconds:s,screenshotWaitSeconds:r.screenshotWaitSeconds??b,stopDetectionThreshold:r.stopDetectionThreshold??5}):await k({command:d,stdin:l,cwd:f.cwd,env:c,timeLimitSeconds:s,screenshotWaitSeconds:r.screenshotWaitSeconds??b,stopDetectionThreshold:r.stopDetectionThreshold??5})}catch(e){n.printTestCaseResult({testCaseId:t.id,decisionCode:i.DecisionCode.RUNTIME_ERROR,stdin:l,stderr:R(e)}),await a.cleanWorkingDirectory(f.cwd,M);return}let h=await u.readOutputFiles(f.cwd,m.requiredOutputFilePaths??[]),g={timeLimitSeconds:s,problemMarkdownFrontMatter:{memoryLimitByte:m.memoryLimitByte,requiredOutputFilePaths:m.requiredOutputFilePaths}},_=D({runResult:p,outputFiles:h,context:g}),v=_;if(_.decisionCode===i.DecisionCode.ACCEPTED)try{let e=await r.test({testCase:t,runResult:p,outputFiles:h,context:g});v={decisionCode:e.decisionCode??_.decisionCode,feedbackMarkdown:e.feedbackMarkdown,stderr:e.stderr,stdout:e.stdout,outputFiles:e.outputFiles}}catch(e){v={decisionCode:i.DecisionCode.RUNTIME_ERROR,stderr:R(e)}}let y=v.decisionCode??i.DecisionCode.ACCEPTED,S=v.stdout??p.stdout,w=v.stderr??p.stderr;if(n.printTestCaseResult({testCaseId:t.id,decisionCode:y,exitStatus:p.status,stdin:p.stdin||void 0,stdout:S||void 0,stderr:w||void 0,timeSeconds:p.timeSeconds,memoryBytes:p.memoryBytes,feedbackMarkdown:v.feedbackMarkdown,outputFiles:v.outputFiles??(h.length>0?h:void 0)}),await a.cleanWorkingDirectory(f.cwd,M),y!==i.DecisionCode.ACCEPTED)break}}catch(e){n.printTestCaseResult({testCaseId:F,decisionCode:i.DecisionCode.RUNTIME_ERROR,stdin:I,stderr:R(e)}),await a.cleanWorkingDirectory(f.cwd,M)}finally{await P?.dispose()}}async function w(e){if(e.configuredMainFilePath){if(await L(v.default.join(e.cwd,e.configuredMainFilePath)))return e.configuredMainFilePath;if(!e.allowConfiguredPathFallback)return}return await s.findEntryPointFile(e.cwd,e.language)}function T(e){let t=Object.entries(r.languageIdToDefinition).filter(([,t])=>t.fileExtensions.some(t=>e.endsWith(t))).map(([e])=>e);return t.length>0?t:void 0}function E(e){let t=e.languageDefinition.buildCommand?.(e.mainFilePath);if(!t)return;let n=p.spawnSyncWithTimeout(t[0],t.slice(1),{cwd:e.cwd,encoding:`utf8`,env:e.env},10);if(n.timeSeconds>10)return{decisionCode:i.DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,stderr:n.stderr||void 0};if(n.status!==0)return{decisionCode:i.DecisionCode.BUILD_ERROR,stderr:n.stderr||n.stdout||void 0}}function D(e){if(e.runResult.stopReason===`timeout`)return{decisionCode:i.DecisionCode.TIME_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(e.runResult.status!==0)return{decisionCode:i.DecisionCode.RUNTIME_ERROR,stderr:e.runResult.stderr};if(e.runResult.memoryBytes>(e.context.problemMarkdownFrontMatter.memoryLimitByte??1/0))return{decisionCode:i.DecisionCode.MEMORY_LIMIT_EXCEEDED,stderr:e.runResult.stderr};let t=e.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length??0;return e.outputFiles.length<t?{decisionCode:i.DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR}:{decisionCode:i.DecisionCode.ACCEPTED}}async function O(e){return await f.readTestCases(v.default.join(e,`test_cases`))}async function k(e){let t=[`timeout`,e.timeLimitSeconds.toFixed(3),...x,...e.command],n=h.default.spawn(t[0],t.slice(1),{cwd:e.cwd,env:e.env,detached:process.platform!==`win32`,stdio:[`pipe`,`pipe`,`pipe`]});n.stdout.setEncoding(`utf8`),n.stderr.setEncoding(`utf8`);let r=``,i=``,a,o,s=`process_exit`,c=[],l=[],u=Date.now()/1e3,d=0;for(n.stdout.on(`data`,e=>{r+=e}),n.stderr.on(`data`,e=>{i+=e}),n.on(`error`,e=>{o=e,a=1}),n.on(`close`,(e,t)=>{if(e===124){s=`timeout`,a=0;return}if(t){a=1,i=i?`${i}\nprocess terminated by signal: ${t}`:`process terminated by signal: ${t}`;return}a=e??1}),e.stdin&&n.stdin.write(e.stdin),n.stdin.end();a===void 0;){if(await(0,y.setTimeout)(e.screenshotWaitSeconds*1e3),d=Math.max(d,F(n.pid)),l=A(e.env.DISPLAY).toSorted((e,t)=>e.data.length-t.data.length),l.length>0){let t=l.map(e=>e.data).toSorted();if(c.unshift(t),c.length=Math.min(c.length,e.stopDetectionThreshold),c.length===e.stopDetectionThreshold&&c.every(e=>e.length===t.length&&e.every((e,n)=>e===t[n]))){s=`stable_screenshot`,a=0;break}}if(Date.now()/1e3-u>e.timeLimitSeconds){s=`timeout`,a=0;break}}if(s!==`process_exit`&&n.exitCode===null&&(n.removeAllListeners(`close`),n.removeAllListeners(`error`)),await P(n),o)throw o;let{memoryBytes:f,stderr:p,timeSeconds:m}=M(i,u,d);return{stdin:e.stdin,stdout:r.trimEnd(),stderr:p,status:a,timeSeconds:m,memoryBytes:f,screenshots:l,stopReason:s}}function A(e){let t=e?{...process.env,DISPLAY:e}:process.env,n=h.default.spawnSync(`xwininfo`,[`-root`,`-tree`],{encoding:`utf8`,env:t});if(n.error)throw n.error;if(n.status!==0||!n.stdout)return[];let r=[];for(let e of j(n.stdout)){let n=h.default.spawnSync(`maim`,[`-i`,e],{env:t});if(n.error)throw n.error;if(n.status!==0||n.stdout.length===0)continue;let i=h.default.spawnSync(`xdotool`,[`getwindowname`,e],{encoding:`utf8`,env:t});if(i.error)throw i.error;let a=i.stdout.trim().replaceAll(/[\s/]/g,`_`);r.push({path:`${a||`window`}_${e}.png`,data:n.stdout.toString(`base64`),encoding:`base64`})}return r}function j(e){let t=[],n=e.split(`
|
|
2
|
+
`);for(let e of n){if(e.includes(`Root window id:`)||e.includes(`Parent window id:`)||e.includes(`()`))continue;let n=/^\s{5}(0x[\da-f]+) /.exec(e);n?.[1]&&t.push(Number.parseInt(n[1],16).toString())}return t}function M(e,t,n){let r=/(?:^|\n)(\d+\.\d+) (\d+)\s*$/.exec(e),i=r?e.slice(0,r.index).trimEnd():e.trimEnd(),a=Number(r?.[2])*1024||0;return{stderr:i,timeSeconds:Number(r?.[1])||Date.now()/1e3-t,memoryBytes:Math.max(a,n)}}async function N(){if(process.platform!==`linux`)throw Error(`GUI screenshot capture is supported only on Linux.`);for(let e=90;e<100;e++){let t=`:${e}`,n,r=h.default.spawn(`Xvfb`,[t,`-screen`,`0`,`1280x1024x24`,`-ac`],{stdio:`ignore`});if(r.on(`error`,e=>{n=e}),await(0,y.setTimeout)(.3*1e3),n)throw n;if(r.exitCode===null)return{display:t,dispose:async()=>{r.killed||(r.kill(`SIGTERM`),await(0,y.setTimeout)(.1*1e3),r.exitCode===null&&r.kill(`SIGKILL`))}}}throw Error(`Xvfb could not be started.`)}async function P(e){e.pid&&(I(e.pid,`SIGTERM`),await(0,y.setTimeout)(.2*1e3),e.exitCode===null&&I(e.pid,`SIGKILL`))}function F(e){if(!e||process.platform!==`linux`)return 0;let t=h.default.spawnSync(`ps`,[`-o`,`rss=`,`--no-headers`,`--pgroup`,String(e)],{encoding:`utf8`});return t.error||t.status!==0||!t.stdout?0:t.stdout.split(`
|
|
3
|
+
`).map(e=>Number(e.trim())).filter(e=>Number.isFinite(e)&&e>0).reduce((e,t)=>e+t*1024,0)}function I(e,t){try{if(process.platform!==`win32`){process.kill(-e,t);return}}catch{}try{process.kill(e,t)}catch{}}async function L(e){try{return await g.default.access(e),!0}catch{return!1}}function R(e){return e instanceof Error?e.message:String(e)}exports.guiCommandJudgePreset=C;
|
|
4
|
+
//# sourceMappingURL=guiCommand.cjs.map
|