|
| 1 | +// scripts/run.js |
1 | 2 | const core = require('@actions/core'); |
2 | 3 | const { execSync } = require('child_process'); |
3 | | -const fs = require('fs'); |
4 | 4 | const path = require('path'); |
5 | 5 |
|
6 | | - |
7 | 6 | async function main() { |
8 | 7 | try { |
9 | | - // 1) Find all Day*.class files in out/src, sorted by day number |
10 | | - // We'll do something like "ls out/src/Day*.class" + sort -V |
11 | | - let out = ''; |
12 | | - try { |
13 | | - out = execSync('ls out/src/Day*.class 2>/dev/null | sort -V', { |
| 8 | + const out = execSync('ls out/src/Day*.class 2>/dev/null | sort -V', { |
14 | 9 | encoding: 'utf-8', |
15 | 10 | }).trim(); |
16 | | - } catch (e) { |
17 | | - // Possibly no matching files |
18 | | - } |
19 | 11 |
|
20 | 12 | const classFiles = out ? out.split('\n') : []; |
21 | 13 | if (classFiles.length === 0) { |
22 | | - console.log('No compiled classes named Day*.class found.'); |
| 14 | + console.log('No compiled classes named "Day*.class" found in out/src.'); |
23 | 15 | return; |
24 | 16 | } |
25 | 17 |
|
26 | | - // 2) Prepare a summary table |
27 | | - const summaryTable = [ |
28 | | - [ |
29 | | - { data: 'Day', header: true }, |
30 | | - { data: 'Class Name', header: true }, |
31 | | - { data: 'Status', header: true }, |
32 | | - ], |
33 | | - ]; |
| 18 | + // 2) We'll store results in a map from day => array of results |
| 19 | + // For each day, we keep { className, status, durationMs } |
| 20 | + const resultsByDay = {}; |
34 | 21 |
|
35 | | - let currentDay = null; |
36 | | - |
37 | | - // 3) For each Day*.class, extract the day number, run it, etc. |
| 22 | + // 3) Run each class, measure time |
38 | 23 | for (const filePath of classFiles) { |
39 | | - // e.g. out/src/Day10.class → Day10 |
40 | | - const base = path.basename(filePath, '.class'); |
41 | | - const className = base; // e.g. Day10 |
42 | | - |
43 | | - // Extract the day number from "Day10", "Day10Part2", etc. |
| 24 | + const className = path.basename(filePath, '.class'); // e.g. "Day10Part2" |
44 | 25 | const match = className.match(/^Day(\d+)/); |
45 | | - if (!match) { |
46 | | - continue; // skip if it doesn't match "DayNN" |
47 | | - } |
| 26 | + if (!match) continue; |
| 27 | + |
48 | 28 | const dayNum = match[1]; |
49 | 29 |
|
50 | | - // If day changed, print a console heading |
51 | | - if (dayNum !== currentDay) { |
52 | | - currentDay = dayNum; |
53 | | - const emoji = '🎄🔹🎄'; |
54 | | - console.log('========================================'); |
55 | | - console.log(` Day ${dayNum} ${emoji}`); |
56 | | - console.log('========================================\n'); |
| 30 | + // Ensure there's a bucket for this day |
| 31 | + if (!resultsByDay[dayNum]) { |
| 32 | + resultsByDay[dayNum] = []; |
57 | 33 | } |
58 | 34 |
|
59 | | - console.log(`Running ${className}...`); |
| 35 | + console.log(`Running ${className} (Day ${dayNum})...`); |
| 36 | + const start = Date.now(); |
| 37 | + |
60 | 38 | let exitCode = 0; |
61 | 39 | let stdout = ''; |
62 | 40 | try { |
63 | | - // Run the class from out/src |
64 | 41 | stdout = execSync(`java -cp out/src ${className}`, { encoding: 'utf-8' }); |
65 | 42 | } catch (error) { |
66 | 43 | exitCode = error.status || 1; |
67 | 44 | stdout = error.stdout?.toString() || ''; |
68 | 45 | } |
| 46 | + const end = Date.now(); |
| 47 | + const durationMs = end - start; |
69 | 48 |
|
70 | 49 | console.log(stdout); |
71 | | - const statusMsg = exitCode === 0 ? '✅ Success' : '❌ Failed'; |
72 | | - console.log(statusMsg, '\n'); |
73 | | - |
74 | | - // Append to summary |
75 | | - summaryTable.push([ |
76 | | - `${dayNum} ${'🎄🎄🎄'}`, |
77 | | - `\`${className}\``, |
78 | | - statusMsg, |
79 | | - ]); |
| 50 | + const statusMsg = exitCode === 0 ? 'Success' : 'Failed'; |
| 51 | + console.log(`${statusMsg} [${durationMs} ms]\n`); |
| 52 | + |
| 53 | + // Store the info for this day |
| 54 | + resultsByDay[dayNum].push({ |
| 55 | + className, |
| 56 | + status: statusMsg, |
| 57 | + duration: durationMs, |
| 58 | + }); |
| 59 | + } |
| 60 | + |
| 61 | + // 4) Now build the Summary content day by day |
| 62 | + // Instead of one big table, we create one table *per* day |
| 63 | + core.summary.addHeading('Build & Run Java Files - Summary', 2); |
| 64 | + |
| 65 | + // Sort the days numerically |
| 66 | + const sortedDays = Object.keys(resultsByDay).sort((a, b) => Number(a) - Number(b)); |
| 67 | + |
| 68 | + for (const day of sortedDays) { |
| 69 | + core.summary.addHeading(`Day ${day}`, 3); |
| 70 | + |
| 71 | + // Build a small table for this day |
| 72 | + const tableData = [ |
| 73 | + [ |
| 74 | + { data: 'Class Name', header: true }, |
| 75 | + { data: 'Status', header: true }, |
| 76 | + { data: 'Duration (ms)', header: true }, |
| 77 | + ], |
| 78 | + ]; |
| 79 | + |
| 80 | + for (const row of resultsByDay[day]) { |
| 81 | + tableData.push([ |
| 82 | + `\`${row.className}\``, |
| 83 | + row.status, |
| 84 | + row.duration.toString(), |
| 85 | + ]); |
| 86 | + } |
| 87 | + |
| 88 | + core.summary.addTable(tableData); |
80 | 89 | } |
81 | 90 |
|
82 | | - // 4) Write the summary |
83 | | - await core.summary |
84 | | - .addHeading('Build & Run Java Files - Summary', 2) |
85 | | - .addTable(summaryTable) |
86 | | - .write(); |
| 91 | + await core.summary.write(); |
87 | 92 |
|
88 | 93 | } catch (err) { |
89 | 94 | core.setFailed(`Script error: ${err.message}`); |
|
0 commit comments