"""
Section compilation for ModuFlow.
This module provides functionality for compiling sections.
"""
import os
import shutil
from pathlib import Path
from typing import Dict, List, Any, Optional, Set
from moduflow.core.config import ConfigManager
from moduflow.core.paths import PathManager
from moduflow.handlers.file_handler import FileHandler
[docs]
class SectionCompiler:
"""Compiler for sections."""
def __init__(self, project_root: Optional[str] = None):
"""Initialize the section compiler.
Args:
project_root: Path to the project root. If None, uses current directory.
"""
self.project_root = Path(project_root or os.getcwd()).resolve()
self.config_manager = ConfigManager(project_root)
self.path_manager = PathManager(project_root)
self.file_handler = FileHandler(project_root)
[docs]
def compile_section(self, name: str) -> Path:
"""Compile a section.
Args:
name: Name of the section.
Returns:
Path to the compiled section.
Raises:
FileNotFoundError: If the section doesn't exist.
"""
# Read section configuration
section_config = self.config_manager.read_section_config(name)
# Create output directory
section_dir = self.path_manager.get_section_output_dir(name)
if section_dir.exists():
shutil.rmtree(section_dir)
section_dir.mkdir(parents=True)
# Copy files
copied_files = self.file_handler.copy_files(
section_config.get('files', []),
self.project_root,
section_dir,
skip_missing=True
)
# Copy design files
design_files = list(self.path_manager.design_dir.glob(f"{name}*"))
if design_files:
design_output_dir = section_dir / "design"
design_output_dir.mkdir(exist_ok=True)
for design_file in design_files:
try:
shutil.copy2(design_file, design_output_dir / design_file.name)
except Exception as e:
print(f"Warning: Could not copy design file {design_file}: {e}")
# Create a manifest file
manifest = {
'name': name,
'description': section_config.get('description', ''),
'files': copied_files,
'design_files': [f.name for f in design_files]
}
manifest_path = section_dir / "manifest.yaml"
self.file_handler.save_yaml(manifest, manifest_path)
return section_dir
[docs]
def compile_all_sections(self) -> Dict[str, Path]:
"""Compile all sections.
Returns:
Dictionary mapping section names to their compiled directories.
"""
# Clear the output directory
if self.path_manager.output_dir.exists():
shutil.rmtree(self.path_manager.output_dir)
self.path_manager.output_dir.mkdir()
# Get all sections
sections = self.config_manager.read_all_section_configs()
# Compile each section
compiled_sections = {}
for section_name in sections:
try:
compiled_dir = self.compile_section(section_name)
compiled_sections[section_name] = compiled_dir
except Exception as e:
print(f"Error compiling section '{section_name}': {e}")
return compiled_sections
[docs]
def save_yaml(self, data: Dict[str, Any], file_path: Path) -> None:
"""Save data to a YAML file.
Args:
data: Dictionary to save.
file_path: Path to the YAML file.
"""
import yaml
# Ensure parent directory exists
file_path.parent.mkdir(exist_ok=True, parents=True)
with open(file_path, 'w') as f:
yaml.dump(data, f, default_flow_style=False, sort_keys=False)