Anvil v1.0.0 -- Arduino build tool with HAL and test scaffolding
Single-binary CLI that scaffolds testable Arduino projects, compiles, uploads, and monitors serial output. Templates embed a hardware abstraction layer, Google Mock infrastructure, and CMake-based host tests so application logic can be verified without hardware. Commands: new, doctor, setup, devices, build, upload, monitor 39 Rust tests (21 unit, 18 integration) Cross-platform: Linux and Windows
This commit is contained in:
196
src/main.rs
Normal file
196
src/main.rs
Normal file
@@ -0,0 +1,196 @@
|
||||
use clap::{Parser, Subcommand};
|
||||
use colored::*;
|
||||
use anyhow::Result;
|
||||
use anvil::version::ANVIL_VERSION;
|
||||
|
||||
mod commands {
|
||||
pub use anvil::commands::*;
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "anvil")]
|
||||
#[command(author = "Eric Ratliff <eric@nxlearn.net>")]
|
||||
#[command(version = ANVIL_VERSION)]
|
||||
#[command(
|
||||
about = "Arduino project generator and build tool - forges clean embedded projects",
|
||||
long_about = None
|
||||
)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Create a new Arduino project
|
||||
New {
|
||||
/// Project name
|
||||
name: Option<String>,
|
||||
|
||||
/// Template to use (basic)
|
||||
#[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
|
||||
Doctor,
|
||||
|
||||
/// Install arduino-cli and required cores
|
||||
Setup,
|
||||
|
||||
/// List connected boards and serial ports
|
||||
Devices,
|
||||
|
||||
/// Compile a sketch (and optionally upload)
|
||||
Build {
|
||||
/// Path to sketch directory
|
||||
sketch: String,
|
||||
|
||||
/// Compile only -- do not upload
|
||||
#[arg(long)]
|
||||
verify: bool,
|
||||
|
||||
/// Open serial monitor after upload
|
||||
#[arg(long)]
|
||||
monitor: bool,
|
||||
|
||||
/// Delete cached build artifacts first
|
||||
#[arg(long)]
|
||||
clean: bool,
|
||||
|
||||
/// Show full compiler output
|
||||
#[arg(long)]
|
||||
verbose: bool,
|
||||
|
||||
/// Serial port (auto-detected if omitted)
|
||||
#[arg(short, long)]
|
||||
port: Option<String>,
|
||||
|
||||
/// Serial monitor baud rate
|
||||
#[arg(short, long)]
|
||||
baud: Option<u32>,
|
||||
|
||||
/// Override Fully Qualified Board Name
|
||||
#[arg(long)]
|
||||
fqbn: Option<String>,
|
||||
},
|
||||
|
||||
/// Upload cached build artifacts (no recompile)
|
||||
Upload {
|
||||
/// Path to sketch directory
|
||||
sketch: String,
|
||||
|
||||
/// Serial port (auto-detected if omitted)
|
||||
#[arg(short, long)]
|
||||
port: Option<String>,
|
||||
|
||||
/// Show full avrdude output
|
||||
#[arg(long)]
|
||||
verbose: bool,
|
||||
|
||||
/// Override Fully Qualified Board Name
|
||||
#[arg(long)]
|
||||
fqbn: Option<String>,
|
||||
},
|
||||
|
||||
/// Open serial monitor
|
||||
Monitor {
|
||||
/// Serial port (auto-detected if omitted)
|
||||
#[arg(short, long)]
|
||||
port: Option<String>,
|
||||
|
||||
/// Baud rate (default: from project config or 115200)
|
||||
#[arg(short, long)]
|
||||
baud: Option<u32>,
|
||||
|
||||
/// Persistent mode: reconnect after upload/reset/replug
|
||||
#[arg(long)]
|
||||
watch: bool,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
#[cfg(windows)]
|
||||
colored::control::set_virtual_terminal(true).ok();
|
||||
|
||||
let cli = Cli::parse();
|
||||
|
||||
print_banner();
|
||||
|
||||
match cli.command {
|
||||
Commands::New { name, template, list_templates } => {
|
||||
if list_templates {
|
||||
commands::new::list_templates()
|
||||
} else if let Some(project_name) = name {
|
||||
commands::new::create_project(
|
||||
&project_name,
|
||||
template.as_deref(),
|
||||
)
|
||||
} else {
|
||||
anyhow::bail!(
|
||||
"Project name required.\n\
|
||||
Usage: anvil new <name>\n\
|
||||
List templates: anvil new --list-templates"
|
||||
);
|
||||
}
|
||||
}
|
||||
Commands::Doctor => {
|
||||
commands::doctor::run_diagnostics()
|
||||
}
|
||||
Commands::Setup => {
|
||||
commands::setup::run_setup()
|
||||
}
|
||||
Commands::Devices => {
|
||||
commands::devices::scan_devices()
|
||||
}
|
||||
Commands::Build {
|
||||
sketch, verify, monitor, clean, verbose,
|
||||
port, baud, fqbn,
|
||||
} => {
|
||||
commands::build::run_build(
|
||||
&sketch, verify, monitor, clean, verbose,
|
||||
port.as_deref(), baud, fqbn.as_deref(),
|
||||
)
|
||||
}
|
||||
Commands::Upload { sketch, port, verbose, fqbn } => {
|
||||
commands::build::run_upload_only(
|
||||
&sketch,
|
||||
port.as_deref(),
|
||||
verbose,
|
||||
fqbn.as_deref(),
|
||||
)
|
||||
}
|
||||
Commands::Monitor { port, baud, watch } => {
|
||||
commands::monitor::run_monitor(
|
||||
port.as_deref(),
|
||||
baud,
|
||||
watch,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_banner() {
|
||||
println!(
|
||||
"{}",
|
||||
"================================================================"
|
||||
.bright_cyan()
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
format!(" Anvil - Arduino Build Tool v{}", ANVIL_VERSION)
|
||||
.bright_cyan()
|
||||
.bold()
|
||||
);
|
||||
println!("{}", " Nexus Workshops LLC".bright_cyan());
|
||||
println!(
|
||||
"{}",
|
||||
"================================================================"
|
||||
.bright_cyan()
|
||||
);
|
||||
println!();
|
||||
}
|
||||
Reference in New Issue
Block a user