| @@ -2,8 +2,9 @@ use dora_core::{ | |||
| config::OperatorId, | |||
| descriptor::{Descriptor, DescriptorExt, NodeExt, SINGLE_OPERATOR_DEFAULT_ID}, | |||
| }; | |||
| use dora_message::descriptor::EnvValue; | |||
| use eyre::{eyre, Context}; | |||
| use std::{path::Path, process::Command}; | |||
| use std::{collections::BTreeMap, path::Path, process::Command}; | |||
| use crate::resolve_dataflow; | |||
| @@ -22,44 +23,59 @@ pub fn build(dataflow: String, uv: bool) -> eyre::Result<()> { | |||
| for node in descriptor.nodes { | |||
| match node.kind()? { | |||
| dora_core::descriptor::NodeKind::Standard(_) => { | |||
| run_build_command(node.build.as_deref(), working_dir, uv).with_context(|| { | |||
| format!("build command failed for standard node `{}`", node.id) | |||
| })? | |||
| run_build_command(node.build.as_deref(), working_dir, uv, node.env.clone()) | |||
| .with_context(|| { | |||
| format!("build command failed for standard node `{}`", node.id) | |||
| })? | |||
| } | |||
| dora_core::descriptor::NodeKind::Runtime(runtime_node) => { | |||
| for operator in &runtime_node.operators { | |||
| run_build_command(operator.config.build.as_deref(), working_dir, uv) | |||
| .with_context(|| { | |||
| format!( | |||
| "build command failed for operator `{}/{}`", | |||
| node.id, operator.id | |||
| ) | |||
| })?; | |||
| } | |||
| } | |||
| dora_core::descriptor::NodeKind::Custom(custom_node) => { | |||
| run_build_command(custom_node.build.as_deref(), working_dir, uv).with_context( | |||
| || format!("build command failed for custom node `{}`", node.id), | |||
| )? | |||
| } | |||
| dora_core::descriptor::NodeKind::Operator(operator) => { | |||
| run_build_command(operator.config.build.as_deref(), working_dir, uv).with_context( | |||
| || { | |||
| run_build_command( | |||
| operator.config.build.as_deref(), | |||
| working_dir, | |||
| uv, | |||
| node.env.clone(), | |||
| ) | |||
| .with_context(|| { | |||
| format!( | |||
| "build command failed for operator `{}/{}`", | |||
| node.id, | |||
| operator.id.as_ref().unwrap_or(&default_op_id) | |||
| node.id, operator.id | |||
| ) | |||
| }, | |||
| )? | |||
| })?; | |||
| } | |||
| } | |||
| dora_core::descriptor::NodeKind::Custom(custom_node) => run_build_command( | |||
| custom_node.build.as_deref(), | |||
| working_dir, | |||
| uv, | |||
| node.env.clone(), | |||
| ) | |||
| .with_context(|| format!("build command failed for custom node `{}`", node.id))?, | |||
| dora_core::descriptor::NodeKind::Operator(operator) => run_build_command( | |||
| operator.config.build.as_deref(), | |||
| working_dir, | |||
| uv, | |||
| node.env.clone(), | |||
| ) | |||
| .with_context(|| { | |||
| format!( | |||
| "build command failed for operator `{}/{}`", | |||
| node.id, | |||
| operator.id.as_ref().unwrap_or(&default_op_id) | |||
| ) | |||
| })?, | |||
| } | |||
| } | |||
| Ok(()) | |||
| } | |||
| fn run_build_command(build: Option<&str>, working_dir: &Path, uv: bool) -> eyre::Result<()> { | |||
| fn run_build_command( | |||
| build: Option<&str>, | |||
| working_dir: &Path, | |||
| uv: bool, | |||
| envs: Option<BTreeMap<String, EnvValue>>, | |||
| ) -> eyre::Result<()> { | |||
| if let Some(build) = build { | |||
| let lines = build.lines().collect::<Vec<_>>(); | |||
| for build_line in lines { | |||
| @@ -76,6 +92,15 @@ fn run_build_command(build: Option<&str>, working_dir: &Path, uv: bool) -> eyre: | |||
| Command::new(program) | |||
| }; | |||
| cmd.args(split); | |||
| // Inject Environment Variables | |||
| if let Some(envs) = envs.clone() { | |||
| for (key, value) in envs { | |||
| let value = value.to_string(); | |||
| cmd.env(key, value); | |||
| } | |||
| } | |||
| cmd.current_dir(working_dir); | |||
| let exit_status = cmd | |||
| .status() | |||