monochromatic-git-policy-cli 0.5.30

Repository-owned Git policy wrapper: forwards Git commands and checks commits against configured policies.
Documentation
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
//! What:
//!  The package-manager repair of a new worktree through the built executable: after `git worktree add` the wrapper starts
//!  pnpm and Cargo in the new worktree (fixture tools, then the real ones), never for `--no-checkout` or the opt-out, and a
//!  tool that fails or is missing leaves the add successful with one line naming the command to run.
//! Why:
//!  The owner's rule is that a new worktree works under every configuration of every package manager the repository uses.
//!  pnpm's links and Cargo's build state are wrong at a new location, so the controls check the effect a person sees: a
//!  `node_modules` entry that resolves, a build that names the worktree's own paths, and the source left as it was.
//!  Controls that need a real tool say so and stop with a loud line when it is missing, as the btrfs controls do.
//!
//! In TS you'd write (pseudocode):
//! ```ts
//! // run(wrappedGit, ['worktree', 'add', ...]); expect(existsSync('../topic/node_modules/leaf/package.json')).toBe(true);
//! ```

/// Import the shared fixtures and bounded process helpers.
use super::support::{Fixture, Observed, executable, fixture, git, remove, repository, run_wrapped, stderr_of, wrapped};
use super::worktree_snapshot::{commit_all, on_btrfs_or_acknowledged, subvolume_repository};
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

/// The environment variable that acknowledges a real tool is absent on this machine, so its controls may be skipped.
const ABSENT_ACKNOWLEDGED: &str = "CLI_GIT_REAL_TOOLS_ABSENT_ACKNOWLEDGED";

/// Whether a real tool is available; where it is not, the run must have said so, and one loud line names the control.
fn available_or_acknowledged(found: Option<&Path>, tool: &str, control: &str) -> bool {
    if found.is_some() {
        return true;
    }
    let acknowledged: bool = std::env::var_os(ABSENT_ACKNOWLEDGED).is_some_and(|value| { return !value.is_empty(); });
    assert!(acknowledged, "the control {control} needs a real {tool}, which is not on PATH; install it, or set {ABSENT_ACKNOWLEDGED}=1");
    eprintln!("REAL {} CONTROL NOT RUN: {control} (no {tool} on PATH)", tool.to_uppercase());
    return false;
}

/// Words of the line that reports a repair that worked.
const REPAIRED_WORDS: &str = "work at its new location";

/// Words of the line that reports a repair that could not finish.
const PENDING_WORDS: &str = "still needs one step";

/// Where the fixture's tools are linked or written: the first directory of the wrapped PATH.
fn bin(fixture: &Fixture) -> PathBuf {
    return fixture.root.join("bin");
}

/// A fixture `pnpm` that appends `arguments | directory` to a record and exits with `status`.
fn fake_pnpm(fixture: &Fixture, status: i32) -> PathBuf {
    let record: PathBuf = fixture.root.join("pnpm-record");
    executable(
        bin(fixture).join("pnpm").as_path(),
        format!("#!/bin/sh\necho \"$* | $(pwd -P)\" >> '{}'\nexit {status}\n", record.display()).as_bytes(),
    );
    return record;
}

/// A repository whose tracked files hold a lockfile and whose ignored directory holds a `node_modules` to copy.
fn repository_with_node_modules(fixture: &Fixture) -> PathBuf {
    let repo: PathBuf = repository(fixture, OsStr::new("repo"));
    std::fs::write(repo.join(".gitignore"), b"node_modules/\n").expect("gitignore");
    std::fs::write(repo.join("pnpm-lock.yaml"), b"lockfileVersion: '9.0'\n").expect("lockfile");
    git(fixture, repo.as_path(), &["add", "--", ".gitignore", "pnpm-lock.yaml"]);
    git(fixture, repo.as_path(), &["commit", "--quiet", "--message=lockfile"]);
    std::fs::create_dir_all(repo.join("node_modules/dep")).expect("node_modules");
    std::fs::write(repo.join("node_modules/dep/index.js"), b"module.exports = 1;\n").expect("dependency");
    return repo;
}

