use crate::context::CliContext;
use crate::paths;
use crate::types::ProjectConfig;
use anyhow::Result;
pub fn build_nodes(_ctx: &mut CliContext) -> Result<()> {
println!("⚡ Nodes resolved on demand (no build required)");
println!();
build_local_project_nodes()?;
Ok(())
}
fn build_local_project_nodes() -> Result<()> {
use crate::types::NodeSource;
use std::process::Command;
let config_path = std::path::Path::new(paths::PROJECT_CONFIG);
if !config_path.exists() {
return Ok(());
}
let config_content = std::fs::read_to_string(config_path)?;
let config: ProjectConfig = serde_json::from_str(&config_content)?;
let local_nodes: Vec<_> = config
.nodes
.get_node_specs()
.into_iter()
.filter(|spec| spec.source == NodeSource::Project)
.collect();
if local_nodes.is_empty() {
return Ok(());
}
println!("🔨 Pre-building local project nodes...");
for node_spec in &local_nodes {
let node_name = &node_spec.name;
let node_dir = std::path::Path::new("nodes").join(node_name);
if !node_dir.exists() {
tracing::warn!("Local node directory not found: nodes/{}", node_name);
continue;
}
println!(" Building {}...", node_name);
let output = Command::new("cargo")
.args(["build", "-p", node_name])
.output()
.map_err(|e| anyhow::anyhow!("Failed to run cargo build for {}: {}", node_name, e))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(anyhow::anyhow!(
"Failed to build local node '{}': {}",
node_name,
stderr
));
}
}
println!("✅ Local nodes built");
println!();
Ok(())
}