Skip to main content

espforge_lib/compile/
mod.rs

1use anyhow::{Context, Result};
2use std::fs;
3use std::path::{Path, PathBuf};
4
5use crate::parse::ConfigParser;
6use espforge_common::EspforgeConfiguration;
7
8// Declare sub-modules
9mod assets;
10mod dependencies;
11mod generators;
12
13pub fn compile_project(config_path: &Path) -> Result<()> {
14    let compiler = ProjectCompiler::new(config_path)?;
15    compiler.run()
16}
17
18struct ProjectCompiler {
19    base_dir: PathBuf,
20    model: EspforgeConfiguration,
21}
22
23impl ProjectCompiler {
24    fn new(config_path: &Path) -> Result<Self> {
25        println!("🔍 Parsing configuration...");
26        let content = fs::read_to_string(config_path).context(format!(
27            "Failed to read configuration file: {}",
28            config_path.display()
29        ))?;
30
31        let parser = ConfigParser::new();
32        let model = parser.parse(&content)?;
33
34        let base_dir = config_path
35            .parent()
36            .unwrap_or_else(|| Path::new("."))
37            .to_path_buf();
38
39        Ok(Self { base_dir, model })
40    }
41
42    fn run(&self) -> Result<()> {
43        println!("   Project: {}", self.model.get_name());
44        println!("   Chip:    {}", self.model.get_chip());
45
46        println!("🔨 Generating artifacts...");
47
48        // Step 1: Scaffold
49        generators::generate_scaffold(&self.model)?;
50
51        let project_dir = self.resolve_project_dir()?;
52        let src_dir = project_dir.join("src");
53
54        // Step 2: Dependencies
55        dependencies::add_dependencies(&project_dir)?;
56
57        // Step 3: Assets (Wokwi, Platform, User App)
58        assets::copy_wokwi_files(&self.base_dir, &project_dir)?;
59        assets::provision_platform_assets(&project_dir, &src_dir)?;
60        assets::inject_app_code(&self.base_dir, &src_dir)?;
61
62        // Step 4: Code Generation
63        generators::generate_component_code(&src_dir, &self.model)?;
64        generators::setup_library_structure(&src_dir)?;
65        generators::generate_entry_point(&src_dir, &self.model)?;
66
67        println!("✨ Project compiled successfully!");
68        Ok(())
69    }
70
71    fn resolve_project_dir(&self) -> Result<PathBuf> {
72        let current_dir = std::env::current_dir().context("Failed to get current directory")?;
73        Ok(current_dir.join(self.model.get_name()))
74    }
75}