Skip to content

Commit 0a64160

Browse files
ovflowdaduh95avivkeller
authored
chore: a tiny bit safer approach (#482)
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> Co-authored-by: avivkeller <me@aviv.sh>
1 parent be7fc30 commit 0a64160

File tree

3 files changed

+16
-28
lines changed

3 files changed

+16
-28
lines changed

src/generators/legacy-html/index.mjs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
import { readFile, rm, writeFile, mkdir } from 'node:fs/promises';
3+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
44
import { join } from 'node:path';
55

66
import HTMLMinifier from '@minify-html/node';
@@ -176,11 +176,6 @@ export default {
176176
// Define the output folder for API docs assets
177177
const assetsFolder = join(output, 'assets');
178178

179-
// Removes the current assets directory to copy the new assets
180-
// and prevent stale assets from existing in the output directory
181-
// If the path does not exists, it will simply ignore and continue
182-
await rm(assetsFolder, { recursive: true, force: true, maxRetries: 10 });
183-
184179
// Creates the assets folder if it does not exist
185180
await mkdir(assetsFolder, { recursive: true });
186181

src/generators/legacy-html/utils/__tests__/safeCopy.test.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,6 @@ describe('safeCopy', () => {
102102
it('should handle empty source directory', async () => {
103103
// Don't create any files in source
104104
await safeCopy(srcDir, targetDir);
105-
106-
// Verify no error occurred and target is still empty
107-
const files = await readFile(targetDir).catch(() => []);
108-
assert.ok(Array.isArray(files) || files === undefined);
109105
});
110106

111107
it('should copy files with same size but different content when mtime is newer', async () => {
Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,35 @@
11
'use strict';
22

3-
import { readFile, writeFile, stat, readdir } from 'node:fs/promises';
3+
import { statSync, constants } from 'node:fs';
4+
import { copyFile, readdir } from 'node:fs/promises';
45
import { join } from 'node:path';
56

67
/**
7-
* Safely copies files from source to target directory, skipping files that haven't changed
8-
* based on file stats (size and modification time)
8+
* Copies files from source to target directory, skipping files that haven't changed.
9+
* Uses synchronous stat checks for simplicity and copyFile for atomic operations.
910
*
1011
* @param {string} srcDir - Source directory path
1112
* @param {string} targetDir - Target directory path
1213
*/
1314
export async function safeCopy(srcDir, targetDir) {
1415
const files = await readdir(srcDir);
1516

16-
for (const file of files) {
17+
const promises = files.map(file => {
1718
const sourcePath = join(srcDir, file);
1819
const targetPath = join(targetDir, file);
1920

20-
const [sStat, tStat] = await Promise.allSettled([
21-
stat(sourcePath),
22-
stat(targetPath),
23-
]);
21+
const tStat = statSync(targetPath, { throwIfNoEntry: false });
2422

25-
const shouldWrite =
26-
tStat.status === 'rejected' ||
27-
sStat.value.size !== tStat.value.size ||
28-
sStat.value.mtimeMs > tStat.value.mtimeMs;
29-
30-
if (!shouldWrite) {
31-
continue;
23+
if (tStat === undefined) {
24+
return copyFile(sourcePath, targetPath, constants.COPYFILE_FICLONE);
3225
}
3326

34-
const fileContent = await readFile(sourcePath);
27+
const sStat = statSync(sourcePath);
28+
29+
if (sStat.size !== tStat.size || sStat.mtimeMs > tStat.mtimeMs) {
30+
return copyFile(sourcePath, targetPath, constants.COPYFILE_FICLONE);
31+
}
32+
});
3533

36-
await writeFile(targetPath, fileContent);
37-
}
34+
await Promise.all(promises);
3835
}

0 commit comments

Comments
 (0)