feat: Add template system to weevil new command
Implements template-based project creation allowing teams to start with
professional example code instead of empty projects.
Features:
- Two templates: 'basic' (minimal) and 'testing' (45-test showcase)
- Template variable substitution ({{PROJECT_NAME}}, etc.)
- Template validation with helpful error messages
- `weevil new --list-templates` command
- Template files embedded in binary at compile time
Technical details:
- Templates stored in templates/basic/ and templates/testing/
- Files ending in .template have variables replaced
- Uses include_dir! macro to embed templates in binary
- Returns file count for user feedback
Testing template includes:
- 3 complete subsystems (MotorCycler, WallApproach, TurnController)
- Hardware abstraction layer with mock implementations
- 45 comprehensive tests (unit, integration, system)
- Professional documentation (DESIGN_AND_TEST_PLAN.md, etc.)
Usage:
weevil new my-robot # basic template
weevil new my-robot --template testing # testing showcase
weevil new --list-templates # show available templates
This enables FTC teams to learn from working code and best practices
rather than starting from scratch.
This commit is contained in:
32
src/main.rs
32
src/main.rs
@@ -3,12 +3,6 @@ use colored::*;
|
||||
use anyhow::Result;
|
||||
use weevil::version::WEEVIL_VERSION;
|
||||
|
||||
// Import ProxyConfig through our own `mod sdk`, not through the `weevil`
|
||||
// library crate. Both re-export the same source, but Rust treats
|
||||
// `weevil::sdk::proxy::ProxyConfig` and `sdk::proxy::ProxyConfig` as
|
||||
// distinct types when a binary and its lib are compiled together.
|
||||
// The command modules already see the local-mod version, so main must match.
|
||||
|
||||
mod commands;
|
||||
mod sdk;
|
||||
mod project;
|
||||
@@ -42,7 +36,7 @@ enum Commands {
|
||||
/// Create a new FTC robot project
|
||||
New {
|
||||
/// Name of the robot project
|
||||
name: String,
|
||||
name: Option<String>,
|
||||
|
||||
/// Path to FTC SDK (optional, will auto-detect or download)
|
||||
#[arg(long)]
|
||||
@@ -51,6 +45,14 @@ enum Commands {
|
||||
/// Path to Android SDK (optional, will auto-detect or download)
|
||||
#[arg(long)]
|
||||
android_sdk: Option<String>,
|
||||
|
||||
/// Template to use (basic, testing)
|
||||
#[arg(long, short = 't', value_name = "TEMPLATE")]
|
||||
template: Option<String>,
|
||||
|
||||
/// List available templates
|
||||
#[arg(long, conflicts_with = "name")]
|
||||
list_templates: bool,
|
||||
},
|
||||
|
||||
/// Check system health and diagnose issues
|
||||
@@ -139,8 +141,20 @@ fn main() -> Result<()> {
|
||||
let proxy = ProxyConfig::resolve(cli.proxy.as_deref(), cli.no_proxy)?;
|
||||
|
||||
match cli.command {
|
||||
Commands::New { name, ftc_sdk, android_sdk } => {
|
||||
commands::new::create_project(&name, ftc_sdk.as_deref(), android_sdk.as_deref(), &proxy)
|
||||
Commands::New { name, ftc_sdk, android_sdk, template, list_templates } => {
|
||||
if list_templates {
|
||||
commands::new::list_templates()
|
||||
} else if let Some(project_name) = name {
|
||||
commands::new::create_project(
|
||||
&project_name,
|
||||
ftc_sdk.as_deref(),
|
||||
android_sdk.as_deref(),
|
||||
template.as_deref(),
|
||||
&proxy
|
||||
)
|
||||
} else {
|
||||
anyhow::bail!("Project name is required. Use --list-templates to see available templates.");
|
||||
}
|
||||
}
|
||||
Commands::Doctor => {
|
||||
commands::doctor::run_diagnostics()
|
||||
|
||||
Reference in New Issue
Block a user