@bluewombat/isolation-git 0.3.0 → 0.4.0
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 +7 -0
- package/dist/child/process-tree.d.ts +19 -0
- package/dist/child/process-tree.d.ts.map +1 -0
- package/dist/child/process-tree.js +137 -0
- package/dist/child/process-tree.js.map +1 -0
- package/dist/child/run-child.d.ts.map +1 -1
- package/dist/child/run-child.js +6 -11
- package/dist/child/run-child.js.map +1 -1
- package/dist/copy-working-files.d.ts +11 -0
- package/dist/copy-working-files.d.ts.map +1 -1
- package/dist/copy-working-files.js +54 -6
- package/dist/copy-working-files.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -41,6 +41,13 @@ run` before it isolates anything. The copy reads no `.gitignore`: what git
|
|
|
41
41
|
ignores is very often exactly what a Builder needs (its dependencies, the
|
|
42
42
|
Project's own agent configuration).
|
|
43
43
|
|
|
44
|
+
**A path git tracks is never left out**, whatever the list says. An exclusion is
|
|
45
|
+
about what exists only on the disk: a tracked path is in the history already, so
|
|
46
|
+
hiding it hides nothing, and its absence from the Child would read as a deletion
|
|
47
|
+
— to the checks on the Parent and to the fold. A tracked `.env.example` stays;
|
|
48
|
+
an untracked `.env` goes. Under a directory the list names, the tracked files
|
|
49
|
+
stay and the rest goes.
|
|
50
|
+
|
|
44
51
|
Each root entry is copied by `cp` — `-c` on macOS, `--reflink=auto` elsewhere
|
|
45
52
|
— so on a file system that clones (APFS, btrfs, XFS) the Child shares its
|
|
46
53
|
bytes with the Parent instead of doubling them; where `cp` cannot, the entry
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
/** Spread into the options of `spawn`: the child leads its own group. */
|
|
3
|
+
export declare function ownGroup(): {
|
|
4
|
+
detached: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Remember a running child so it does not outlive this process: a group of its
|
|
8
|
+
* own no longer shares the terminal's Ctrl-C, nor dies by accident with us.
|
|
9
|
+
* Forgotten on its own once it closes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function track(child: ChildProcess): void;
|
|
12
|
+
/**
|
|
13
|
+
* SIGKILL to the child's whole group and to every descendant, wherever its
|
|
14
|
+
* group; to the child alone where there are no groups. Once per child.
|
|
15
|
+
*/
|
|
16
|
+
export declare function killTree(child: ChildProcess): void;
|
|
17
|
+
/** `killTree`, then the pipes are cut after the grace period. Once per child. */
|
|
18
|
+
export declare function killAndCut(child: ChildProcess): void;
|
|
19
|
+
//# sourceMappingURL=process-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.d.ts","sourceRoot":"","sources":["../../src/child/process-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AAoCrE,yEAAyE;AACzE,wBAAgB,QAAQ,IAAI;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAe/C;AAiCD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CA8BlD;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CASpD"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
// Canonical source of every `process-tree.ts` in this repository. Edit it here,
|
|
3
|
+
// then run `node scripts/check-process-tree.mjs --write`; `npm run lint` fails
|
|
4
|
+
// when a copy differs. A package stands alone, so each carries its own copy.
|
|
5
|
+
//
|
|
6
|
+
// The rule it keeps: whoever starts a child and owns its deadline — a
|
|
7
|
+
// supervisor — starts it as the leader of its own process group, and ends it by
|
|
8
|
+
// signalling that group. A child is rarely alone: a producer is `node producer`
|
|
9
|
+
// → `node agent` → the vendor CLI → its shells. Killing only the first leaves
|
|
10
|
+
// the rest running, holding the pipes open, until they end on their own; the
|
|
11
|
+
// deadline then means nothing and a finished job is reported as lost.
|
|
12
|
+
//
|
|
13
|
+
// A layer in the middle of such a chain (a producer, an agent runner) is not a
|
|
14
|
+
// supervisor: it starts its child in its own group, so the supervisor's signal
|
|
15
|
+
// reaches it too.
|
|
16
|
+
//
|
|
17
|
+
// The group is not the whole tree. A vendor CLI may start each shell command
|
|
18
|
+
// in a group of its own (cursor-agent does), out of the group's reach. So the
|
|
19
|
+
// descendants are read from `ps` first — once their parent dies they are
|
|
20
|
+
// re-parented and the link is lost — and each is killed too.
|
|
21
|
+
/** Windows has no process groups: there a child is killed alone. */
|
|
22
|
+
const OWN_GROUP = process.platform !== "win32";
|
|
23
|
+
/**
|
|
24
|
+
* After a kill the pipes are cut this long afterwards, so a grandchild that
|
|
25
|
+
* left the group (setsid) and still holds one cannot hold the outcome back.
|
|
26
|
+
*/
|
|
27
|
+
const PIPE_GRACE_MS = 2_000;
|
|
28
|
+
const live = new Set();
|
|
29
|
+
/** Already killed: a supervisor polling its interrupt asks again every tick. */
|
|
30
|
+
const ended = new WeakSet();
|
|
31
|
+
let exitHookInstalled = false;
|
|
32
|
+
/** Spread into the options of `spawn`: the child leads its own group. */
|
|
33
|
+
export function ownGroup() {
|
|
34
|
+
return { detached: OWN_GROUP };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Remember a running child so it does not outlive this process: a group of its
|
|
38
|
+
* own no longer shares the terminal's Ctrl-C, nor dies by accident with us.
|
|
39
|
+
* Forgotten on its own once it closes.
|
|
40
|
+
*/
|
|
41
|
+
export function track(child) {
|
|
42
|
+
if (OWN_GROUP && !exitHookInstalled) {
|
|
43
|
+
exitHookInstalled = true;
|
|
44
|
+
process.on("exit", () => {
|
|
45
|
+
for (const running of live) {
|
|
46
|
+
killTree(running);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
live.add(child);
|
|
51
|
+
const forget = () => {
|
|
52
|
+
live.delete(child);
|
|
53
|
+
};
|
|
54
|
+
child.once("close", forget);
|
|
55
|
+
child.once("error", forget);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Every process below `pid`, as `ps` lists them now. Empty where `ps` cannot be
|
|
59
|
+
* read: the group kill still stands.
|
|
60
|
+
*/
|
|
61
|
+
function descendants(pid) {
|
|
62
|
+
let table;
|
|
63
|
+
try {
|
|
64
|
+
table = execFileSync("ps", ["-A", "-o", "pid=,ppid="], {
|
|
65
|
+
encoding: "utf8",
|
|
66
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const childrenOf = new Map();
|
|
73
|
+
for (const line of table.split("\n")) {
|
|
74
|
+
const match = /^\s*(\d+)\s+(\d+)\s*$/.exec(line);
|
|
75
|
+
if (match !== null) {
|
|
76
|
+
const parent = Number(match[2]);
|
|
77
|
+
childrenOf.set(parent, [...(childrenOf.get(parent) ?? []), Number(match[1])]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const found = [];
|
|
81
|
+
let frontier = [pid];
|
|
82
|
+
while (frontier.length > 0) {
|
|
83
|
+
frontier = frontier.flatMap((each) => childrenOf.get(each) ?? []);
|
|
84
|
+
found.push(...frontier);
|
|
85
|
+
}
|
|
86
|
+
return found;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* SIGKILL to the child's whole group and to every descendant, wherever its
|
|
90
|
+
* group; to the child alone where there are no groups. Once per child.
|
|
91
|
+
*/
|
|
92
|
+
export function killTree(child) {
|
|
93
|
+
if (ended.has(child)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
ended.add(child);
|
|
97
|
+
if (OWN_GROUP && child.pid !== undefined) {
|
|
98
|
+
const below = descendants(child.pid);
|
|
99
|
+
let grouped = true;
|
|
100
|
+
try {
|
|
101
|
+
process.kill(-child.pid, "SIGKILL");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// no such group: the child itself, below
|
|
105
|
+
grouped = false;
|
|
106
|
+
}
|
|
107
|
+
for (const pid of below) {
|
|
108
|
+
try {
|
|
109
|
+
process.kill(pid, "SIGKILL");
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// already gone, with the group
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (grouped) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
child.kill("SIGKILL");
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// already gone
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** `killTree`, then the pipes are cut after the grace period. Once per child. */
|
|
127
|
+
export function killAndCut(child) {
|
|
128
|
+
if (ended.has(child)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
killTree(child);
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
child.stdout?.destroy();
|
|
134
|
+
child.stderr?.destroy();
|
|
135
|
+
}, PIPE_GRACE_MS).unref();
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=process-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.js","sourceRoot":"","sources":["../../src/child/process-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-child.d.ts","sourceRoot":"","sources":["../../src/child/run-child.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-child.d.ts","sourceRoot":"","sources":["../../src/child/run-child.ts"],"names":[],"mappings":"AAKA,KAAK,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,YAAY,EAAE,SAAS,CAAC;IACxB,0DAA0D;IAC1D,eAAe,EAAE,MAAM,OAAO,CAAC;IAC/B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;IACpC,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;CAC9C,CAAC;AAQF;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC,UAAU,CAKjE;AAED,MAAM,MAAM,YAAY,GACpB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AASN;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAkGrE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrE"}
|
package/dist/child/run-child.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { killAndCut, ownGroup, track } from "./process-tree.js";
|
|
2
3
|
const OUTPUT_TRUNCATE = 8_192;
|
|
3
4
|
/**
|
|
4
5
|
* A child's messages become the detail of a failed Isolation or fold, and so
|
|
@@ -21,14 +22,6 @@ function truncate(text) {
|
|
|
21
22
|
}
|
|
22
23
|
return `[…${text.length - OUTPUT_TRUNCATE} characters cut]${text.slice(-OUTPUT_TRUNCATE)}`;
|
|
23
24
|
}
|
|
24
|
-
function killProcessTree(child) {
|
|
25
|
-
try {
|
|
26
|
-
child.kill("SIGKILL");
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
// already gone
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
25
|
/**
|
|
33
26
|
* Run one child with a wall-clock timeout. Does not inherit the caller's stdin.
|
|
34
27
|
*/
|
|
@@ -65,6 +58,7 @@ export function runChild(request) {
|
|
|
65
58
|
cwd: request.cwd,
|
|
66
59
|
env: childEnv(request),
|
|
67
60
|
stdio: ["ignore", "pipe", "pipe"],
|
|
61
|
+
...ownGroup(),
|
|
68
62
|
});
|
|
69
63
|
}
|
|
70
64
|
catch (error) {
|
|
@@ -72,6 +66,7 @@ export function runChild(request) {
|
|
|
72
66
|
finish({ kind: "spawn_error", detail });
|
|
73
67
|
return;
|
|
74
68
|
}
|
|
69
|
+
track(child);
|
|
75
70
|
if (!child.stdout || !child.stderr) {
|
|
76
71
|
finish({ kind: "spawn_error", detail: "Child stdout/stderr pipes unavailable." });
|
|
77
72
|
return;
|
|
@@ -89,17 +84,17 @@ export function runChild(request) {
|
|
|
89
84
|
});
|
|
90
85
|
timer = setTimeout(() => {
|
|
91
86
|
timedOut = true;
|
|
92
|
-
|
|
87
|
+
killAndCut(child);
|
|
93
88
|
}, Math.max(1, request.timeoutMs));
|
|
94
89
|
interruptPoll = setInterval(() => {
|
|
95
90
|
if (request.shouldInterrupt()) {
|
|
96
91
|
interrupted = true;
|
|
97
|
-
|
|
92
|
+
killAndCut(child);
|
|
98
93
|
}
|
|
99
94
|
}, 20);
|
|
100
95
|
if (request.shouldInterrupt()) {
|
|
101
96
|
interrupted = true;
|
|
102
|
-
|
|
97
|
+
killAndCut(child);
|
|
103
98
|
}
|
|
104
99
|
child.on("close", (exitCode, signal) => {
|
|
105
100
|
const out = truncate(stdout);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-child.js","sourceRoot":"","sources":["../../src/child/run-child.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"run-child.js","sourceRoot":"","sources":["../../src/child/run-child.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { type IsolationStop, IsolationStoppedError } from "@bluewombat/isolator";
|
|
2
|
+
/**
|
|
3
|
+
* What git tracks in `directory`, as `/`-separated paths from its root; empty
|
|
4
|
+
* where it is not a repository. An exclusion is about what exists only on the
|
|
5
|
+
* disk: a tracked path is in the history already, and leaving it out of a Child
|
|
6
|
+
* would make it a deletion there.
|
|
7
|
+
*/
|
|
8
|
+
export declare function trackedPaths(directory: string): Promise<ReadonlySet<string>>;
|
|
2
9
|
/**
|
|
3
10
|
* What never leaves the Parent for a Child, unless a Project says otherwise:
|
|
4
11
|
* a secret in the clear has no business in a workspace an agent reads and a
|
|
@@ -15,6 +22,10 @@ export declare const DEFAULT_EXCLUDES: readonly string[];
|
|
|
15
22
|
* cannot. Excluded paths are then removed from the Child; a clone shares
|
|
16
23
|
* blocks that were already on the disk, so nothing was written in the clear
|
|
17
24
|
* that was not there before.
|
|
25
|
+
*
|
|
26
|
+
* A path git tracks is never left out, whatever `exclude` says (see
|
|
27
|
+
* `trackedPaths`): it is in the history, so hiding it hides nothing, and its
|
|
28
|
+
* absence would read as a deletion in every check and in the fold.
|
|
18
29
|
*/
|
|
19
30
|
export declare function copyWorkingFiles(input: {
|
|
20
31
|
from: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-working-files.d.ts","sourceRoot":"","sources":["../src/copy-working-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"copy-working-files.d.ts","sourceRoot":"","sources":["../src/copy-working-files.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,aAAa,EAAE,qBAAqB,EAAkB,MAAM,sBAAsB,CAAC;AAUjG;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAWlF;AAgBD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAuB,CAAC;AAEtE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,aAAa,GAAG,SAAS,CAAC;CAC7C,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,aAAa,GAAG,SAAS,GAC1C,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAQ7E"}
|
|
@@ -1,10 +1,47 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
1
2
|
import { copyFile, lstat, mkdir, readdir, readlink, rm, symlink } from "node:fs/promises";
|
|
2
3
|
import { platform } from "node:os";
|
|
3
4
|
import { basename, join, relative, sep } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
4
6
|
import { IsolationStoppedError, throwIfStopped } from "@bluewombat/isolator";
|
|
5
7
|
import { runChild } from "./child/run-child.js";
|
|
6
8
|
/** How long one `cp` of one root entry may take before the walk takes over. */
|
|
7
9
|
const CLONE_TIMEOUT_MS = 120_000;
|
|
10
|
+
const LS_FILES_TIMEOUT_MS = 60_000;
|
|
11
|
+
const LS_FILES_MAX_BUFFER = 256 * 1024 * 1024;
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
/**
|
|
14
|
+
* What git tracks in `directory`, as `/`-separated paths from its root; empty
|
|
15
|
+
* where it is not a repository. An exclusion is about what exists only on the
|
|
16
|
+
* disk: a tracked path is in the history already, and leaving it out of a Child
|
|
17
|
+
* would make it a deletion there.
|
|
18
|
+
*/
|
|
19
|
+
export async function trackedPaths(directory) {
|
|
20
|
+
try {
|
|
21
|
+
const { stdout } = await execFileAsync("git", ["-C", directory, "ls-files", "-z"], {
|
|
22
|
+
timeout: LS_FILES_TIMEOUT_MS,
|
|
23
|
+
maxBuffer: LS_FILES_MAX_BUFFER,
|
|
24
|
+
encoding: "utf8",
|
|
25
|
+
});
|
|
26
|
+
return new Set(stdout.split("\0").filter((path) => path.length > 0));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return new Set();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Whether `path` or anything below it is tracked. */
|
|
33
|
+
function holdsTracked(path, tracked) {
|
|
34
|
+
if (tracked.has(path)) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
const prefix = `${path}/`;
|
|
38
|
+
for (const candidate of tracked) {
|
|
39
|
+
if (candidate.startsWith(prefix)) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
8
45
|
/**
|
|
9
46
|
* What never leaves the Parent for a Child, unless a Project says otherwise:
|
|
10
47
|
* a secret in the clear has no business in a workspace an agent reads and a
|
|
@@ -21,9 +58,14 @@ export const DEFAULT_EXCLUDES = [".env", ".env.*"];
|
|
|
21
58
|
* cannot. Excluded paths are then removed from the Child; a clone shares
|
|
22
59
|
* blocks that were already on the disk, so nothing was written in the clear
|
|
23
60
|
* that was not there before.
|
|
61
|
+
*
|
|
62
|
+
* A path git tracks is never left out, whatever `exclude` says (see
|
|
63
|
+
* `trackedPaths`): it is in the history, so hiding it hides nothing, and its
|
|
64
|
+
* absence would read as a deletion in every check and in the fold.
|
|
24
65
|
*/
|
|
25
66
|
export async function copyWorkingFiles(input) {
|
|
26
67
|
const exclude = input.exclude ?? DEFAULT_EXCLUDES;
|
|
68
|
+
const tracked = await trackedPaths(input.from);
|
|
27
69
|
await throwIfStopped(input.shouldStop);
|
|
28
70
|
const entries = await readdir(input.from, { withFileTypes: true });
|
|
29
71
|
for (const entry of entries) {
|
|
@@ -31,7 +73,7 @@ export async function copyWorkingFiles(input) {
|
|
|
31
73
|
if (input.skipGitAtRoot && entry.name === ".git") {
|
|
32
74
|
continue;
|
|
33
75
|
}
|
|
34
|
-
if (isExcluded(entry.name, exclude)) {
|
|
76
|
+
if (isExcluded(entry.name, exclude) && !holdsTracked(entry.name, tracked)) {
|
|
35
77
|
continue;
|
|
36
78
|
}
|
|
37
79
|
const src = join(input.from, entry.name);
|
|
@@ -42,7 +84,7 @@ export async function copyWorkingFiles(input) {
|
|
|
42
84
|
await copyEntry(src, dest, entry, input.shouldStop);
|
|
43
85
|
}
|
|
44
86
|
}
|
|
45
|
-
await pruneExcluded(input.to, input.to, exclude, input.shouldStop);
|
|
87
|
+
await pruneExcluded(input.to, input.to, exclude, tracked, input.shouldStop);
|
|
46
88
|
}
|
|
47
89
|
export async function wipeWorkingFiles(directory, shouldStop) {
|
|
48
90
|
await throwIfStopped(shouldStop);
|
|
@@ -120,8 +162,11 @@ async function copyEntry(src, dest, entry, shouldStop) {
|
|
|
120
162
|
}
|
|
121
163
|
throw new Error(`Cannot isolate "${src}": unsupported file type.`);
|
|
122
164
|
}
|
|
123
|
-
/**
|
|
124
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Remove from `directory` every path below `root` that `patterns` name, unless
|
|
167
|
+
* git tracks it or something under it. Never follows a link.
|
|
168
|
+
*/
|
|
169
|
+
async function pruneExcluded(root, directory, patterns, tracked, shouldStop, underExcluded = false) {
|
|
125
170
|
if (patterns.length === 0) {
|
|
126
171
|
return;
|
|
127
172
|
}
|
|
@@ -132,12 +177,15 @@ async function pruneExcluded(root, directory, patterns, shouldStop) {
|
|
|
132
177
|
if (directory === root && entry.name === ".git") {
|
|
133
178
|
continue;
|
|
134
179
|
}
|
|
135
|
-
|
|
180
|
+
const shown = relative(root, path).split(sep).join("/");
|
|
181
|
+
// A directory kept for the tracked files in it still loses what git does not track.
|
|
182
|
+
const left = underExcluded || isExcluded(shown, patterns);
|
|
183
|
+
if (left && !holdsTracked(shown, tracked)) {
|
|
136
184
|
await rm(path, { recursive: true, force: true });
|
|
137
185
|
continue;
|
|
138
186
|
}
|
|
139
187
|
if (entry.isDirectory() && !(await lstat(path)).isSymbolicLink()) {
|
|
140
|
-
await pruneExcluded(root, path, patterns, shouldStop);
|
|
188
|
+
await pruneExcluded(root, path, patterns, tracked, shouldStop, left);
|
|
141
189
|
}
|
|
142
190
|
}
|
|
143
191
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-working-files.js","sourceRoot":"","sources":["../src/copy-working-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAsB,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,+EAA+E;AAC/E,MAAM,gBAAgB,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"copy-working-files.js","sourceRoot":"","sources":["../src/copy-working-files.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bluewombat/isolation-git",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Isolation strategy: git worktree attach, three-way merge fold.",
|
|
6
6
|
"keywords": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"build": "tsc -p tsconfig.build.json"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@bluewombat/integrator": "^0.
|
|
46
|
-
"@bluewombat/isolator": "^0.
|
|
45
|
+
"@bluewombat/integrator": "^0.4.0",
|
|
46
|
+
"@bluewombat/isolator": "^0.4.0"
|
|
47
47
|
}
|
|
48
48
|
}
|