/// The lines of a record file, empty when nothing was recorded.
fn recorded(record: &Path) -> Vec<String> {
    return std::fs::read_to_string(record).map(|text: String| { return text.lines().map(str::to_owned).collect(); }).unwrap_or_default();
}

/// Add a worktree from the repository and require success.
fn add(fixture: &Fixture, repo: &Path, options: &[&str], branch: &str, destination: &str) -> Observed {
    let mut arguments: Vec<&str> = vec!["worktree", "add"];
    arguments.extend_from_slice(options);
    arguments.extend_from_slice(&["-b", branch, destination]);
    let created: Observed = run_wrapped(fixture, repo, arguments.as_slice());
    assert_eq!(created.code, Some(0), "{}", stderr_of(&created));
    return created;
}

/// pnpm is started in the new worktree, and only there, with the offline and frozen-lockfile switches; the source is not a
///  directory it runs in.
#[test]
fn pnpm_runs_in_the_new_worktree_only() {
    let fixture: Fixture = fixture("repair-pnpm-runs");
    let repo: PathBuf = repository_with_node_modules(&fixture);
    let record: PathBuf = fake_pnpm(&fixture, 0);
    let created: Observed = add(&fixture, repo.as_path(), &[], "one", "../one");
    let lines: Vec<String> = recorded(record.as_path());
    assert_eq!(lines.len(), 1, "{lines:?} {}", stderr_of(&created));
    let one: PathBuf = fixture.root.join("one");
    assert!(lines[0].ends_with(format!("| {}", one.display()).as_str()), "{lines:?}");
    assert!(lines[0].contains("--offline") && lines[0].contains("--frozen-lockfile"), "{lines:?}");
    assert!(stderr_of(&created).contains(REPAIRED_WORDS), "{}", stderr_of(&created));
    remove(&fixture);
}

/// The same add through the snapshot rung, which carries the ignored state itself, still starts pnpm in the new worktree.
#[test]
fn pnpm_runs_after_the_snapshot_rung() {
    let fixture: Fixture = fixture("repair-pnpm-snapshot");
    if !on_btrfs_or_acknowledged(&fixture, "pnpm_runs_after_the_snapshot_rung") {
        remove(&fixture);
        return;
    }
    let repo: PathBuf = subvolume_repository(&fixture);
    std::fs::write(repo.join(".gitignore"), b"ignored/\nnode_modules/\n").expect("gitignore");
    std::fs::write(repo.join("pnpm-lock.yaml"), b"lockfileVersion: '9.0'\n").expect("lockfile");
    commit_all(&fixture, repo.as_path(), "lockfile");
    std::fs::create_dir_all(repo.join("node_modules/dep")).expect("node_modules");
    std::fs::write(repo.join("node_modules/dep/index.js"), b"module.exports = 1;\n").expect("dependency");
    let record: PathBuf = fake_pnpm(&fixture, 0);
    add(&fixture, repo.as_path(), &[], "one", "../one");
    let lines: Vec<String> = recorded(record.as_path());
    assert_eq!(lines.len(), 1, "{lines:?}");
    assert!(lines[0].ends_with(format!("| {}", fixture.root.join("one").display()).as_str()), "{lines:?}");
    assert!(fixture.root.join("one/node_modules/dep/index.js").exists(), "the snapshot carried the dependency");
    remove(&fixture);
}

