use anyhow::{Result, bail}; use std::path::PathBuf; use colored::*; use crate::sdk::SdkConfig; use crate::project::ProjectBuilder; pub fn create_project( name: &str, ftc_sdk: Option<&str>, android_sdk: Option<&str>, ) -> Result<()> { // Validate project name if name.is_empty() { bail!("Project name cannot be empty"); } if !name.chars().all(|c| c.is_alphanumeric() || c == '-' || c == '_') { bail!("Project name must contain only alphanumeric characters, hyphens, and underscores"); } let project_path = PathBuf::from(name); // Check if project already exists if project_path.exists() { bail!( "{}\n\nDirectory already exists: {}\n\nTo upgrade: weevil upgrade {}", "Project Already Exists".red().bold(), project_path.display(), name ); } println!("{}", format!("Creating FTC project: {}", name).bright_green().bold()); println!(); // Setup or verify SDK configuration let sdk_config = SdkConfig::with_paths(ftc_sdk, android_sdk)?; // Install SDKs if needed println!("{}", "Checking SDKs...".bright_yellow()); ensure_sdks(&sdk_config)?; println!(); println!("{}", "Creating project structure...".bright_yellow()); // Build the project let builder = ProjectBuilder::new(name, &sdk_config)?; builder.create(&project_path, &sdk_config)?; println!(); println!("{}", "═══════════════════════════════════════════════════════════".bright_green()); println!("{}", format!(" ✓ Project Created: {}", name).bright_green().bold()); println!("{}", "═══════════════════════════════════════════════════════════".bright_green()); println!(); println!("FTC SDK: {}", sdk_config.ftc_sdk_path.display()); println!("Version: {}", crate::sdk::ftc::get_version(&sdk_config.ftc_sdk_path).unwrap_or_else(|_| "unknown".to_string())); println!(); println!("{}", "Next steps:".bright_yellow().bold()); println!(" 1. cd {}", name); println!(" 2. Review README.md for project structure"); println!(" 3. Start coding in src/main/java/robot/"); println!(" 4. Run: ./gradlew test"); println!(" 5. Deploy: weevil deploy {}", name); println!(); Ok(()) } fn ensure_sdks(config: &SdkConfig) -> Result<()> { // Check FTC SDK if !config.ftc_sdk_path.exists() { println!("FTC SDK not found. Installing..."); crate::sdk::ftc::install(&config.ftc_sdk_path, &config.android_sdk_path)?; } else { println!("{} FTC SDK found at: {}", "✓".green(), config.ftc_sdk_path.display()); crate::sdk::ftc::verify(&config.ftc_sdk_path)?; } // Check Android SDK if !config.android_sdk_path.exists() { println!("Android SDK not found. Installing..."); crate::sdk::android::install(&config.android_sdk_path)?; } else { println!("{} Android SDK found at: {}", "✓".green(), config.android_sdk_path.display()); crate::sdk::android::verify(&config.android_sdk_path)?; } Ok(()) }