use anyhow::{Context, Result};
use console::{style, Emoji};
use std::path::PathBuf;
use std::process::Command;
pub fn build(target: Option<&str>) -> Result<()> {
let project_dir = std::env::current_dir().context("Failed to get current directory")?;
println!();
println!("{} {}", Emoji("🏗️", ""), style("Building release binary").bold());
println!();
let mut args = vec!["build", "--release"];
if let Some(t) = target {
args.push("--message-format=json");
args.push("--target");
args.push(t);
println!(" {} {}", style("Target:").dim(), style(t).cyan());
} else {
args.push("--message-format=json");
}
println!(" {} {}", style("Mode:").dim(), style("release (opt-level=3, lto=true)").cyan());
println!();
let status = Command::new("cargo")
.args(&args)
.current_dir(&project_dir)
.status()
.context("Failed to run cargo build")?;
if !status.success() {
anyhow::bail!("Build failed with exit code: {:?}", status.code());
}
let package_name = project_dir
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_else(|| "app".to_string());
let binary_path = if target.is_some() {
PathBuf::from("target")
.join(target.unwrap())
.join("release")
.join(&package_name)
} else {
PathBuf::from("target")
.join("release")
.join(&package_name)
};
let full_path = project_dir.join(&binary_path);
if full_path.exists() {
let size_kb = std::fs::metadata(&full_path)
.map(|m| m.len() / 1024)
.unwrap_or(0);
println!();
println!("{} {}", Emoji("✅", ""), style("Build successful!").green());
println!(" {} {} ({} KB)", style("Binary:").dim(), full_path.display(), size_kb);
} else {
println!();
println!("{} {}", Emoji("✅", ""), style("Build successful!").green());
println!(" {} (in {})", style("Binary:").dim(), binary_path.display());
}
println!();
Ok(())
}