/// `--no-checkout` and the copy opt-out start nothing and print nothing about a repair.
#[test]
fn no_checkout_and_the_opt_out_start_nothing() {
    let fixture: Fixture = fixture("repair-pnpm-skipped");
    let repo: PathBuf = repository_with_node_modules(&fixture);
    let record: PathBuf = fake_pnpm(&fixture, 0);
    let bare: Observed = add(&fixture, repo.as_path(), &["--no-checkout"], "one", "../one");
    let opted_out: Observed = add(&fixture, repo.as_path(), &["--no-worktree-copy"], "two", "../two");
    assert!(recorded(record.as_path()).is_empty(), "a tool was started: {:?}", recorded(record.as_path()));
    for printed in [stderr_of(&bare), stderr_of(&opted_out)] {
        assert!(!printed.contains(REPAIRED_WORDS) && !printed.contains(PENDING_WORDS), "{printed}");
    }
    remove(&fixture);
}

/// `--quiet` silences the report of a repair that worked and still runs it.
#[test]
fn quiet_runs_the_repair_and_says_nothing_about_success() {
    let fixture: Fixture = fixture("repair-pnpm-quiet");
    let repo: PathBuf = repository_with_node_modules(&fixture);
    let record: PathBuf = fake_pnpm(&fixture, 0);
    let created: Observed = add(&fixture, repo.as_path(), &["--quiet"], "one", "../one");
    assert_eq!(recorded(record.as_path()).len(), 1);
    assert!(!stderr_of(&created).contains(REPAIRED_WORDS), "{}", stderr_of(&created));
    remove(&fixture);
}

/// A pnpm that fails leaves the add successful and prints one line that names the command, even under `--quiet`.
#[test]
fn a_failing_pnpm_never_fails_the_add() {
    let fixture: Fixture = fixture("repair-pnpm-fails");
    let repo: PathBuf = repository_with_node_modules(&fixture);
    fake_pnpm(&fixture, 1);
    let created: Observed = add(&fixture, repo.as_path(), &["--quiet"], "one", "../one");
    let printed: String = stderr_of(&created);
    let line: &str = printed.lines().find(|line: &&str| { return line.contains(PENDING_WORDS); }).expect("one line about the repair");
    assert!(line.contains("pnpm --dir") && line.contains("--offline") && line.contains("--frozen-lockfile"), "{line}");
    assert!(line.contains(fixture.root.join("one").to_str().expect("utf8")), "{line}");
    assert!(fixture.root.join("one/node_modules/dep/index.js").exists(), "the copy is kept");
    remove(&fixture);
}

/// A missing pnpm is the same: the add succeeds and the line says what to run.
#[test]
fn a_missing_pnpm_never_fails_the_add() {
    let fixture: Fixture = fixture("repair-pnpm-missing");
    let repo: PathBuf = repository_with_node_modules(&fixture);
    let created: Observed = add(&fixture, repo.as_path(), &[], "one", "../one");
    let printed: String = stderr_of(&created);
    assert!(printed.contains("pnpm was not found") && printed.contains("--frozen-lockfile"), "{printed}");
    remove(&fixture);
}

/// The most the fixture pnpm waits for its release, in tenths of a second; a bound so that a failing control cannot hang.
const HOLD_TENTHS: u32 = 150;

/// How long the control waits for the held repair to start, in tenths of a second.
const START_WAIT_TENTHS: u32 = 300;

