dw-kit 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/lib/copy.mjs CHANGED
@@ -1,110 +1,118 @@
1
- import {
2
- existsSync, mkdirSync, copyFileSync, readdirSync, readFileSync,
3
- } from 'node:fs';
4
- import { join, dirname } from 'node:path';
5
-
6
- export function ensureDir(dir) {
7
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
8
- }
9
-
10
- export function copyFile(src, dst, { dryRun = false } = {}) {
11
- if (dryRun) return { action: 'copy', src, dst, applied: false };
12
- ensureDir(dirname(dst));
13
- copyFileSync(src, dst);
14
- return { action: 'copy', src, dst, applied: true };
15
- }
16
-
17
- export function copyDir(srcDir, dstDir, { dryRun = false, overwrite = false } = {}) {
18
- const results = [];
19
- if (!existsSync(srcDir)) return results;
20
-
21
- const entries = readdirSync(srcDir, { withFileTypes: true });
22
- for (const entry of entries) {
23
- const srcPath = join(srcDir, entry.name);
24
- const dstPath = join(dstDir, entry.name);
25
-
26
- if (entry.isDirectory()) {
27
- results.push(...copyDir(srcPath, dstPath, { dryRun, overwrite }));
28
- } else if (entry.isFile()) {
29
- if (!overwrite && existsSync(dstPath)) {
30
- results.push({ action: 'skip', src: srcPath, dst: dstPath, reason: 'exists' });
31
- continue;
32
- }
33
- results.push(copyFile(srcPath, dstPath, { dryRun }));
34
- }
35
- }
36
- return results;
37
- }
38
-
39
- /**
40
- * Copy files from srcDir to dstDir, respecting an overrides directory.
41
- * Files present in overridesDir take precedence over srcDir.
42
- */
43
- export function copyWithOverrides(srcDir, dstDir, overridesDir, { dryRun = false } = {}) {
44
- const results = [];
45
- if (!existsSync(srcDir)) return results;
46
-
47
- const entries = readdirSync(srcDir, { withFileTypes: true });
48
- for (const entry of entries) {
49
- const srcPath = join(srcDir, entry.name);
50
- const dstPath = join(dstDir, entry.name);
51
- const overridePath = overridesDir ? join(overridesDir, entry.name) : null;
52
-
53
- if (entry.isDirectory()) {
54
- const subOverride = overridePath && existsSync(overridePath) ? overridePath : null;
55
- results.push(...copyWithOverrides(srcPath, dstPath, subOverride, { dryRun }));
56
- } else if (entry.isFile()) {
57
- if (overridePath && existsSync(overridePath)) {
58
- results.push({
59
- action: 'override',
60
- src: overridePath,
61
- dst: dstPath,
62
- ...(dryRun ? { applied: false } : (() => { ensureDir(dirname(dstPath)); copyFileSync(overridePath, dstPath); return { applied: true }; })()),
63
- });
64
- } else {
65
- results.push(copyFile(srcPath, dstPath, { dryRun }));
66
- }
67
- }
68
- }
69
- return results;
70
- }
71
-
72
- /**
73
- * Compute file differences between two directories.
74
- * Returns { added, modified, unchanged } arrays of relative paths.
75
- */
76
- export function diffDirs(sourceDir, targetDir) {
77
- const added = [];
78
- const modified = [];
79
- const unchanged = [];
80
-
81
- if (!existsSync(sourceDir)) return { added, modified, unchanged };
82
-
83
- function walk(dir, base) {
84
- const entries = readdirSync(dir, { withFileTypes: true });
85
- for (const entry of entries) {
86
- const srcPath = join(dir, entry.name);
87
- const relPath = base ? join(base, entry.name) : entry.name;
88
-
89
- if (entry.isDirectory()) {
90
- walk(srcPath, relPath);
91
- } else if (entry.isFile()) {
92
- const targetPath = join(targetDir, relPath);
93
- if (!existsSync(targetPath)) {
94
- added.push(relPath);
95
- } else {
96
- const srcContent = readFileSync(srcPath);
97
- const tgtContent = readFileSync(targetPath);
98
- if (srcContent.equals(tgtContent)) {
99
- unchanged.push(relPath);
100
- } else {
101
- modified.push(relPath);
102
- }
103
- }
104
- }
105
- }
106
- }
107
-
108
- walk(sourceDir, '');
109
- return { added, modified, unchanged };
110
- }
1
+ import {
2
+ existsSync, mkdirSync, copyFileSync, readdirSync, readFileSync, writeFileSync,
3
+ } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+
6
+ export function ensureDir(dir) {
7
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
8
+ }
9
+
10
+ export function copyFile(src, dst, { dryRun = false } = {}) {
11
+ if (dryRun) return { action: 'copy', src, dst, applied: false };
12
+ ensureDir(dirname(dst));
13
+ if (src.endsWith('.sh')) {
14
+ // Always write shell scripts with LF endings.
15
+ // Prevents CRLF contamination when git later checks out these files on Windows
16
+ // (core.autocrlf=true overrides .gitattributes in the *user's* repo, which dw-kit cannot control).
17
+ const content = readFileSync(src, 'utf-8').replace(/\r\n/g, '\n');
18
+ writeFileSync(dst, content, 'utf-8');
19
+ } else {
20
+ copyFileSync(src, dst);
21
+ }
22
+ return { action: 'copy', src, dst, applied: true };
23
+ }
24
+
25
+ export function copyDir(srcDir, dstDir, { dryRun = false, overwrite = false } = {}) {
26
+ const results = [];
27
+ if (!existsSync(srcDir)) return results;
28
+
29
+ const entries = readdirSync(srcDir, { withFileTypes: true });
30
+ for (const entry of entries) {
31
+ const srcPath = join(srcDir, entry.name);
32
+ const dstPath = join(dstDir, entry.name);
33
+
34
+ if (entry.isDirectory()) {
35
+ results.push(...copyDir(srcPath, dstPath, { dryRun, overwrite }));
36
+ } else if (entry.isFile()) {
37
+ if (!overwrite && existsSync(dstPath)) {
38
+ results.push({ action: 'skip', src: srcPath, dst: dstPath, reason: 'exists' });
39
+ continue;
40
+ }
41
+ results.push(copyFile(srcPath, dstPath, { dryRun }));
42
+ }
43
+ }
44
+ return results;
45
+ }
46
+
47
+ /**
48
+ * Copy files from srcDir to dstDir, respecting an overrides directory.
49
+ * Files present in overridesDir take precedence over srcDir.
50
+ */
51
+ export function copyWithOverrides(srcDir, dstDir, overridesDir, { dryRun = false } = {}) {
52
+ const results = [];
53
+ if (!existsSync(srcDir)) return results;
54
+
55
+ const entries = readdirSync(srcDir, { withFileTypes: true });
56
+ for (const entry of entries) {
57
+ const srcPath = join(srcDir, entry.name);
58
+ const dstPath = join(dstDir, entry.name);
59
+ const overridePath = overridesDir ? join(overridesDir, entry.name) : null;
60
+
61
+ if (entry.isDirectory()) {
62
+ const subOverride = overridePath && existsSync(overridePath) ? overridePath : null;
63
+ results.push(...copyWithOverrides(srcPath, dstPath, subOverride, { dryRun }));
64
+ } else if (entry.isFile()) {
65
+ if (overridePath && existsSync(overridePath)) {
66
+ results.push({
67
+ action: 'override',
68
+ src: overridePath,
69
+ dst: dstPath,
70
+ ...(dryRun ? { applied: false } : (() => { ensureDir(dirname(dstPath)); copyFileSync(overridePath, dstPath); return { applied: true }; })()),
71
+ });
72
+ } else {
73
+ results.push(copyFile(srcPath, dstPath, { dryRun }));
74
+ }
75
+ }
76
+ }
77
+ return results;
78
+ }
79
+
80
+ /**
81
+ * Compute file differences between two directories.
82
+ * Returns { added, modified, unchanged } arrays of relative paths.
83
+ */
84
+ export function diffDirs(sourceDir, targetDir) {
85
+ const added = [];
86
+ const modified = [];
87
+ const unchanged = [];
88
+
89
+ if (!existsSync(sourceDir)) return { added, modified, unchanged };
90
+
91
+ function walk(dir, base) {
92
+ const entries = readdirSync(dir, { withFileTypes: true });
93
+ for (const entry of entries) {
94
+ const srcPath = join(dir, entry.name);
95
+ const relPath = base ? join(base, entry.name) : entry.name;
96
+
97
+ if (entry.isDirectory()) {
98
+ walk(srcPath, relPath);
99
+ } else if (entry.isFile()) {
100
+ const targetPath = join(targetDir, relPath);
101
+ if (!existsSync(targetPath)) {
102
+ added.push(relPath);
103
+ } else {
104
+ const srcContent = readFileSync(srcPath);
105
+ const tgtContent = readFileSync(targetPath);
106
+ if (srcContent.equals(tgtContent)) {
107
+ unchanged.push(relPath);
108
+ } else {
109
+ modified.push(relPath);
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ walk(sourceDir, '');
117
+ return { added, modified, unchanged };
118
+ }