P2 slice 3: opening and closing the books (plan 3.9, D-21, D-23)

One wanderbooks executable. The books are open while the viewer, an
agent session or a terminal holds them: a host process takes leases on
a socket, starts the server (the hidden mode `wanderbooks server`) with
a pipe on its input, and closes it 10 s after the last lease ends. No
background service. One host even in a race (run/host.lock).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-20 11:14:19 -06:00
1 parent 168e5c9846
commit a298d154b6
31 files changed
+11937 -112

No files matched your search

+39 -9
View File
@@ -69,16 +69,20 @@ fn setup_makes_the_private_folder_and_never_names_it() {
}
#[test]
fn a_root_elsewhere_is_noted_and_xdg_is_honoured() {
fn a_root_elsewhere_is_noted_for_next_time() {
// (XDG_DATA_HOME is honoured only for this account's own home, which
// a test never touches: Root::setup's tests cover it.)
let home = tempfile::Builder::new()
.prefix("wb-setup-xdg-")
.prefix("wb-setup-else-")
.tempdir()
.unwrap();
let xdg = home.path().join("xdg");
let elsewhere = home.path().join("elsewhere").join("wanderbooks");
let out = wanderbooks()
.args(["setup", "--home"])
.arg(home.path())
.env("XDG_DATA_HOME", &xdg)
.arg("--root")
.arg(&elsewhere)
.env_remove("XDG_DATA_HOME")
.output()
.unwrap();
assert!(out.status.success(), "{out:?}");
@@ -86,13 +90,10 @@ fn a_root_elsewhere_is_noted_and_xdg_is_honoured() {
String::from_utf8_lossy(&out.stdout).contains("noted for next time"),
"{out:?}"
);
assert_eq!(mode(&xdg.join("wanderbooks")), 0o700);
assert_eq!(mode(&elsewhere), 0o700);
let noted =
std::fs::read_to_string(home.path().join(".local/share/wanderbooks.location")).unwrap();
assert_eq!(
noted.trim_end(),
xdg.join("wanderbooks").display().to_string()
);
assert_eq!(noted.trim_end(), elsewhere.display().to_string());
}
#[test]
@@ -122,3 +123,32 @@ fn setup_refuses_what_it_does_not_know_and_unsafe_folders() {
let out = wanderbooks().args(["--force", "setup"]).output().unwrap();
assert_eq!(out.status.code(), Some(2));
}
/// With another home given (tests), this account's XDG_DATA_HOME is never
/// read: setup can't be aimed at this account's real books by it.
#[test]
fn another_home_ignores_this_accounts_data_home() {
let home = tempfile::Builder::new()
.prefix("wb-setup-xdg-")
.tempdir()
.unwrap();
let elsewhere = home.path().join("elsewhere");
std::fs::create_dir(&elsewhere).unwrap();
let out = wanderbooks()
.args(["setup", "--home"])
.arg(home.path())
.env("XDG_DATA_HOME", &elsewhere)
.output()
.unwrap();
assert!(out.status.success(), "{out:?}");
assert!(
home.path()
.join(".local/share/wanderbooks/.wanderbooks-root")
.is_file()
);
assert_eq!(
std::fs::read_dir(&elsewhere).unwrap().count(),
0,
"XDG_DATA_HOME was used"
);
}