use anyhow::{bail, Context, Result};
use clap::Args;
use crate::exec::subprocess::{command_exists, run_command};
const DEFAULT_TEMPLATE: &str = "https://github.com/zhlinh/ccgo-template";
#[derive(Args, Debug)]
pub struct NewCommand {
pub name: String,
#[arg(long)]
pub defaults: bool,
#[arg(long)]
pub template: Option<String>,
#[arg(long)]
pub use_latest: bool,
}
impl NewCommand {
pub fn execute(self, verbose: bool) -> Result<()> {
if !command_exists("copier") {
bail!(
"Copier not found. Please install it:\n\n\
pip install copier\n\
# or\n\
pipx install copier"
);
}
let template_src = self.template.as_deref().unwrap_or(DEFAULT_TEMPLATE);
let mut args = vec!["copy".to_string()];
if self.defaults {
args.push("--defaults".to_string());
}
args.push("--trust".to_string());
args.push("-d".to_string());
args.push(format!("cpy_project_name={}", self.name));
if !self.use_latest {
args.push("--vcs-ref".to_string());
args.push("HEAD".to_string());
}
args.push(template_src.to_string());
args.push(self.name.clone());
if verbose {
eprintln!(
"Creating new project '{}' from template: {}",
self.name, template_src
);
eprintln!("Running: copier {}", args.join(" "));
}
let result =
run_command("copier", &args, true, None).context("Failed to execute copier")?;
if !result.success {
bail!(
"Project creation failed with exit code: {}",
result.exit_code
);
}
if verbose {
eprintln!("✅ Project '{}' created successfully!", self.name);
}
Ok(())
}
}