use xshell::{cmd, Shell};
use crate::{cmd::Cmd, logger};
fn prerequisites() -> [Prerequisite; 5] {
[
Prerequisite {
name: "git",
download_link: "https://git-scm.com/book/en/v2/Getting-Started-Installing-Git",
custom_validator: None,
},
Prerequisite {
name: "docker",
download_link: "https://docs.docker.com/get-docker/",
custom_validator: None,
},
Prerequisite {
name: "forge",
download_link:
"https://github.com/matter-labs/foundry-zksync?tab=readme-ov-file#quick-install",
custom_validator: Some(Box::new(|| {
let shell = Shell::new().unwrap();
let Ok(result) = Cmd::new(cmd!(shell, "forge build --help")).run_with_output()
else {
return false;
};
let Ok(stdout) = String::from_utf8(result.stdout) else {
return false;
};
stdout.contains("ZKSync configuration")
})),
},
Prerequisite {
name: "cargo",
download_link: "https://doc.rust-lang.org/cargo/getting-started/installation.html",
custom_validator: None,
},
Prerequisite {
name: "yarn",
download_link: "https://yarnpkg.com/getting-started/install",
custom_validator: None,
},
]
}
const DOCKER_COMPOSE_PREREQUISITE: Prerequisite = Prerequisite {
name: "docker compose",
download_link: "https://docs.docker.com/compose/install/",
custom_validator: None,
};
pub const GPU_PREREQUISITES: [Prerequisite; 3] = [
Prerequisite {
name: "cmake",
download_link: "https://cmake.org/download/",
custom_validator: None,
},
Prerequisite {
name: "nvcc",
download_link: "https://developer.nvidia.com/cuda-downloads",
custom_validator: None,
}, Prerequisite {
name: "nvidia-smi",
download_link: "https://developer.nvidia.com/cuda-downloads",
custom_validator: None,
}, ];
pub const GCLOUD_PREREQUISITE: [Prerequisite; 1] = [Prerequisite {
name: "gcloud",
download_link: "https://cloud.google.com/sdk/docs/install",
custom_validator: None,
}];
pub const PROVER_CLI_PREREQUISITE: [Prerequisite; 1] = [Prerequisite {
name: "prover_cli",
download_link:
"https://github.com/matter-labs/zksync-era/tree/main/prover/crates/bin/prover_cli",
custom_validator: None,
}];
pub struct Prerequisite {
name: &'static str,
download_link: &'static str,
custom_validator: Option<Box<dyn Fn() -> bool>>,
}
pub fn check_general_prerequisites(shell: &Shell) {
check_prerequisites(shell, &prerequisites(), true);
}
pub fn check_prerequisites(shell: &Shell, prerequisites: &[Prerequisite], check_compose: bool) {
let mut missing_prerequisites = vec![];
for prerequisite in prerequisites {
if !check_prerequisite(shell, prerequisite) {
missing_prerequisites.push(prerequisite);
}
}
if check_compose && !check_docker_compose_prerequisite(shell) {
missing_prerequisites.push(&DOCKER_COMPOSE_PREREQUISITE);
}
if !missing_prerequisites.is_empty() {
logger::error("Prerequisite check has failed");
logger::error_note(
"The following prerequisites are missing",
&missing_prerequisites
.iter()
.map(|prerequisite| {
format!("- {} ({})", prerequisite.name, prerequisite.download_link)
})
.collect::<Vec<_>>()
.join("\n"),
);
logger::outro("Failed");
std::process::exit(1);
}
}
fn check_prerequisite(shell: &Shell, prerequisite: &Prerequisite) -> bool {
let name = prerequisite.name;
if Cmd::new(cmd!(shell, "which {name}")).run().is_err() {
return false;
}
let Some(custom) = &prerequisite.custom_validator else {
return true;
};
custom()
}
fn check_docker_compose_prerequisite(shell: &Shell) -> bool {
Cmd::new(cmd!(shell, "docker compose version"))
.run()
.is_ok()
}