use crate::version::bump_version;
use std::fs;
use std::path::Path;
use xshell::{Shell, cmd};
pub fn build() -> Result<(), Box<dyn std::error::Error>> {
let sh = Shell::new()?;
let cargo_content = fs::read_to_string("Cargo.toml")?;
let mut cargo_toml: toml::Value = cargo_content.parse()?;
let (namespace, mode, project_name): (String, String, String) = {
let spruce = cargo_toml
.get("spruce")
.ok_or("No [spruce] section found in Cargo.toml. Please run 'spruce init' first.")?;
let ns = spruce
.get("namespace")
.and_then(|n| n.as_str())
.ok_or("No namespace found in [spruce] section. Please run 'spruce init' first.")?
.to_string();
let md = spruce
.get("mode")
.and_then(|m| m.as_str())
.unwrap_or("alpha")
.to_string();
let pn = cargo_toml["package"]["name"]
.as_str()
.ok_or("Could not find package name in Cargo.toml")?
.to_string();
(ns, md, pn)
};
if !Path::new("Dockerfile").exists() {
eprintln!("Error: Dockerfile not found. Please run 'spruce init' first.");
std::process::exit(1);
}
let current_version = cargo_toml["package"]["version"]
.as_str()
.ok_or("Could not find version in Cargo.toml")?
.to_string();
let new_version = bump_version(¤t_version, &mode)?;
cargo_toml["package"]["version"] = toml::Value::String(new_version.clone());
let updated_cargo = toml::to_string_pretty(&cargo_toml)?;
fs::write("Cargo.toml", updated_cargo)?;
println!(
"[OK] Updated Cargo.toml version: {} -> {}",
current_version, new_version
);
println!(" (using '{}' mode)", mode);
let full_image_name = format!("{}/{}:{}", namespace, project_name, new_version);
let latest_image_name = format!("{}/{}:latest", namespace, project_name);
println!("\nBuilding Docker image: {}", full_image_name);
cmd!(
sh,
"docker build -t {full_image_name} -t {latest_image_name} ."
)
.run()?;
println!("[OK] Successfully built image: {}", full_image_name);
println!("[OK] Tagged as: {}", latest_image_name);
Ok(())
}