-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathsafeCopy.mjs
More file actions
39 lines (32 loc) · 1.15 KB
/
safeCopy.mjs
File metadata and controls
39 lines (32 loc) · 1.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
'use strict';
import { copyFile, readdir, stat } 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). Uses native fs.copyFile which handles
* concurrent operations gracefully.
*
* @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;
}
// Use copyFile with COPYFILE_FICLONE flag for efficient copying
// This is atomic and handles concurrent operations better than manual read/write
await copyFile(sourcePath, targetPath);
}
}