cook: don't stage recipes with cargo path deps escaping their source

redbear-greeter's manifest has
  redbear-login-protocol = { path = "../../redbear-login-protocol/source" }
Cargo resolves that relative to the manifest, so out-of-tree staging pointed it
at <recipe>/target/redbear-login-protocol/source:
  failed to read .../target/redbear-login-protocol/source/Cargo.toml
  No such file or directory (os error 2)

Rewriting the manifest would silently change dependency paths behind the
recipe's back. Leaving these in tree is the honest option: they are cargo
recipes that do not sed their source, so the mutation risk staging exists to
prevent does not apply to them.
This commit is contained in:
2026-08-04 19:24:40 +03:00
parent 85462821a2
commit 130f37de8b
+20
View File
@@ -1001,7 +1001,27 @@ pub fn build(
// ones recipes actually rewrite.
let source_is_submodule = source_real.join(".git").exists();
// Cargo path dependencies that ESCAPE the source tree cannot be
// staged: they are resolved relative to the manifest, so moving the
// manifest breaks them. redbear-greeter depends on
// `../redbear-login-protocol/source`, which under staging resolved
// to <recipe>/target/redbear-login-protocol/source and failed:
// failed to read .../target/redbear-login-protocol/source/Cargo.toml
// No such file or directory (os error 2)
// Rewriting the manifests would edit dependency paths behind the
// recipe's back; leaving these in tree is the honest option. They
// are Rust recipes that build via cargo and do not sed their source,
// so the mutation risk staging protects against does not apply.
let escapes_source_tree = fs::read_to_string(source_real.join("Cargo.toml"))
.map(|manifest| {
manifest
.lines()
.any(|l| l.contains("path") && l.contains("\"..") )
})
.unwrap_or(false);
let source_is_tracked = !source_is_submodule
&& !escapes_source_tree
&& std::env::var_os("REDBEAR_IN_TREE_BUILD").is_none()
&& Command::new("git")
.arg("ls-files")