@ricsam/r5d-worker 0.0.78 → 0.0.79
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/README.md +6 -0
- package/dist/cjs/main.cjs +1550 -335
- package/dist/cjs/managed-paths.cjs +101 -1
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/project-workspace-state.cjs +184 -5
- package/dist/cjs/project-worktrees.cjs +641 -56
- package/dist/cjs/registry-auth.cjs +310 -0
- package/dist/cjs/repository-transition-policy.cjs +49 -0
- package/dist/cjs/supervisor.cjs +62 -11
- package/dist/cjs/working-tree-mirror.cjs +191 -34
- package/dist/cjs/workspace-automatic-sync-policy.cjs +69 -0
- package/dist/cjs/workspace-branch-incarnation-policy.cjs +37 -0
- package/dist/cjs/workspace-command-sync-policy.cjs +18 -0
- package/dist/cjs/workspace-git-sync.cjs +1028 -54
- package/dist/cjs/workspace-mount-boundary.cjs +71 -0
- package/dist/cjs/workspace-path-move.cjs +195 -0
- package/dist/cjs/workspace-preserve-only-policy.cjs +36 -0
- package/dist/cjs/workspace-project-config-policy.cjs +46 -0
- package/dist/cjs/workspace-publication-evidence.cjs +46 -0
- package/dist/mjs/main.mjs +1584 -341
- package/dist/mjs/managed-paths.mjs +100 -1
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/project-workspace-state.mjs +181 -5
- package/dist/mjs/project-worktrees.mjs +632 -55
- package/dist/mjs/registry-auth.mjs +269 -0
- package/dist/mjs/repository-transition-policy.mjs +22 -0
- package/dist/mjs/supervisor.mjs +61 -11
- package/dist/mjs/working-tree-mirror.mjs +190 -34
- package/dist/mjs/workspace-automatic-sync-policy.mjs +40 -0
- package/dist/mjs/workspace-branch-incarnation-policy.mjs +13 -0
- package/dist/mjs/workspace-command-sync-policy.mjs +17 -0
- package/dist/mjs/workspace-git-sync.mjs +1023 -54
- package/dist/mjs/workspace-mount-boundary.mjs +37 -0
- package/dist/mjs/workspace-path-move.mjs +160 -0
- package/dist/mjs/workspace-preserve-only-policy.mjs +11 -0
- package/dist/mjs/workspace-project-config-policy.mjs +21 -0
- package/dist/mjs/workspace-publication-evidence.mjs +21 -0
- package/dist/types/credential-authority-lock-fixture.d.ts +1 -0
- package/dist/types/main.d.ts +175 -1
- package/dist/types/managed-paths.d.ts +11 -0
- package/dist/types/project-workspace-state.d.ts +45 -1
- package/dist/types/project-worktrees.d.ts +119 -2
- package/dist/types/registry-auth.d.ts +47 -0
- package/dist/types/repository-transition-policy.d.ts +26 -0
- package/dist/types/supervisor-daemonized-fixture.d.ts +1 -0
- package/dist/types/supervisor-signal-fixture.d.ts +1 -0
- package/dist/types/supervisor.d.ts +6 -4
- package/dist/types/working-tree-mirror.d.ts +7 -0
- package/dist/types/workspace-automatic-sync-policy.d.ts +37 -0
- package/dist/types/workspace-branch-incarnation-policy.d.ts +14 -0
- package/dist/types/workspace-command-sync-policy.d.ts +9 -0
- package/dist/types/workspace-git-sync.d.ts +33 -3
- package/dist/types/workspace-mount-boundary.d.ts +10 -0
- package/dist/types/workspace-path-move.d.ts +21 -0
- package/dist/types/workspace-preserve-only-policy.d.ts +15 -0
- package/dist/types/workspace-project-config-policy.d.ts +34 -0
- package/dist/types/workspace-publication-evidence.d.ts +17 -0
- package/package.json +1 -1
|
@@ -28,15 +28,45 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var working_tree_mirror_exports = {};
|
|
30
30
|
__export(working_tree_mirror_exports, {
|
|
31
|
+
assertWorkingTreeHasNoPortableGitMetadataAliases: () => assertWorkingTreeHasNoPortableGitMetadataAliases,
|
|
31
32
|
inspectWorkingTree: () => inspectWorkingTree,
|
|
32
33
|
mirrorWorkingTree: () => mirrorWorkingTree
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(working_tree_mirror_exports);
|
|
35
36
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
36
37
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
38
|
+
var import_node_crypto = require("node:crypto");
|
|
37
39
|
var import_git_process_environment = require("./git-process-environment.cjs");
|
|
40
|
+
const HFS_IGNORED_CODE_POINTS = /[\u200c-\u200f\u202a-\u202e\u206a-\u206f\ufeff]/gu;
|
|
41
|
+
const MIRROR_TEMPORARY_FILE_PREFIX = ".r5d-working-tree-mirror-";
|
|
42
|
+
function isPortableGitMetadataSegment(segment) {
|
|
43
|
+
const hfsFolded = segment.replace(HFS_IGNORED_CODE_POINTS, "").toLowerCase();
|
|
44
|
+
if (hfsFolded === ".git") return true;
|
|
45
|
+
const ntfsFolded = segment.toLowerCase();
|
|
46
|
+
return /^(?:\.git|git~1)[ .]*(?::|$)/u.test(ntfsFolded);
|
|
47
|
+
}
|
|
38
48
|
function isGitMetadataPath(relativePath) {
|
|
39
|
-
return relativePath.split(
|
|
49
|
+
return relativePath.split(/[\\/]/u).some(isPortableGitMetadataSegment);
|
|
50
|
+
}
|
|
51
|
+
function assertWorkingTreeHasNoPortableGitMetadataAliases(root) {
|
|
52
|
+
root = import_node_path.default.resolve(root);
|
|
53
|
+
const rootStatus = import_node_fs.default.lstatSync(root);
|
|
54
|
+
if (!rootStatus.isDirectory() || rootStatus.isSymbolicLink()) {
|
|
55
|
+
throw new Error(`Working-tree root is not a regular directory: ${root}`);
|
|
56
|
+
}
|
|
57
|
+
const inspectDirectory = (directoryPath, relativeDirectory) => {
|
|
58
|
+
for (const name of import_node_fs.default.readdirSync(directoryPath).sort()) {
|
|
59
|
+
const relativePath = relativeDirectory ? import_node_path.default.posix.join(relativeDirectory, name) : name;
|
|
60
|
+
if (name === ".git") continue;
|
|
61
|
+
if (isGitMetadataPath(relativePath)) {
|
|
62
|
+
throw new Error(`Working tree contains a portable Git metadata alias that cannot be moved safely: ${relativePath}`);
|
|
63
|
+
}
|
|
64
|
+
const entryPath = import_node_path.default.join(directoryPath, name);
|
|
65
|
+
const status = import_node_fs.default.lstatSync(entryPath);
|
|
66
|
+
if (status.isDirectory() && !status.isSymbolicLink()) inspectDirectory(entryPath, relativePath);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
inspectDirectory(root, "");
|
|
40
70
|
}
|
|
41
71
|
function normalizeRelativePath(value) {
|
|
42
72
|
const normalized = value.split(import_node_path.default.sep).join(import_node_path.default.posix.sep).replace(/^\.\/+/, "").replace(/^\/+|\/+$/g, "");
|
|
@@ -49,6 +79,41 @@ function assertInside(root, candidate) {
|
|
|
49
79
|
throw new Error(`Working-tree path escapes its root: ${candidate}`);
|
|
50
80
|
}
|
|
51
81
|
}
|
|
82
|
+
function inspectRelativePathWithoutFollowingAncestors(root, relativePath) {
|
|
83
|
+
const normalized = normalizeRelativePath(relativePath);
|
|
84
|
+
if (!normalized) return { kind: "blocked", blockingPath: relativePath };
|
|
85
|
+
let current = import_node_path.default.resolve(root);
|
|
86
|
+
const segments = normalized.split("/");
|
|
87
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
88
|
+
current = import_node_path.default.join(current, segments[index]);
|
|
89
|
+
assertInside(root, current);
|
|
90
|
+
let stat;
|
|
91
|
+
try {
|
|
92
|
+
stat = import_node_fs.default.lstatSync(current);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (error.code === "ENOENT") return { kind: "missing" };
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
if (index < segments.length - 1 && (!stat.isDirectory() || stat.isSymbolicLink())) {
|
|
98
|
+
return { kind: "blocked", blockingPath: current };
|
|
99
|
+
}
|
|
100
|
+
if (index === segments.length - 1) return { kind: "entry", absolutePath: current, stat };
|
|
101
|
+
}
|
|
102
|
+
return { kind: "missing" };
|
|
103
|
+
}
|
|
104
|
+
function inspectDirectoryRoot(root, options) {
|
|
105
|
+
let stat;
|
|
106
|
+
try {
|
|
107
|
+
stat = import_node_fs.default.lstatSync(root);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (options.allowMissing && error.code === "ENOENT") return false;
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
113
|
+
throw new Error(`${options.label} is not a regular directory: ${root}`);
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
52
117
|
function gitEligibleRoots(root) {
|
|
53
118
|
const result = Bun.spawnSync(
|
|
54
119
|
[
|
|
@@ -85,16 +150,13 @@ function gitEligibleRoots(root) {
|
|
|
85
150
|
function addEntry(entries, root, relativePath, recurseDirectories) {
|
|
86
151
|
const normalized = normalizeRelativePath(relativePath);
|
|
87
152
|
if (!normalized || entries.has(normalized)) return;
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
stat = import_node_fs.default.lstatSync(absolutePath);
|
|
93
|
-
} catch (error) {
|
|
94
|
-
if (error.code === "ENOENT") return;
|
|
95
|
-
throw error;
|
|
96
|
-
}
|
|
153
|
+
const inspected = inspectRelativePathWithoutFollowingAncestors(root, normalized);
|
|
154
|
+
if (inspected.kind !== "entry") return;
|
|
155
|
+
const { absolutePath, stat } = inspected;
|
|
97
156
|
if (stat.isSymbolicLink()) {
|
|
157
|
+
for (const existing of [...entries.keys()]) {
|
|
158
|
+
if (existing.startsWith(`${normalized}/`)) entries.delete(existing);
|
|
159
|
+
}
|
|
98
160
|
entries.set(normalized, { kind: "symlink", mode: stat.mode, target: import_node_fs.default.readlinkSync(absolutePath) });
|
|
99
161
|
return;
|
|
100
162
|
}
|
|
@@ -114,9 +176,11 @@ function addParentDirectories(entries, root) {
|
|
|
114
176
|
let parent = import_node_path.default.posix.dirname(relativePath);
|
|
115
177
|
while (parent !== ".") {
|
|
116
178
|
if (!entries.has(parent)) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
179
|
+
const inspected = inspectRelativePathWithoutFollowingAncestors(root, parent);
|
|
180
|
+
if (inspected.kind !== "entry" || !inspected.stat.isDirectory() || inspected.stat.isSymbolicLink()) {
|
|
181
|
+
throw new Error(`Working-tree entry has an unsafe parent directory: ${parent}`);
|
|
182
|
+
}
|
|
183
|
+
entries.set(parent, { kind: "directory", mode: inspected.stat.mode });
|
|
120
184
|
}
|
|
121
185
|
parent = import_node_path.default.posix.dirname(parent);
|
|
122
186
|
}
|
|
@@ -124,7 +188,8 @@ function addParentDirectories(entries, root) {
|
|
|
124
188
|
}
|
|
125
189
|
function inspectWorkingTree(root, mode) {
|
|
126
190
|
const entries = /* @__PURE__ */ new Map();
|
|
127
|
-
|
|
191
|
+
root = import_node_path.default.resolve(root);
|
|
192
|
+
if (!inspectDirectoryRoot(root, { allowMissing: true, label: "Working-tree root" })) return entries;
|
|
128
193
|
if (mode === "all") {
|
|
129
194
|
for (const child of import_node_fs.default.readdirSync(root).sort()) addEntry(entries, root, child, true);
|
|
130
195
|
} else {
|
|
@@ -136,32 +201,58 @@ function inspectWorkingTree(root, mode) {
|
|
|
136
201
|
return entries;
|
|
137
202
|
}
|
|
138
203
|
function removeEntry(targetRoot, relativePath) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
204
|
+
const inspected = inspectRelativePathWithoutFollowingAncestors(targetRoot, relativePath);
|
|
205
|
+
if (inspected.kind === "missing") return;
|
|
206
|
+
if (inspected.kind === "blocked") {
|
|
207
|
+
throw new Error(`Refusing to remove a working-tree path through a symlink or non-directory: ${inspected.blockingPath}`);
|
|
208
|
+
}
|
|
209
|
+
import_node_fs.default.rmSync(inspected.absolutePath, { recursive: true, force: true });
|
|
142
210
|
}
|
|
143
211
|
function ensureDirectory(targetRoot, relativePath, mode) {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
212
|
+
const normalized = normalizeRelativePath(relativePath);
|
|
213
|
+
if (!normalized) throw new Error(`Invalid working-tree directory path: ${relativePath}`);
|
|
214
|
+
let current = import_node_path.default.resolve(targetRoot);
|
|
215
|
+
const segments = normalized.split("/");
|
|
216
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
217
|
+
current = import_node_path.default.join(current, segments[index]);
|
|
218
|
+
assertInside(targetRoot, current);
|
|
219
|
+
let stat = null;
|
|
220
|
+
try {
|
|
221
|
+
stat = import_node_fs.default.lstatSync(current);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
if (error.code !== "ENOENT") throw error;
|
|
224
|
+
}
|
|
225
|
+
if (stat && (!stat.isDirectory() || stat.isSymbolicLink())) {
|
|
226
|
+
import_node_fs.default.rmSync(current, { recursive: true, force: true });
|
|
227
|
+
stat = null;
|
|
228
|
+
}
|
|
229
|
+
if (!stat) import_node_fs.default.mkdirSync(current, { mode: index === segments.length - 1 ? mode & 511 : 493 });
|
|
230
|
+
}
|
|
148
231
|
}
|
|
149
|
-
function filesEqual(leftPath, rightPath,
|
|
232
|
+
function filesEqual(leftPath, rightPath, entry) {
|
|
150
233
|
let rightStat;
|
|
151
234
|
try {
|
|
152
235
|
rightStat = import_node_fs.default.lstatSync(rightPath);
|
|
153
236
|
} catch {
|
|
154
237
|
return false;
|
|
155
238
|
}
|
|
156
|
-
if (!rightStat.isFile() || rightStat.size !== size) return false;
|
|
157
|
-
|
|
158
|
-
|
|
239
|
+
if (!rightStat.isFile() || rightStat.size !== entry.size || (rightStat.mode & 511) !== (entry.mode & 511)) return false;
|
|
240
|
+
let left;
|
|
241
|
+
let right;
|
|
242
|
+
try {
|
|
243
|
+
left = import_node_fs.default.openSync(leftPath, import_node_fs.default.constants.O_RDONLY | import_node_fs.default.constants.O_NOFOLLOW);
|
|
244
|
+
right = import_node_fs.default.openSync(rightPath, import_node_fs.default.constants.O_RDONLY | import_node_fs.default.constants.O_NOFOLLOW);
|
|
245
|
+
} catch {
|
|
246
|
+
if (left !== void 0) import_node_fs.default.closeSync(left);
|
|
247
|
+
if (right !== void 0) import_node_fs.default.closeSync(right);
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
159
250
|
const leftBuffer = Buffer.allocUnsafe(64 * 1024);
|
|
160
251
|
const rightBuffer = Buffer.allocUnsafe(64 * 1024);
|
|
161
252
|
try {
|
|
162
253
|
let offset = 0;
|
|
163
|
-
while (offset < size) {
|
|
164
|
-
const length = Math.min(leftBuffer.length, size - offset);
|
|
254
|
+
while (offset < entry.size) {
|
|
255
|
+
const length = Math.min(leftBuffer.length, entry.size - offset);
|
|
165
256
|
const leftRead = import_node_fs.default.readSync(left, leftBuffer, 0, length, offset);
|
|
166
257
|
const rightRead = import_node_fs.default.readSync(right, rightBuffer, 0, length, offset);
|
|
167
258
|
if (leftRead !== rightRead || !leftBuffer.subarray(0, leftRead).equals(rightBuffer.subarray(0, rightRead))) return false;
|
|
@@ -173,18 +264,73 @@ function filesEqual(leftPath, rightPath, size) {
|
|
|
173
264
|
import_node_fs.default.closeSync(right);
|
|
174
265
|
}
|
|
175
266
|
}
|
|
267
|
+
function copyRegularFile(sourcePath, targetPath, entry) {
|
|
268
|
+
const source = import_node_fs.default.openSync(sourcePath, import_node_fs.default.constants.O_RDONLY | import_node_fs.default.constants.O_NOFOLLOW);
|
|
269
|
+
const temporaryPath = import_node_path.default.join(import_node_path.default.dirname(targetPath), `${MIRROR_TEMPORARY_FILE_PREFIX}${(0, import_node_crypto.randomUUID)()}.tmp`);
|
|
270
|
+
let target;
|
|
271
|
+
try {
|
|
272
|
+
const sourceStat = import_node_fs.default.fstatSync(source);
|
|
273
|
+
if (!sourceStat.isFile() || sourceStat.size !== entry.size || (sourceStat.mode & 511) !== (entry.mode & 511)) {
|
|
274
|
+
throw new Error(`Working-tree source changed while it was being mirrored: ${sourcePath}`);
|
|
275
|
+
}
|
|
276
|
+
target = import_node_fs.default.openSync(
|
|
277
|
+
temporaryPath,
|
|
278
|
+
import_node_fs.default.constants.O_WRONLY | import_node_fs.default.constants.O_CREAT | import_node_fs.default.constants.O_EXCL | import_node_fs.default.constants.O_NOFOLLOW,
|
|
279
|
+
entry.mode & 511
|
|
280
|
+
);
|
|
281
|
+
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
282
|
+
let offset = 0;
|
|
283
|
+
while (offset < sourceStat.size) {
|
|
284
|
+
const bytesRead = import_node_fs.default.readSync(source, buffer, 0, Math.min(buffer.length, sourceStat.size - offset), offset);
|
|
285
|
+
if (bytesRead <= 0) throw new Error(`Working-tree source ended while it was being mirrored: ${sourcePath}`);
|
|
286
|
+
let written = 0;
|
|
287
|
+
while (written < bytesRead) {
|
|
288
|
+
written += import_node_fs.default.writeSync(target, buffer, written, bytesRead - written, offset + written);
|
|
289
|
+
}
|
|
290
|
+
offset += bytesRead;
|
|
291
|
+
}
|
|
292
|
+
import_node_fs.default.fchmodSync(target, entry.mode & 511);
|
|
293
|
+
import_node_fs.default.fsyncSync(target);
|
|
294
|
+
const finalSourceStat = import_node_fs.default.fstatSync(source);
|
|
295
|
+
if (!finalSourceStat.isFile() || finalSourceStat.size !== sourceStat.size || (finalSourceStat.mode & 511) !== (sourceStat.mode & 511) || finalSourceStat.mtimeMs !== sourceStat.mtimeMs || finalSourceStat.ctimeMs !== sourceStat.ctimeMs) {
|
|
296
|
+
throw new Error(`Working-tree source changed while it was being mirrored: ${sourcePath}`);
|
|
297
|
+
}
|
|
298
|
+
import_node_fs.default.closeSync(target);
|
|
299
|
+
target = void 0;
|
|
300
|
+
import_node_fs.default.renameSync(temporaryPath, targetPath);
|
|
301
|
+
const parent = import_node_fs.default.openSync(import_node_path.default.dirname(targetPath), import_node_fs.default.constants.O_RDONLY);
|
|
302
|
+
try {
|
|
303
|
+
import_node_fs.default.fsyncSync(parent);
|
|
304
|
+
} finally {
|
|
305
|
+
import_node_fs.default.closeSync(parent);
|
|
306
|
+
}
|
|
307
|
+
} finally {
|
|
308
|
+
if (target !== void 0) import_node_fs.default.closeSync(target);
|
|
309
|
+
import_node_fs.default.closeSync(source);
|
|
310
|
+
import_node_fs.default.rmSync(temporaryPath, { force: true });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
176
313
|
function copyEntry(sourceRoot, targetRoot, relativePath, entry) {
|
|
177
|
-
const sourcePath = import_node_path.default.join(sourceRoot, ...relativePath.split("/"));
|
|
178
314
|
const targetPath = import_node_path.default.join(targetRoot, ...relativePath.split("/"));
|
|
179
|
-
assertInside(sourceRoot, sourcePath);
|
|
180
315
|
assertInside(targetRoot, targetPath);
|
|
181
316
|
const parent = import_node_path.default.posix.dirname(relativePath);
|
|
182
317
|
if (parent !== ".") ensureDirectory(targetRoot, parent, 493);
|
|
318
|
+
const source = inspectRelativePathWithoutFollowingAncestors(sourceRoot, relativePath);
|
|
319
|
+
if (source.kind !== "entry") {
|
|
320
|
+
throw new Error(`Working-tree source became unsafe while it was being mirrored: ${relativePath}`);
|
|
321
|
+
}
|
|
322
|
+
const sourcePath = source.absolutePath;
|
|
183
323
|
if (entry.kind === "directory") {
|
|
324
|
+
if (!source.stat.isDirectory() || source.stat.isSymbolicLink()) {
|
|
325
|
+
throw new Error(`Working-tree source changed while it was being mirrored: ${sourcePath}`);
|
|
326
|
+
}
|
|
184
327
|
ensureDirectory(targetRoot, relativePath, entry.mode);
|
|
185
328
|
return;
|
|
186
329
|
}
|
|
187
330
|
if (entry.kind === "symlink") {
|
|
331
|
+
if (!source.stat.isSymbolicLink() || import_node_fs.default.readlinkSync(sourcePath) !== entry.target) {
|
|
332
|
+
throw new Error(`Working-tree source changed while it was being mirrored: ${sourcePath}`);
|
|
333
|
+
}
|
|
188
334
|
let unchanged = false;
|
|
189
335
|
try {
|
|
190
336
|
unchanged = import_node_fs.default.lstatSync(targetPath).isSymbolicLink() && import_node_fs.default.readlinkSync(targetPath) === entry.target;
|
|
@@ -197,16 +343,26 @@ function copyEntry(sourceRoot, targetRoot, relativePath, entry) {
|
|
|
197
343
|
}
|
|
198
344
|
return;
|
|
199
345
|
}
|
|
200
|
-
if (!
|
|
201
|
-
|
|
202
|
-
|
|
346
|
+
if (!source.stat.isFile() || source.stat.isSymbolicLink() || source.stat.size !== entry.size) {
|
|
347
|
+
throw new Error(`Working-tree source changed while it was being mirrored: ${sourcePath}`);
|
|
348
|
+
}
|
|
349
|
+
if (!filesEqual(sourcePath, targetPath, entry)) {
|
|
350
|
+
const target = inspectRelativePathWithoutFollowingAncestors(targetRoot, relativePath);
|
|
351
|
+
if (target.kind === "blocked") {
|
|
352
|
+
throw new Error(`Refusing to copy through a symlink or non-directory: ${target.blockingPath}`);
|
|
353
|
+
}
|
|
354
|
+
const targetStat = target.kind === "entry" ? target.stat : null;
|
|
355
|
+
if (targetStat && !targetStat.isFile()) removeEntry(targetRoot, relativePath);
|
|
356
|
+
copyRegularFile(sourcePath, targetPath, entry);
|
|
203
357
|
}
|
|
204
|
-
import_node_fs.default.chmodSync(targetPath, entry.mode & 511);
|
|
205
358
|
}
|
|
206
359
|
function mirrorWorkingTree(input) {
|
|
207
360
|
const sourceRoot = import_node_path.default.resolve(input.sourceRoot);
|
|
208
361
|
const targetRoot = import_node_path.default.resolve(input.targetRoot);
|
|
209
|
-
|
|
362
|
+
if (!inspectDirectoryRoot(targetRoot, { allowMissing: true, label: "Working-tree target root" })) {
|
|
363
|
+
import_node_fs.default.mkdirSync(targetRoot, { recursive: true });
|
|
364
|
+
}
|
|
365
|
+
inspectDirectoryRoot(targetRoot, { allowMissing: false, label: "Working-tree target root" });
|
|
210
366
|
const desired = inspectWorkingTree(sourceRoot, input.sourceMode);
|
|
211
367
|
const existing = inspectWorkingTree(targetRoot, input.deletionMode === "git" ? "git" : "all");
|
|
212
368
|
for (const relativePath of [...existing.keys()].sort((left, right) => right.split("/").length - left.split("/").length)) {
|
|
@@ -221,6 +377,7 @@ function mirrorWorkingTree(input) {
|
|
|
221
377
|
}
|
|
222
378
|
// Annotate the CommonJS export names for ESM import in node:
|
|
223
379
|
0 && (module.exports = {
|
|
380
|
+
assertWorkingTreeHasNoPortableGitMetadataAliases,
|
|
224
381
|
inspectWorkingTree,
|
|
225
382
|
mirrorWorkingTree
|
|
226
383
|
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var workspace_automatic_sync_policy_exports = {};
|
|
20
|
+
__export(workspace_automatic_sync_policy_exports, {
|
|
21
|
+
PENDING_CREATED_BRANCH_AUTOMATIC_SYNC_GRACE_MS: () => PENDING_CREATED_BRANCH_AUTOMATIC_SYNC_GRACE_MS,
|
|
22
|
+
hasActiveVisibleProjectsWorkspaceTarget: () => hasActiveVisibleProjectsWorkspaceTarget,
|
|
23
|
+
pendingCreatedBranchAutomaticSyncDeferral: () => pendingCreatedBranchAutomaticSyncDeferral,
|
|
24
|
+
pendingCreatedBranchKey: () => pendingCreatedBranchKey,
|
|
25
|
+
projectBranchHasActiveWorkspaceTarget: () => projectBranchHasActiveWorkspaceTarget,
|
|
26
|
+
shouldDeferAutomaticWorkspaceSyncForPendingBranch: () => shouldDeferAutomaticWorkspaceSyncForPendingBranch
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(workspace_automatic_sync_policy_exports);
|
|
29
|
+
const PENDING_CREATED_BRANCH_AUTOMATIC_SYNC_GRACE_MS = 12e4;
|
|
30
|
+
function pendingCreatedBranchKey(projectId, branchName) {
|
|
31
|
+
return `${projectId}\0${branchName}`;
|
|
32
|
+
}
|
|
33
|
+
function hasActiveVisibleProjectsWorkspaceTarget(activeTargets) {
|
|
34
|
+
for (const target of activeTargets) {
|
|
35
|
+
if (target.type === "workspace" && target.rootProfile === "visible_projects") return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function projectBranchHasActiveWorkspaceTarget(projectId, branchName, activeTargets) {
|
|
40
|
+
for (const target of activeTargets) {
|
|
41
|
+
if (target.type === "project" && target.projectId === projectId && target.branchName === branchName) return true;
|
|
42
|
+
if (target.type === "workspace" && target.rootProfile === "visible_projects") return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
function shouldDeferAutomaticWorkspaceSyncForPendingBranch(pendingCreatedBranches, activeTargets) {
|
|
47
|
+
if (pendingCreatedBranches.length === 0) return false;
|
|
48
|
+
const targets = [...activeTargets];
|
|
49
|
+
return pendingCreatedBranches.some(({ projectId, branchName }) => projectBranchHasActiveWorkspaceTarget(projectId, branchName, targets));
|
|
50
|
+
}
|
|
51
|
+
function pendingCreatedBranchAutomaticSyncDeferral(pendingCreatedBranches, activeTargets, publicationNotBeforeByBranch, nowMs = Date.now()) {
|
|
52
|
+
if (shouldDeferAutomaticWorkspaceSyncForPendingBranch(pendingCreatedBranches, activeTargets)) {
|
|
53
|
+
return { kind: "active_target" };
|
|
54
|
+
}
|
|
55
|
+
const notBeforeMs = pendingCreatedBranches.reduce(
|
|
56
|
+
(latest, { projectId, branchName }) => Math.max(latest, publicationNotBeforeByBranch.get(pendingCreatedBranchKey(projectId, branchName)) ?? 0),
|
|
57
|
+
0
|
|
58
|
+
);
|
|
59
|
+
return notBeforeMs > nowMs ? { kind: "creation_grace", retryAfterMs: notBeforeMs - nowMs } : null;
|
|
60
|
+
}
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
PENDING_CREATED_BRANCH_AUTOMATIC_SYNC_GRACE_MS,
|
|
64
|
+
hasActiveVisibleProjectsWorkspaceTarget,
|
|
65
|
+
pendingCreatedBranchAutomaticSyncDeferral,
|
|
66
|
+
pendingCreatedBranchKey,
|
|
67
|
+
projectBranchHasActiveWorkspaceTarget,
|
|
68
|
+
shouldDeferAutomaticWorkspaceSyncForPendingBranch
|
|
69
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var workspace_branch_incarnation_policy_exports = {};
|
|
20
|
+
__export(workspace_branch_incarnation_policy_exports, {
|
|
21
|
+
assertProjectBranchDeletionIncarnation: () => assertProjectBranchDeletionIncarnation
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(workspace_branch_incarnation_policy_exports);
|
|
24
|
+
function assertProjectBranchDeletionIncarnation(input) {
|
|
25
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/.test(input.requiredBranchId)) {
|
|
26
|
+
throw new Error("Project branch deletion requires a valid durable branch incarnation");
|
|
27
|
+
}
|
|
28
|
+
for (const branch of [input.configuredBranch, input.pendingLocalBranch]) {
|
|
29
|
+
if (branch && branch.branchId !== input.requiredBranchId) {
|
|
30
|
+
throw new Error("Project branch deletion belongs to another durable branch incarnation");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
35
|
+
0 && (module.exports = {
|
|
36
|
+
assertProjectBranchDeletionIncarnation
|
|
37
|
+
});
|
|
@@ -19,10 +19,27 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var workspace_command_sync_policy_exports = {};
|
|
20
20
|
__export(workspace_command_sync_policy_exports, {
|
|
21
21
|
acquireWorkspaceCommandMutation: () => acquireWorkspaceCommandMutation,
|
|
22
|
+
reserveWorkspaceCommandAfterCurrentSync: () => reserveWorkspaceCommandAfterCurrentSync,
|
|
22
23
|
runWorkspaceCommand: () => runWorkspaceCommand,
|
|
23
24
|
shouldSerializeWorkspaceCommand: () => shouldSerializeWorkspaceCommand
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(workspace_command_sync_policy_exports);
|
|
27
|
+
function usesVisibleWorkspace(target) {
|
|
28
|
+
return target.type === "project" || target.rootProfile === "visible_projects";
|
|
29
|
+
}
|
|
30
|
+
async function reserveWorkspaceCommandAfterCurrentSync(target, coordinator, reserve) {
|
|
31
|
+
if (!usesVisibleWorkspace(target)) {
|
|
32
|
+
reserve();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
while (true) {
|
|
36
|
+
const currentSync = coordinator.afterCurrent();
|
|
37
|
+
await currentSync;
|
|
38
|
+
if (currentSync !== coordinator.afterCurrent()) continue;
|
|
39
|
+
reserve();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
26
43
|
function shouldSerializeWorkspaceCommand(target) {
|
|
27
44
|
return target.type === "workspace" && target.rootProfile === "canonical_sync";
|
|
28
45
|
}
|
|
@@ -35,6 +52,7 @@ function acquireWorkspaceCommandMutation(target, coordinator) {
|
|
|
35
52
|
// Annotate the CommonJS export names for ESM import in node:
|
|
36
53
|
0 && (module.exports = {
|
|
37
54
|
acquireWorkspaceCommandMutation,
|
|
55
|
+
reserveWorkspaceCommandAfterCurrentSync,
|
|
38
56
|
runWorkspaceCommand,
|
|
39
57
|
shouldSerializeWorkspaceCommand
|
|
40
58
|
});
|