-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathsafeCopy.mjs
More file actions
41 lines (33 loc) · 1.05 KB
/
safeCopy.mjs
File metadata and controls
41 lines (33 loc) · 1.05 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
40
41
'use strict';
import { copyFile, readdir, stat, constants } from 'node:fs/promises';
import { join } from 'node:path';
/**
* Attempts to copy a file forcibly (`COPYFILE_FICLONE_FORCE`. Otherwise, falls back to a time-based check approach)
*
* @param {string} srcDir - Source directory path
* @param {string} targetDir - Target directory path
*/
export async function safeCopy(srcDir, targetDir) {
try {
await copyFile(srcDir, targetDir, constants.COPYFILE_FICLONE);
} catch (err) {
if (err?.syscall !== 'copyfile') {
throw err;
}
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.all([
stat(sourcePath),
stat(targetPath),
]).catch(() => []);
const shouldWrite =
!tStat || sStat.size !== tStat.size || sStat.mtimeMs > tStat.mtimeMs;
if (!shouldWrite) {
continue;
}
await copyFile(sourcePath, targetPath);
}
}
}