Skip to content

Commit f739149

Browse files
committed
@aduh95 suggestion
1 parent a11e966 commit f739149

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,40 @@ import { copyFile, readdir, stat, constants } from 'node:fs/promises';
44
import { join } from 'node:path';
55

66
/**
7-
* Safely copies files from source to target directory, skipping files that haven't changed
8-
* based on file stats (size and modification time). Uses native fs.copyFile which handles
9-
* concurrent operations gracefully.
7+
* Attempts to copy a file forcibly (`COPYFILE_FICLONE_FORCE`. Otherwise, falls back to a time-based check approach)
108
*
119
* @param {string} srcDir - Source directory path
1210
* @param {string} targetDir - Target directory path
1311
*/
1412
export async function safeCopy(srcDir, targetDir) {
15-
const files = await readdir(srcDir);
13+
try {
14+
await copyFile(srcDir, targetDir, constants.COPYFILE_FICLONE);
15+
} catch (err) {
16+
if (err?.syscall !== 'copyfile') {
17+
throw err;
18+
}
1619

17-
for (const file of files) {
18-
const sourcePath = join(srcDir, file);
19-
const targetPath = join(targetDir, file);
20+
const files = await readdir(srcDir);
2021

21-
const [sStat, tStat] = await Promise.allSettled([
22-
stat(sourcePath),
23-
stat(targetPath),
24-
]);
22+
for (const file of files) {
23+
const sourcePath = join(srcDir, file);
24+
const targetPath = join(targetDir, file);
2525

26-
const shouldWrite =
27-
tStat.status === 'rejected' ||
28-
sStat.value.size !== tStat.value.size ||
29-
sStat.value.mtimeMs > tStat.value.mtimeMs;
26+
const [sStat, tStat] = await Promise.allSettled([
27+
stat(sourcePath),
28+
stat(targetPath),
29+
]);
3030

31-
if (!shouldWrite) {
32-
continue;
33-
}
31+
const shouldWrite =
32+
tStat.status === 'rejected' ||
33+
sStat.value.size !== tStat.value.size ||
34+
sStat.value.mtimeMs > tStat.value.mtimeMs;
3435

35-
// Use copyFile with COPYFILE_FICLONE flag for efficient copying
36-
// This is atomic and handles concurrent operations better than manual read/write
37-
await copyFile(sourcePath, targetPath, constants.COPYFILE_FICLONE);
36+
if (!shouldWrite) {
37+
continue;
38+
}
39+
40+
await copyFile(sourcePath, targetPath);
41+
}
3842
}
3943
}

0 commit comments

Comments
 (0)