test(cli): the terminal tests speak BSD script on macOS; a noted root is compared as the system spells it
check / check (push) Canceled after 0s
portable-macos / portable (macos-latest) (push) Canceled after 0s
portable-windows / portable (windows-latest) (push) Canceled after 0s
two-user / two-user (push) Canceled after 0s

The portable macOS job, now past the server start: `script -qefc` is
util-linux's spelling; macOS's BSD `script` has no -f and no -c, so the
three pseudo-terminal helpers choose the spelling for the OS. And the
root noted "for next time" is the canonical path (macOS writes /tmp as
/private/tmp); the test compares it canonically.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
swaitsandClaude Fable 5.1 committed 2026-10-29 18:36:34 -06:00
1 parent 1353be0c10
commit 932c05177f
3 files changed
+53 -7

No files matched your search

+15 -1
View File
@@ -144,7 +144,7 @@ impl Home {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" "); .join(" ");
let mut child = Command::new("script") let mut child = Command::new("script")
.args(["-qefc", &command, "/dev/null"]) .args(script_args(&command))
.env_clear() .env_clear()
.env("PATH", "/usr/bin:/bin") .env("PATH", "/usr/bin:/bin")
.env("HOME", self.dir.path()) .env("HOME", self.dir.path())
@@ -973,3 +973,17 @@ fn books_p2_served_cut_over_whole() {
"and never after" "and never after"
); );
} }
/// `script`'s arguments to run `command` on a pseudo-terminal, quietly,
/// with the command's exit code as its own: util-linux's spelling on
/// Linux, BSD's on macOS (no `-f`, no `-c`; the command after the file).
fn script_args(command: &str) -> Vec<String> {
if cfg!(target_os = "macos") {
["-qeF", "/dev/null", "/bin/sh", "-c", command]
} else {
["-qefc", command, "/dev/null"]
}
.into_iter()
.map(String::from)
.collect()
}
+15 -1
View File
@@ -1944,7 +1944,7 @@ fn the_books_command_takes_its_flags_and_asks_before_adopting() {
args.push(a.to_string()); args.push(a.to_string());
} }
let mut child = Command::new("script") let mut child = Command::new("script")
.args(["-qefc", &args.join(" "), "/dev/null"]) .args(script_args(&args.join(" ")))
.env_clear() .env_clear()
.env("PATH", "/usr/bin:/bin") .env("PATH", "/usr/bin:/bin")
.env("HOME", home.dir.path()) .env("HOME", home.dir.path())
@@ -2948,3 +2948,17 @@ fn token_check_says_where_the_token_file_stands_and_an_unreadable_one_is_said()
let (_, listed, _) = token(&["list"]); let (_, listed, _) = token(&["list"]);
assert!(listed.contains("No tokens yet"), "{listed}"); assert!(listed.contains("No tokens yet"), "{listed}");
} }
/// `script`'s arguments to run `command` on a pseudo-terminal, quietly,
/// with the command's exit code as its own: util-linux's spelling on
/// Linux, BSD's on macOS (no `-f`, no `-c`; the command after the file).
fn script_args(command: &str) -> Vec<String> {
if cfg!(target_os = "macos") {
["-qeF", "/dev/null", "/bin/sh", "-c", command]
} else {
["-qefc", command, "/dev/null"]
}
.into_iter()
.map(String::from)
.collect()
}
+23 -5
View File
@@ -95,7 +95,11 @@ fn a_root_elsewhere_is_noted_for_next_time() {
ledger_store::root::platform_data_dir(home.path()).join("wanderbooks.location"), ledger_store::root::platform_data_dir(home.path()).join("wanderbooks.location"),
) )
.unwrap(); .unwrap();
assert_eq!(noted.trim_end(), elsewhere.display().to_string()); // As the system spells it (macOS writes /tmp as /private/tmp).
assert_eq!(
std::path::PathBuf::from(noted.trim_end()),
std::fs::canonicalize(&elsewhere).unwrap()
);
} }
#[test] #[test]
@@ -155,9 +159,23 @@ fn another_home_ignores_this_accounts_data_home() {
); );
} }
/// Run `args` at a terminal (a pseudo-terminal, through util-linux /// `script`'s arguments to run `command` on a pseudo-terminal, quietly,
/// `script`), typing `lines` one at a time: its exit code and what the /// with the command's exit code as its own: util-linux's spelling on
/// terminal showed. /// Linux, BSD's on macOS (no `-f`, no `-c`; the command after the file).
fn script_args(command: &str) -> Vec<String> {
if cfg!(target_os = "macos") {
["-qeF", "/dev/null", "/bin/sh", "-c", command]
} else {
["-qefc", command, "/dev/null"]
}
.into_iter()
.map(String::from)
.collect()
}
/// Run `args` at a terminal (a pseudo-terminal, through `script`),
/// typing `lines` one at a time: its exit code and what the terminal
/// showed.
fn at_terminal(args: &[String], lines: &[&str]) -> (i32, String) { fn at_terminal(args: &[String], lines: &[&str]) -> (i32, String) {
use std::io::Write; use std::io::Write;
let command = std::iter::once(env!("CARGO_BIN_EXE_wanderbooks").to_string()) let command = std::iter::once(env!("CARGO_BIN_EXE_wanderbooks").to_string())
@@ -165,7 +183,7 @@ fn at_terminal(args: &[String], lines: &[&str]) -> (i32, String) {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" "); .join(" ");
let mut child = Command::new("script") let mut child = Command::new("script")
.args(["-qefc", &command, "/dev/null"]) .args(script_args(&command))
.env_remove("XDG_DATA_HOME") .env_remove("XDG_DATA_HOME")
.stdin(std::process::Stdio::piped()) .stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped())