From 473a19a699a61c57f79af6e4ec797e64ad2a94e0 Mon Sep 17 00:00:00 2001 From: 4gray Date: Thu, 27 Aug 2026 10:53:26 +0200 Subject: [PATCH] fix(release): print an absolute path when the output escapes the repo `--out /tmp/cards` reported every written file as a stack of `../../..` segments, which is less readable than the path it was shortening. Paths inside the workspace stay repo-relative. Found by an end-to-end run of the documented commands rather than by a test: the tooling worked, its output did not. Co-Authored-By: Claude Fable 5 --- tools/release/generate-highlight-cards.mjs | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tools/release/generate-highlight-cards.mjs b/tools/release/generate-highlight-cards.mjs index 6628de4c1..637e44a7e 100644 --- a/tools/release/generate-highlight-cards.mjs +++ b/tools/release/generate-highlight-cards.mjs @@ -140,6 +140,20 @@ async function prepareShotOverlay(screenshotPath) { return { input: cropped, left: SHOT_LEFT, top: SHOT_TOP }; } +/** + * Repo-relative when the path is inside the workspace, absolute otherwise: + * `--out /tmp/cards` printed as a stack of `../../..` segments is worse than + * no shortening at all. + * + * @param {string} target + * @returns {string} + */ +function displayPath(target) { + const relative = path.relative(workspaceRoot, target); + + return relative.startsWith('..') ? target : relative; +} + /** * Removes the cards a previous run of THIS generator left in `outputDir`, so a * renamed, dropped, or newly-internal highlight cannot leave a stale image @@ -231,7 +245,7 @@ async function main() { if (notes.length === 0) { console.error( [ - `No notes found in ${path.relative(workspaceRoot, notesDir)}/.`, + `No notes found in ${displayPath(notesDir)}/.`, 'Cards are built from `highlight:`, which exists only in the note', 'files — if `build-release-notes.mjs --consume` already ran, that', 'metadata is gone. Render cards before consuming.', @@ -300,7 +314,7 @@ async function main() { console.error('Missing screenshot(s) for highlight card(s):\n'); for (const job of missingShots) { console.error( - ` ${path.relative(workspaceRoot, job.screenshotPath)}` + ` ${displayPath(job.screenshotPath)}` ); } console.error('\nRun `pnpm run release:screenshots` first.'); @@ -310,14 +324,14 @@ async function main() { console.log(`${plan.feature.length} highlight card(s) + hero for v${options.version}:`); for (const job of plan.feature) { const shot = job.screenshotPath - ? path.relative(workspaceRoot, job.screenshotPath) + ? displayPath(job.screenshotPath) : 'no screenshot (typographic card)'; console.log(` ${job.fileName} — "${job.headline}" (${shot})`); } if (options.mode === 'dry-run') { - console.log(`\nWould write to ${path.relative(workspaceRoot, outputDir)}/.`); + console.log(`\nWould write to ${displayPath(outputDir)}/.`); return; } @@ -335,7 +349,7 @@ async function main() { const written = await renderCards(plan, options.version, outputDir); for (const file of written) { - console.log(`Wrote ${path.relative(workspaceRoot, file)}`); + console.log(`Wrote ${displayPath(file)}`); } console.log(