From d4cd48e6f70fffb9fda8bbee897d923316378a97 Mon Sep 17 00:00:00 2001 From: avivkeller Date: Mon, 3 Nov 2025 17:55:00 -0500 Subject: [PATCH 1/3] chore(ignore-failure): ignore copy failures --- src/generators/legacy-html/index.mjs | 44 +++++++++++-------- src/generators/legacy-html/utils/safeCopy.mjs | 38 ---------------- 2 files changed, 26 insertions(+), 56 deletions(-) delete mode 100644 src/generators/legacy-html/utils/safeCopy.mjs diff --git a/src/generators/legacy-html/index.mjs b/src/generators/legacy-html/index.mjs index c100967b..517ad338 100644 --- a/src/generators/legacy-html/index.mjs +++ b/src/generators/legacy-html/index.mjs @@ -1,13 +1,12 @@ 'use strict'; -import { readFile, rm, writeFile, mkdir } from 'node:fs/promises'; +import { cp, readFile, rm, writeFile } from 'node:fs/promises'; import { join } from 'node:path'; import HTMLMinifier from '@minify-html/node'; import buildContent from './utils/buildContent.mjs'; import dropdowns from './utils/buildDropdowns.mjs'; -import { safeCopy } from './utils/safeCopy.mjs'; import tableOfContents from './utils/tableOfContents.mjs'; import { groupNodesByModule } from '../../utils/generators.mjs'; import { getRemarkRehype } from '../../utils/remark.mjs'; @@ -170,22 +169,31 @@ export default { } if (output) { - // Define the source folder for API docs assets - const srcAssets = join(baseDir, 'assets'); - - // Define the output folder for API docs assets - const assetsFolder = join(output, 'assets'); - - // Removes the current assets directory to copy the new assets - // and prevent stale assets from existing in the output directory - // If the path does not exists, it will simply ignore and continue - await rm(assetsFolder, { recursive: true, force: true, maxRetries: 10 }); - - // Creates the assets folder if it does not exist - await mkdir(assetsFolder, { recursive: true }); - - // Copy all files from assets folder to output, skipping unchanged files - await safeCopy(srcAssets, assetsFolder); + try { + // Define the output folder for API docs assets + const assetsFolder = join(output, 'assets'); + + // Removes the current assets directory to copy the new assets + // and prevent stale assets from existing in the output directory + // If the path does not exists, it will simply ignore and continue + await rm(assetsFolder, { + recursive: true, + force: true, + maxRetries: 10, + }); + + // We copy all the other assets to the output folder at the end of the process + // to ensure that all latest changes on the styles are applied to the output + // Note.: This is not meant to be used for DX/developer purposes. + await cp(join(baseDir, 'assets'), assetsFolder, { + recursive: true, + force: true, + }); + } finally { + // There's a chance that this step will fail when being run in parallel, since + // the generators will all attempt to modify the same files at the same time. + // In that scenario, we just want to ignore the potential failure. + } } return generatedValues; diff --git a/src/generators/legacy-html/utils/safeCopy.mjs b/src/generators/legacy-html/utils/safeCopy.mjs deleted file mode 100644 index e96b62ed..00000000 --- a/src/generators/legacy-html/utils/safeCopy.mjs +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -import { readFile, writeFile, stat, readdir } from 'node:fs/promises'; -import { join } from 'node:path'; - -/** - * Safely copies files from source to target directory, skipping files that haven't changed - * based on file stats (size and modification time) - * - * @param {string} srcDir - Source directory path - * @param {string} targetDir - Target directory path - */ -export async function safeCopy(srcDir, targetDir) { - const files = await readdir(srcDir); - - for (const file of files) { - const sourcePath = join(srcDir, file); - const targetPath = join(targetDir, file); - - const [sStat, tStat] = await Promise.allSettled([ - stat(sourcePath), - stat(targetPath), - ]); - - const shouldWrite = - tStat.status === 'rejected' || - sStat.value.size !== tStat.value.size || - sStat.value.mtimeMs > tStat.value.mtimeMs; - - if (!shouldWrite) { - continue; - } - - const fileContent = await readFile(sourcePath); - - await writeFile(targetPath, fileContent); - } -} From 0272cdcf58313d6d90b8c2bfcaef3a85ed46933d Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Mon, 3 Nov 2025 18:05:53 -0500 Subject: [PATCH 2/3] Handle potential failures in asset copying Change finally block to catch block to handle potential failures gracefully. --- src/generators/legacy-html/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/legacy-html/index.mjs b/src/generators/legacy-html/index.mjs index 517ad338..31f72ad5 100644 --- a/src/generators/legacy-html/index.mjs +++ b/src/generators/legacy-html/index.mjs @@ -189,7 +189,7 @@ export default { recursive: true, force: true, }); - } finally { + } catch (_) { // There's a chance that this step will fail when being run in parallel, since // the generators will all attempt to modify the same files at the same time. // In that scenario, we just want to ignore the potential failure. From 3eebf20afbbf2f438707464c7b3038424946291f Mon Sep 17 00:00:00 2001 From: avivkeller Date: Mon, 3 Nov 2025 18:07:14 -0500 Subject: [PATCH 3/3] fixup! --- src/generators/legacy-html/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/legacy-html/index.mjs b/src/generators/legacy-html/index.mjs index 31f72ad5..639d864a 100644 --- a/src/generators/legacy-html/index.mjs +++ b/src/generators/legacy-html/index.mjs @@ -189,7 +189,7 @@ export default { recursive: true, force: true, }); - } catch (_) { + } catch { // There's a chance that this step will fail when being run in parallel, since // the generators will all attempt to modify the same files at the same time. // In that scenario, we just want to ignore the potential failure.