use std::path::Path;
use arcature_templates::{Database, Frontend as TemplateFrontend, Preset};
use crate::cli::NewOptions;
use crate::error::CommandError;
use crate::project::Frontend;
use crate::release::{self, ReleaseError};
const PLATFORM_MANIFEST: &str = "platform/2026.1.toml";
pub(crate) fn execute(options: NewOptions) -> Result<(), CommandError> {
let frontend = match Frontend::from(options.frontend) {
Frontend::React => TemplateFrontend::React,
Frontend::Vue => TemplateFrontend::Vue,
};
let database = if options.no_db {
Database::Disabled
} else {
Database::Enabled
};
let preset = Preset::new(frontend, database);
let (arcature_version, client_version) = read_certified_versions()?;
arcature_templates::generate(
&options.destination,
preset,
&arcature_version,
&client_version,
)?;
println!("created {}", options.destination.display());
println!(" certified platform: arcature v{arcature_version}");
println!("next: cd {} && arc dev", options.destination.display());
Ok(())
}
fn read_certified_versions() -> Result<(String, String), CommandError> {
let path = Path::new(PLATFORM_MANIFEST);
if path.exists() {
let text = std::fs::read_to_string(path).map_err(|e| {
CommandError::Release(ReleaseError::Validation(vec![release::Diagnostic {
crate_name: "platform".to_string(),
message: format!("cannot read Platform manifest {PLATFORM_MANIFEST}: {e}"),
}]))
})?;
let arcature_version = text.lines().find_map(|line| {
let trimmed = line.trim();
trimmed
.strip_prefix("arcature = ")
.map(|rest| rest.trim().trim_matches('"').to_string())
});
let client_version = text.lines().find_map(|line| {
let trimmed = line.trim();
trimmed
.strip_prefix("arcature_client_version = ")
.map(|rest| rest.trim().trim_matches('"').to_string())
});
if let (Some(arcature_version), Some(client_version)) = (arcature_version, client_version) {
return Ok((arcature_version, client_version));
}
}
let contract = crate::stack::load();
Ok((
contract.snapshot.arcature_version,
contract.snapshot.arcature_client_version,
))
}