use anyhow::Result;
use clap::Parser;
use std::{fs, path::Path, process::Command};
use yansi::Paint;
#[derive(Parser)]
#[command(name = "new", about = "Setup a new project that runs inside the SP1.")]
pub struct NewCmd {
name: String,
#[arg(long, action)]
evm: bool,
#[arg(long, default_value = "main")]
version: String,
}
const TEMPLATE_REPOSITORY_URL: &str = "https://github.com/succinctlabs/sp1-project-template";
impl NewCmd {
pub fn run(&self) -> Result<()> {
let root = Path::new(&self.name);
if !root.exists() {
fs::create_dir(&self.name)?;
}
println!(" \x1b[1m{}\x1b[0m {}", Paint::green("Cloning"), TEMPLATE_REPOSITORY_URL);
let output = Command::new("git")
.arg("clone")
.arg("--branch")
.arg(&self.version)
.arg(TEMPLATE_REPOSITORY_URL)
.arg(root.as_os_str())
.arg("--recurse-submodules")
.arg("--depth=1")
.output()
.expect("failed to execute command");
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(anyhow::anyhow!("failed to clone repository: {}", stderr));
}
fs::remove_dir_all(root.join(".git"))?;
if self.evm {
if Command::new("foundry").arg("--version").output().is_err() {
println!(
" \x1b[1m{}\x1b[0m Make sure to install Foundry to use contracts: https://book.getfoundry.sh/getting-started/installation",
Paint::yellow("Warning:"),
);
}
} else {
fs::remove_dir_all(root.join("contracts"))?;
fs::remove_file(root.join(".gitmodules"))?;
}
println!(
" \x1b[1m{}\x1b[0m {} ({})",
Paint::green("Initialized"),
self.name,
std::fs::canonicalize(root).expect("failed to canonicalize").to_str().unwrap()
);
Ok(())
}
}