/// While one add's repair runs, another add in the same repository is not held by it: the repairs touch only their own new
///  worktree, so the settlement lock is released before they start.
#[test]
fn a_running_repair_does_not_hold_another_add() {
    let fixture: Fixture = fixture("repair-lock-free");
    let repo: PathBuf = repository_with_node_modules(&fixture);
    let record: PathBuf = fixture.root.join("pnpm-record");
    let started: PathBuf = fixture.root.join("held-started");
    let release: PathBuf = fixture.root.join("held-release");
    executable(
        bin(&fixture).join("pnpm").as_path(),
        format!(
            "#!/bin/sh\necho \"$* | $(pwd -P)\" >> '{record}'\ncase \"$(pwd -P)\" in\n  */one) : > '{started}'; waited=0; while [ ! -e '{release}' ] && [ $waited -lt {HOLD_TENTHS} ]; do sleep 0.1; waited=$((waited + 1)); done;;\nesac\nexit 0\n",
            record = record.display(),
            started = started.display(),
            release = release.display(),
        )
        .as_bytes(),
    );
    let mut first = wrapped(&fixture).current_dir(&repo).args(["worktree", "add", "--quiet", "-b", "one", "../one"]).stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::piped()).spawn().expect("start the first add");
    let mut waited: u32 = 0;
    while !started.exists() && waited < START_WAIT_TENTHS {
        std::thread::sleep(std::time::Duration::from_millis(100));
        waited += 1;
    }
    assert!(started.exists(), "the first add's repair never started");
    let second: Observed = add(&fixture, repo.as_path(), &["--quiet"], "two", "../two");
    assert!(first.try_wait().expect("poll the first add").is_none(), "the first add ended before the second returned, so the second waited for it: {}", stderr_of(&second));
    assert!(!release.exists());
    assert!(fixture.root.join("two/node_modules/dep/index.js").exists(), "the second worktree is whole");
    std::fs::write(&release, b"go").expect("release the first repair");
    let finished = first.wait_with_output().expect("wait for the first add");
    assert_eq!(finished.status.code(), Some(0), "{}", String::from_utf8_lossy(&finished.stderr));
    assert_eq!(recorded(record.as_path()).len(), 2, "each add repaired its own worktree: {:?}", recorded(record.as_path()));
    remove(&fixture);
}

/// A real `pnpm` found by the test process, linked into the fixture's PATH directory.
fn link_real(fixture: &Fixture, name: &str, target: &Path) {
    std::os::unix::fs::symlink(target, bin(fixture).join(name)).expect("link a real tool");
}

/// The first executable named `name` on the test process's PATH.
fn on_path(name: &str) -> Option<PathBuf> {
    let search: std::ffi::OsString = std::env::var_os("PATH")?;
    return std::env::split_paths(&search).map(|directory: PathBuf| { return directory.join(name); }).find(|candidate: &PathBuf| { return candidate.is_file(); });
}

/// The first `pnpm` on the test process's PATH that is pnpm itself and not the repository's shadow of it, which looks for a
///  real pnpm further along the PATH and finds none in the fixture's.
fn real_pnpm() -> Option<PathBuf> {
    let search: std::ffi::OsString = std::env::var_os("PATH")?;
    return std::env::split_paths(&search)
        .map(|directory: PathBuf| { return directory.join("pnpm"); })
        .filter(|candidate: &PathBuf| { return candidate.is_file(); })
        .find(|candidate: &PathBuf| {
            let version = Command::new(candidate).arg("--version").stdin(std::process::Stdio::null()).output();
            return version.is_ok_and(|output: std::process::Output| { return output.status.success() && !String::from_utf8_lossy(&output.stdout).contains("shadow"); });
        });
}

/// Run a linked tool in a directory with the hermetic environment the wrapped runs use, and require success.
fn run_tool(fixture: &Fixture, program: &str, directory: &Path, arguments: &[&str]) -> String {
    let output = Command::new(bin(fixture).join(program))
        .env_clear()
        .env("PATH", format!("{}:/usr/bin:/bin", bin(fixture).display()))
        .env("HOME", fixture.root.join("home"))
        .current_dir(directory)
        .args(arguments)
        .output()
        .expect("run the tool");
    assert!(output.status.success(), "{program} {arguments:?} failed in {}: {}", directory.display(), String::from_utf8_lossy(&output.stderr));
    return String::from_utf8_lossy(&output.stdout).into_owned();
}

