// Write the current commit into src/build-info.js. // // Runs before serving and before building, so what is on screen always names // the commit it came from. The file is tracked rather than generated-and- // ignored so that a fresh clone works without running anything first; it // changes at most once per commit, and only when the value actually differs. import { execFileSync } from 'node:child_process'; import { readFileSync, writeFileSync } from 'node:fs'; import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); const target = resolve(root, 'src/build-info.js'); function commit() { try { const sha = execFileSync('git', ['rev-parse', '--short', 'HEAD'], { cwd: root, stdio: 'pipe' }) .toString().trim(); const dirty = execFileSync('git', ['status', '--porcelain'], { cwd: root, stdio: 'pipe' }) .toString().trim().length > 0; return dirty ? `${sha}+` : sha; } catch { return 'dev'; } } const next = `// Stamped by tools/stamp.js, which runs before \`npm run serve\` and // \`npm run build\`. The commit is whatever HEAD was at stamp time, so a dist // file says exactly which commit produced it. export const BUILD = { commit: '${commit()}', builtAt: '${new Date().toISOString().slice(0, 10)}', }; `; const current = readFileSync(target, 'utf8'); // Only the date differs on a same-commit restamp; leave the file alone then, // so a working tree does not churn every time the server starts. const strip = (text) => text.replace(/builtAt: '[^']*'/, ''); if (strip(current) !== strip(next)) { writeFileSync(target, next, 'utf8'); console.log(`stamped build ${commit()}`); }