Support Cargo scaffolding and human output, and find boolean expressions

This commit is contained in:
2026-11-11 21:57:37 +00:00
parent c7606b8ae9
commit 652ea7960f
7 changed files with 267 additions and 116 deletions
+21 -9
View File
@@ -66,7 +66,7 @@ impl Builder {
ensure!(
[
"build", "check", "clippy", "test", "run", "fmt", "fetch", "add", "remove",
"update", "tree", "metadata", "clean"
"update", "tree", "metadata", "clean", "new", "init"
]
.contains(&action),
"unsupported Cargo command"
@@ -96,7 +96,14 @@ impl Builder {
.checked_add(Duration::from_secs(seconds))
.context("timeout too large")?;
let world_cwd = sausage_vfs::resolve("/", &request.cwd);
let workspace = files::workspace(self.root.as_ref(), &world_cwd).await?;
let scaffold = matches!(action, "new" | "init");
let workspace = if scaffold {
files::workspace(self.root.as_ref(), &world_cwd)
.await
.unwrap_or_else(|_| world_cwd.clone())
} else {
files::workspace(self.root.as_ref(), &world_cwd).await?
};
let world_target = sausage_vfs::resolve(&workspace, "target");
use std::hash::{Hash, Hasher};
let mut hash = std::collections::hash_map::DefaultHasher::new();
@@ -140,10 +147,10 @@ impl Builder {
fetch.arg("fetch");
}
fetch.current_dir(&cwd).env("CARGO_HOME", &registry);
let mut code = if matches!(action, "clean" | "fmt" | "remove") {
let mut code = if scaffold || matches!(action, "clean" | "fmt" | "remove") {
0
} else {
run(fetch, tx, deadline).await?.0
run(fetch, tx, deadline, false).await?.0
};
if code == 0 && action == "add" {
let mut fetch = Command::new("cargo");
@@ -151,7 +158,7 @@ impl Builder {
.arg("fetch")
.current_dir(&cwd)
.env("CARGO_HOME", &registry);
code = run(fetch, tx, deadline).await?.0;
code = run(fetch, tx, deadline, false).await?.0;
}
let mut executables = Vec::new();
if code == 0 {
@@ -191,7 +198,7 @@ impl Builder {
)?;
let mut startup = Command::new("nu");
startup.arg(tools.join("build.nu"));
let (startup_code, _) = run(startup, tx, deadline).await?;
let (startup_code, _) = run(startup, tx, deadline, false).await?;
if startup_code != 0 {
files::copy_back(self.root.as_ref(), &source, &workspace, Some(&before)).await?;
self.evict(20 * 1024 * 1024 * 1024)?;
@@ -303,7 +310,7 @@ impl Builder {
]);
}
cmd.args(&args[split..]);
let (status, stdout) = run(cmd, tx, deadline).await?;
let (status, stdout) = run(cmd, tx, deadline, compiles).await?;
code = status;
if action == "clean" && code == 0 {
files::clean_artifacts(self.root.as_ref(), &target, &world_target).await?;
@@ -439,6 +446,7 @@ async fn pump(
mut reader: impl tokio::io::AsyncRead + Unpin,
tx: &mpsc::Sender<Event>,
stderr: bool,
silent_stdout: bool,
) -> Result<Vec<u8>> {
let mut all = Vec::new();
let mut bytes = vec![0; 8192];
@@ -450,6 +458,9 @@ async fn pump(
if !stderr {
all.extend_from_slice(&bytes[..n]);
}
if !stderr && silent_stdout {
continue;
}
tx.send(if stderr {
Event::Stderr {
bytes: bytes[..n].to_vec(),
@@ -466,6 +477,7 @@ async fn run(
mut cmd: Command,
tx: &mpsc::Sender<Event>,
deadline: Instant,
silent_stdout: bool,
) -> Result<(i32, Vec<u8>)> {
cmd.stdin(Stdio::null())
.stdout(Stdio::piped())
@@ -479,8 +491,8 @@ async fn run(
let collect = async {
let (status, out, _) = tokio::try_join!(
async { Ok::<_, anyhow::Error>(child.wait().await?) },
pump(out, tx, false),
pump(err, tx, true)
pump(out, tx, false, silent_stdout),
pump(err, tx, true, false)
)?;
Ok::<_, anyhow::Error>((status.code().unwrap_or(1), out))
};