/// A workspace whose one dependency is a local tarball, installed with the global virtual store outside the tree: the
///  layout whose links climb out of the tree by a fixed number of levels.
fn pnpm_repository(fixture: &Fixture) -> PathBuf {
    let repo: PathBuf = repository(fixture, OsStr::new("repo"));
    std::fs::create_dir_all(fixture.root.join("home")).expect("home");
    let packed: PathBuf = fixture.root.join("leaf-source");
    std::fs::create_dir_all(packed.join("package")).expect("package directory");
    std::fs::write(packed.join("package/package.json"), b"{\"name\":\"leaf\",\"version\":\"1.0.0\"}\n").expect("leaf manifest");
    std::fs::create_dir_all(repo.join("vendor")).expect("vendor");
    let tar = Command::new("/usr/bin/tar").arg("--create").arg("--gzip").arg("--file").arg(repo.join("vendor/leaf.tgz")).arg("--directory").arg(&packed).arg("package").status().expect("tar");
    assert!(tar.success());
    std::fs::write(repo.join("package.json"), b"{\"name\":\"root\",\"private\":true,\"dependencies\":{\"leaf\":\"file:./vendor/leaf.tgz\"}}\n").expect("manifest");
    std::fs::write(repo.join("pnpm-workspace.yaml"), format!("storeDir: {}\nvirtualStoreType: global\n", fixture.root.join("store").display())).expect("workspace");
    std::fs::write(repo.join(".gitignore"), b"node_modules/\n.claude/\n").expect("gitignore");
    run_tool(fixture, "pnpm", repo.as_path(), &["install"]);
    git(fixture, repo.as_path(), &["add", "--", ".gitignore", "package.json", "pnpm-workspace.yaml", "pnpm-lock.yaml", "vendor/leaf.tgz"]);
    git(fixture, repo.as_path(), &["commit", "--quiet", "--message=workspace"]);
    return repo;
}

/// With real pnpm: a copy of the install at another depth has a dead entry, and after the add the entry resolves, both in a
///  worktree under the source and in one outside it, with the source left as it was.
#[test]
fn real_pnpm_relinks_a_global_virtual_store_install() {
    let fixture: Fixture = fixture("repair-real-pnpm");
    let real: Option<PathBuf> = real_pnpm();
    if !available_or_acknowledged(real.as_deref(), "pnpm", "real_pnpm_relinks_a_global_virtual_store_install") {
        remove(&fixture);
        return;
    }
    link_real(&fixture, "pnpm", real.as_deref().expect("checked above"));
    let repo: PathBuf = pnpm_repository(&fixture);
    let entry = |root: &Path| -> PathBuf { return root.join("node_modules/leaf/package.json"); };
    assert!(entry(repo.as_path()).exists(), "the source install works");
    let before: Vec<PathBuf> = std::fs::read_dir(repo.join("node_modules")).expect("source modules").flatten().map(|item| { return item.path(); }).collect();
    // Positive control: the same tree copied verbatim to another depth has a dead entry, so the fixture reproduces the hazard.
    std::fs::create_dir_all(fixture.root.join("deeper/more")).expect("deeper");
    let control: PathBuf = fixture.root.join("deeper/more/control");
    std::fs::create_dir_all(&control).expect("control");
    let copied = Command::new("/usr/bin/cp").arg("--archive").arg(repo.join("node_modules")).arg(&control).status().expect("cp");
    assert!(copied.success());
    assert!(!entry(control.as_path()).exists(), "the verbatim copy should hold a dead link");
    let outside: Observed = add(&fixture, repo.as_path(), &["--quiet"], "outside", "../deeper/more/outside");
    let nested: Observed = add(&fixture, repo.as_path(), &["--quiet"], "nested", ".claude/worktrees/nested");
    for (label, root) in [("outside", fixture.root.join("deeper/more/outside")), ("nested", repo.join(".claude/worktrees/nested"))] {
        assert!(entry(root.as_path()).exists(), "{label}: the entry is dead after the add: {} {}", stderr_of(&outside), stderr_of(&nested));
        let resolved: PathBuf = std::fs::canonicalize(entry(root.as_path())).expect("resolved");
        assert!(!resolved.starts_with(repo.join("node_modules")), "{label}: resolves into the source's modules: {}", resolved.display());
    }
    let after: Vec<PathBuf> = std::fs::read_dir(repo.join("node_modules")).expect("source modules").flatten().map(|item| { return item.path(); }).collect();
    assert_eq!(before.len(), after.len(), "the source's node_modules changed");
    assert!(entry(repo.as_path()).exists(), "the source install still works");
    remove(&fixture);
}

/// The registry crate the Cargo fixture depends on, so a build shows what is reused.
const REGISTRY_CRATE: &str = "itoa-1.0.18";

/// The person's Cargo home when its offline cache holds `REGISTRY_CRATE`, which lets a fixture depend on a registry crate
///  without the network.
fn cargo_home_with_registry_crate() -> Option<PathBuf> {
    let home: PathBuf = std::env::var_os("CARGO_HOME").map(PathBuf::from).or_else(|| { return std::env::var_os("HOME").map(|home: std::ffi::OsString| { return PathBuf::from(home).join(".cargo"); }); })?;
    let indexes = std::fs::read_dir(home.join("registry/cache")).ok()?;
    let found: bool = indexes.flatten().any(|index| { return index.path().join(format!("{REGISTRY_CRATE}.crate")).is_file(); });
    return found.then_some(home);
}

/// A Cargo workspace of two path-dependent crates, built once in the source. `external` keys the build directory by workspace
///  path outside the tree, as the person's `~/.cargo/config.toml` does; otherwise Cargo's default layout applies.
fn cargo_repository(fixture: &Fixture, external: bool) -> PathBuf {
    let repo: PathBuf = repository(fixture, OsStr::new("repo"));
    std::fs::create_dir_all(fixture.root.join("home")).expect("home");
    for directory in ["lib/src", "app/src", ".cargo"] {
        std::fs::create_dir_all(repo.join(directory)).expect("directory");
    }
    std::fs::write(repo.join("Cargo.toml"), b"[workspace]\nmembers = [\"app\", \"lib\"]\nresolver = \"3\"\n").expect("workspace");
    let registry: bool = cargo_home_with_registry_crate().is_some();
    let dependency: &str = if registry { "\n[dependencies]\nitoa = \"=1.0.18\"\n" } else { "" };
    std::fs::write(repo.join("lib/Cargo.toml"), format!("[package]\nname = \"lib\"\nversion = \"0.1.0\"\nedition = \"2024\"\n{dependency}")).expect("lib manifest");
    let uses: &str = if registry { "pub fn render(number: u32) -> String { return itoa::Buffer::new().format(number).to_owned(); }\n" } else { "" };
    std::fs::write(repo.join("lib/src/lib.rs"), format!("pub const MANIFEST: &str = env!(\"CARGO_MANIFEST_DIR\");\n{uses}")).expect("lib source");
    std::fs::write(repo.join("app/Cargo.toml"), b"[package]\nname = \"app\"\nversion = \"0.1.0\"\nedition = \"2024\"\n\n[dependencies]\nlib = { path = \"../lib\" }\n").expect("app manifest");
    std::fs::write(repo.join("app/src/main.rs"), b"fn main() { println!(\"{}\", lib::MANIFEST); }\n").expect("app source");
    let layout: String = if external { format!("[build]\nbuild-dir = \"{}/{{workspace-path-hash}}\"\n", fixture.root.join("cargo-build").display()) } else { String::new() };
    std::fs::write(repo.join(".cargo/config.toml"), layout).expect("cargo config");
    std::fs::write(repo.join(".gitignore"), b"target/\n.claude/\n").expect("gitignore");
    run_tool(fixture, "cargo", repo.as_path(), &["build", "--offline"]);
    git(fixture, repo.as_path(), &["add", "--", ".gitignore", ".cargo/config.toml", "Cargo.toml", "Cargo.lock", "lib", "app"]);
    git(fixture, repo.as_path(), &["commit", "--quiet", "--message=workspace"]);
    return repo;
}

