| 90 | } |
| 91 | |
| 92 | async function resolveArtifactRunDir(artifactDirArg?: string): Promise<string> { |
| 93 | const requested = resolve(REPO_ROOT, artifactDirArg ?? DEFAULT_ARTIFACTS_ROOT) |
| 94 | const requestedResults = resolve(requested, 'results.json') |
| 95 | if (await exists(requestedResults)) { |
| 96 | return requested |
| 97 | } |
| 98 | |
| 99 | const entries = await readdir(requested, { withFileTypes: true }) |
| 100 | const dirs = entries.filter((entry) => entry.isDirectory()) |
| 101 | const runs: Array<{ dir: string; mtimeMs: number }> = [] |
| 102 | |
| 103 | for (const dirent of dirs) { |
| 104 | const dir = resolve(requested, dirent.name) |
| 105 | const resultsPath = resolve(dir, 'results.json') |
| 106 | if (!(await exists(resultsPath))) continue |
| 107 | const stats = await stat(resultsPath) |
| 108 | runs.push({ dir, mtimeMs: stats.mtimeMs }) |
| 109 | } |
| 110 | |
| 111 | if (runs.length === 0) { |
| 112 | throw new Error( |
| 113 | `No artifact run found in ${requested}. Expected a results.json file.` |
| 114 | ) |
| 115 | } |
| 116 | |
| 117 | runs.sort((a, b) => b.mtimeMs - a.mtimeMs) |
| 118 | return runs[0].dir |
| 119 | } |
| 120 | |
| 121 | function toPercent(part: number, total: number): string { |
| 122 | if (total <= 0) return '0.00%' |