Files
weevil/src/main.rs
Eric Ratliff 6626ca83d1 feat: Add Windows support and stabilize SDK installation (v1.0.0-rc1)
Complete Windows compatibility overhaul with robust cross-platform SDK management.
This release candidate establishes feature freeze for the 1.0.0 release.

Key improvements:
- Fixed Android SDK installation on Windows
  * Use cmd.exe wrapper for sdkmanager.bat with piped stdin
  * Properly reorganize cmdline-tools directory structure
  * Write license acceptances synchronously to avoid hangs

- Fixed FTC SDK configuration
  * Auto-generate local.properties with Android SDK path
  * Escape backslashes in Kotlin build.gradle.kts strings
  * Support both new installs and upgrades via ensure_local_properties()

- Enhanced Windows console output
  * Enable ANSI color support via enable_ansi_support crate
  * Maintain color compatibility across Windows versions

- Improved error handling and debugging
  * Added comprehensive logging throughout SDK installation
  * Better context messages for troubleshooting failures

Cross-platform testing verified on:
- Windows 11 with Eclipse Adoptium JDK 21
- Linux (existing support maintained)

Breaking changes: None
This RC introduces feature freeze - subsequent 1.0.x releases will be
bug fixes only. New features deferred to 1.1.0.

Closes Windows compatibility milestone.
2026-01-25 18:10:18 -06:00

131 lines
3.7 KiB
Rust

use clap::{Parser, Subcommand};
use colored::*;
use anyhow::Result;
mod commands;
mod sdk;
mod project;
mod templates;
#[derive(Parser)]
#[command(name = "weevil")]
#[command(author = "Eric Barch <eric@intrepidfusion.com>")]
#[command(version = "1.0.0")]
#[command(about = "FTC robotics project generator - bores into complexity, emerges with clean code", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Create a new FTC robot project
New {
/// Name of the robot project
name: String,
/// Path to FTC SDK (optional, will auto-detect or download)
#[arg(long)]
ftc_sdk: Option<String>,
/// Path to Android SDK (optional, will auto-detect or download)
#[arg(long)]
android_sdk: Option<String>,
},
/// Upgrade an existing project to the latest generator version
Upgrade {
/// Path to the project directory
path: String,
},
/// Build and deploy project to Control Hub
Deploy {
/// Path to the project directory
path: String,
/// Force USB connection
#[arg(long)]
usb: bool,
/// Force WiFi connection
#[arg(long)]
wifi: bool,
/// Custom IP address
#[arg(short, long)]
ip: Option<String>,
},
/// Manage SDKs (FTC and Android)
Sdk {
#[command(subcommand)]
command: SdkCommands,
},
/// Show or update project configuration
Config {
/// Path to the project directory
path: String,
/// Set FTC SDK path for this project
#[arg(long, value_name = "PATH")]
set_sdk: Option<String>,
},
}
#[derive(Subcommand)]
enum SdkCommands {
/// Install required SDKs
Install,
/// Show SDK status and locations
Status,
/// Update SDKs to latest versions
Update,
}
fn main() -> Result<()> {
// Enable colors on Windows
#[cfg(windows)]
colored::control::set_virtual_terminal(true).ok();
let cli = Cli::parse();
print_banner();
match cli.command {
Commands::New { name, ftc_sdk, android_sdk } => {
commands::new::create_project(&name, ftc_sdk.as_deref(), android_sdk.as_deref())
}
Commands::Upgrade { path } => {
commands::upgrade::upgrade_project(&path)
}
Commands::Deploy { path, usb, wifi, ip } => {
commands::deploy::deploy_project(&path, usb, wifi, ip.as_deref())
}
Commands::Sdk { command } => {
match command {
SdkCommands::Install => commands::sdk::install_sdks(),
SdkCommands::Status => commands::sdk::show_status(),
SdkCommands::Update => commands::sdk::update_sdks(),
}
}
Commands::Config { path, set_sdk } => {
if let Some(sdk_path) = set_sdk {
commands::config::set_sdk(&path, &sdk_path)
} else {
commands::config::show_config(&path)
}
}
}
}
fn print_banner() {
println!("{}", "═══════════════════════════════════════════════════════════".bright_cyan());
println!("{}", " 🪲 Weevil - FTC Project Generator v1.0.0".bright_cyan().bold());
println!("{}", " Nexus Workshops LLC".bright_cyan());
println!("{}", "═══════════════════════════════════════════════════════════".bright_cyan());
println!();
}