/// The crates Cargo compiled (not found fresh) in one build of a workspace.
fn compiled(fixture: &Fixture, root: &Path) -> Vec<String> {
    let output: String = run_tool(fixture, "cargo", root, &["build", "--offline", "--message-format=json"]);
    let mut names: Vec<String> = output
        .lines()
        .filter(|line: &&str| { return line.starts_with("{\"reason\":\"compiler-artifact\""); })
        .filter_map(|line: &str| { return serde_json::from_str::<serde_json::Value>(line).ok(); })
        .filter(|artifact: &serde_json::Value| { return artifact["fresh"] == false; })
        .filter_map(|artifact: serde_json::Value| { return artifact["target"]["name"].as_str().map(str::to_owned); })
        .collect();
    names.sort();
    return names;
}

/// Link the person's Rust toolchain into the fixture's PATH directory and share only the registry of their Cargo home, or say
///  loudly why the controls cannot run.
fn prepare_cargo(fixture: &Fixture, name: &str) -> bool {
    let compiler: Option<PathBuf> = on_path("rustc");
    if !available_or_acknowledged(compiler.as_deref(), "cargo", name) {
        return false;
    }
    let sysroot: String = String::from_utf8_lossy(&Command::new("rustc").arg("--print").arg("sysroot").output().expect("rustc").stdout).trim().to_owned();
    for tool in ["cargo", "rustc", "rustdoc"] {
        link_real(fixture, tool, Path::new(sysroot.as_str()).join("bin").join(tool).as_path());
    }
    // The registry crate comes from the person's offline cache, reached through the fixture's home.
    if let Some(home) = cargo_home_with_registry_crate() {
        // Only the registry is shared: the person's Cargo configuration (which keys the build directory) must not apply.
        std::fs::create_dir_all(fixture.root.join("home/.cargo")).expect("fixture cargo home");
        std::os::unix::fs::symlink(home.join("registry"), fixture.root.join("home/.cargo/registry")).expect("link the registry");
    } else {
        eprintln!("REGISTRY REUSE NOT EXERCISED: {name} (no {REGISTRY_CRATE} in the offline Cargo cache)");
    }
    return true;
}

/// With real Cargo, in each layout and in a worktree under the source and one outside it: the worktree's crates rebuild with
///  the worktree's own paths, a second build compiles nothing, an edit in the worktree rebuilds, and the source is untouched.
fn cargo_control(name: &str, external: bool) {
    let fixture: Fixture = fixture(name);
    if !prepare_cargo(&fixture, name) {
        remove(&fixture);
        return;
    }
    let repo: PathBuf = cargo_repository(&fixture, external);
    let source_output: String = run_tool(&fixture, "cargo", repo.as_path(), &["run", "--offline", "--quiet"]);
    assert_eq!(source_output.trim(), repo.join("lib").to_str().expect("utf8"));
    std::fs::create_dir_all(fixture.root.join("deeper")).expect("deeper");
    let outside: Observed = add(&fixture, repo.as_path(), &["--quiet"], "outside", "../deeper/outside");
    let nested: Observed = add(&fixture, repo.as_path(), &["--quiet"], "nested", ".claude/worktrees/nested");
    for (label, root) in [("outside", fixture.root.join("deeper/outside")), ("nested", repo.join(".claude/worktrees/nested"))] {
        let reported: String = format!("{} {}", stderr_of(&outside), stderr_of(&nested));
        assert!(!reported.contains(PENDING_WORDS), "{label}: {reported}");
        // Dependencies from the registry are reused (not compiled again); the worktree's own crates rebuild.
        let first: Vec<String> = compiled(&fixture, root.as_path());
        assert_eq!(first, vec![String::from("app"), String::from("lib")], "{label}: only the worktree's own crates rebuild: {reported}");
        let ran: String = run_tool(&fixture, "cargo", root.as_path(), &["run", "--offline", "--quiet"]);
        assert_eq!(ran.trim(), root.join("lib").to_str().expect("utf8"), "{label}: the build names the worktree's own paths");
        assert!(compiled(&fixture, root.as_path()).is_empty(), "{label}: a second build compiles nothing");
        std::fs::write(root.join("lib/src/lib.rs"), b"pub const MANIFEST: &str = env!(\"CARGO_MANIFEST_DIR\");\npub const EDITED: u8 = 1;\n").expect("edit in the worktree");
        assert!(compiled(&fixture, root.as_path()).contains(&String::from("lib")), "{label}: an edit in the worktree rebuilds");
    }
    assert!(compiled(&fixture, repo.as_path()).is_empty(), "the source build is still fresh");
    let still: String = run_tool(&fixture, "cargo", repo.as_path(), &["run", "--offline", "--quiet"]);
    assert_eq!(still.trim(), repo.join("lib").to_str().expect("utf8"), "the source still names its own paths");
    remove(&fixture);
}

