use anyhow::{Result, ensure};
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::{
fs,
path::{Path, PathBuf},
process::{Child, Command, Stdio},
};
pub fn install_snarkos(snarkos_path: &Path, version: Option<&str>, features: &[String]) -> Result<PathBuf> {
let tempdir = tempfile::tempdir()?;
let install_root = tempdir.path();
let mut cmd = Command::new("cargo");
cmd.args(["install", "--locked", "--force", "snarkos", "--root", install_root.to_str().unwrap()]);
if let Some(v) = version {
cmd.arg("--version").arg(v);
}
if !features.is_empty() {
cmd.arg("--features").arg(features.join(","));
}
println!("🔧 Building snarkOS into {} …", install_root.display());
ensure!(cmd.status()?.success(), "`cargo install` failed");
let built_bin = install_root.join("bin").join(if cfg!(windows) { "snarkos.exe" } else { "snarkos" });
if snarkos_path.exists() {
fs::remove_file(snarkos_path)?; }
fs::create_dir_all(snarkos_path.parent().unwrap())?;
fs::copy(&built_bin, snarkos_path)?;
#[cfg(unix)]
{
let mut perms = fs::metadata(snarkos_path)?.permissions();
perms.set_mode(0o755); fs::set_permissions(snarkos_path, perms)?;
}
ensure!(snarkos_path.is_file(), "snarkOS binary not produced at {}", snarkos_path.display());
println!("✅ Installed snarkOS ⇒ {}", snarkos_path.display());
Ok(snarkos_path.to_path_buf())
}
pub fn clean_snarkos(
snarkos: &Path,
network: usize,
idx: usize,
ledger_storage: &Path,
node_data_storage: &Path,
) -> std::io::Result<Child> {
Command::new(snarkos)
.arg("clean")
.arg("--network")
.arg(network.to_string())
.arg("--dev")
.arg(idx.to_string())
.arg("--ledger-storage")
.arg(ledger_storage)
.arg("--node-data-storage")
.arg(node_data_storage)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
}