1use anyhow::Result;
2use clap::{Args, Parser};
3use std::{
4 fs,
5 path::Path,
6 process::{Command, Stdio},
7};
8use yansi::Paint;
9
10#[derive(Args)]
11#[group(required = true, multiple = false)]
12struct TemplateType {
13 #[arg(long)]
15 bare: bool,
16
17 #[arg(long)]
19 evm: bool,
20}
21
22#[derive(Parser)]
23#[command(name = "new", about = "Setup a new project that runs inside the SP1.")]
24pub struct NewCmd {
25 name: String,
27
28 #[command(flatten)]
30 template: TemplateType,
31
32 #[arg(long, default_value = "main")]
34 version: String,
35}
36
37const TEMPLATE_REPOSITORY_URL: &str = "https://github.com/succinctlabs/sp1-project-template";
38
39impl NewCmd {
40 pub fn run(&self) -> Result<()> {
41 let root = Path::new(&self.name);
42
43 if !root.exists() {
45 fs::create_dir(&self.name)?;
46 }
47
48 println!(" \x1b[1m{}\x1b[0m {}", Paint::green("Cloning"), TEMPLATE_REPOSITORY_URL);
49
50 let mut command = Command::new("git");
52
53 command
54 .arg("clone")
55 .arg("--branch")
56 .arg(&self.version)
57 .arg(TEMPLATE_REPOSITORY_URL)
58 .arg(root.as_os_str())
59 .arg("--depth=1");
60
61 command.stdout(Stdio::inherit()).stderr(Stdio::piped());
63
64 let output = command.output().expect("failed to execute command");
65 if !output.status.success() {
66 let stderr = String::from_utf8_lossy(&output.stderr);
67 return Err(anyhow::anyhow!("Failed to clone repository: {}", stderr));
68 }
69
70 fs::remove_dir_all(root.join(".git"))?;
72
73 if self.template.evm {
74 if Command::new("forge").arg("--version").output().is_err() {
76 println!(
77 " \x1b[1m{}\x1b[0m Make sure to install Foundry and run `forge install` in the \"contracts\" folder to use contracts: https://book.getfoundry.sh/getting-started/installation",
78 Paint::yellow("Warning:"),
79 );
80 } else {
81 println!(
82 " \x1b[1m{}\x1b[0m Please run `forge install` in the \"contracts\" folder to setup contracts development",
83 Paint::blue("Info:"),
84 );
85 }
86 } else {
87 fs::remove_dir_all(root.join("contracts"))?;
89
90 fs::remove_file(root.join(".gitmodules"))?;
92 }
93
94 println!(
95 " \x1b[1m{}\x1b[0m {} ({})",
96 Paint::green("Initialized"),
97 self.name,
98 std::fs::canonicalize(root).expect("failed to canonicalize").to_str().unwrap()
99 );
100
101 Ok(())
102 }
103}