/// Cargo with the build directory keyed by workspace path outside the tree, as the person's configuration has it.
#[test]
fn real_cargo_rebuilds_own_crates_with_an_external_build_directory() {
    cargo_control("repair-real-cargo-external", true);
}

/// Cargo's default layout, where the build state lives in `target/` and arrives with the copy.
#[test]
fn real_cargo_rebuilds_own_crates_with_the_default_layout() {
    cargo_control("repair-real-cargo-default", false);
}

/// With real Cargo and a committed `Cargo.lock` that no longer matches a manifest (the state of several workspaces of this
///  repository), the clean needs Cargo to resolve and Cargo would rewrite the lock; the add must leave the tracked file as
///  checked out, so `git status` of the new worktree stays clean, and must not report a failure.
#[test]
fn real_cargo_leaves_a_stale_lockfile_as_checked_out() {
    let fixture: Fixture = fixture("repair-real-cargo-stale-lock");
    if !prepare_cargo(&fixture, "real_cargo_leaves_a_stale_lockfile_as_checked_out") {
        remove(&fixture);
        return;
    }
    let repo: PathBuf = cargo_repository(&fixture, false);
    // A new member that `app` now depends on, committed without regenerating the lock.
    std::fs::create_dir_all(repo.join("extra/src")).expect("extra");
    std::fs::write(repo.join("extra/Cargo.toml"), b"[package]\nname = \"extra\"\nversion = \"0.1.0\"\nedition = \"2024\"\n").expect("extra manifest");
    std::fs::write(repo.join("extra/src/lib.rs"), b"pub const EXTRA: u8 = 1;\n").expect("extra source");
    std::fs::write(repo.join("Cargo.toml"), b"[workspace]\nmembers = [\"app\", \"lib\", \"extra\"]\nresolver = \"3\"\n").expect("workspace");
    let app: String = std::fs::read_to_string(repo.join("app/Cargo.toml")).expect("app manifest");
    std::fs::write(repo.join("app/Cargo.toml"), format!("{app}extra = {{ path = \"../extra\" }}\n")).expect("app manifest with extra");
    git(&fixture, repo.as_path(), &["add", "--", "Cargo.toml", "app/Cargo.toml", "extra"]);
    git(&fixture, repo.as_path(), &["commit", "--quiet", "--message=a member the lock lacks"]);
    let before: Vec<u8> = std::fs::read(repo.join("Cargo.lock")).expect("lock");
    std::fs::create_dir_all(fixture.root.join("deeper")).expect("deeper");
    let created: Observed = add(&fixture, repo.as_path(), &["--quiet"], "stale", "../deeper/stale");
    let worktree: PathBuf = fixture.root.join("deeper/stale");
    assert!(!stderr_of(&created).contains(PENDING_WORDS), "{}", stderr_of(&created));
    assert_eq!(std::fs::read(worktree.join("Cargo.lock")).expect("worktree lock"), before, "the worktree's lock was rewritten");
    let status = git(&fixture, worktree.as_path(), &["status", "--porcelain"]);
    assert!(status.stdout.is_empty(), "the new worktree is dirty: {}", String::from_utf8_lossy(&status.stdout));
    assert_eq!(std::fs::read(repo.join("Cargo.lock")).expect("source lock"), before, "the source's lock changed");
    remove(&fixture);
}