pub mod error;
pub mod plan;
pub mod source;
pub mod transform;
use crate::config::ProjectConfig;
use fs_extra::dir::{copy, CopyOptions};
use std::{fs, path::Path};
pub use error::EngineError;
pub fn run(config: &ProjectConfig, destination: &Path) -> Result<(), EngineError> {
println!("🚀 Engine starting...");
let final_project_path = destination.join(&config.project_name);
if final_project_path.exists() {
if !final_project_path.is_dir() {
return Err(EngineError::FileSystem(format!(
"Destination '{}' exists but it is not a directory.",
final_project_path.display()
)));
}
let is_empty = final_project_path.read_dir()?.next().is_none();
if !is_empty {
return Err(EngineError::FileSystem(format!(
"Destination directory '{}' already exists and is not empty. Aborting.",
final_project_path.display()
)));
}
println!("✔️ Destination directory exists and is empty. Using it.");
} else {
println!("✔️ Creating destination directory: {}", final_project_path.display());
fs::create_dir_all(&final_project_path)?; }
let temp_dir = source::fetch()?;
println!("📝 Building transformation plan...");
let plan = plan::build_plan(config)?;
println!("⚙️ Applying transformations...");
transform::execute(&plan, temp_dir.path())?;
println!(
"🚚 Copying project files to {}...",
final_project_path.display()
);
let mut options = CopyOptions::new();
options.content_only = true;
copy(temp_dir.path(), &final_project_path, &options)
.map_err(|e| EngineError::FinalCopyFailed(format!("Failed to copy project: {}", e)))?;
println!(
"\n✅ Project '{}' created successfully!",
config.project_name
);
Ok(())
}