use anyhow::Result;
pub(super) fn run_required_post_builds(
languages: &[crate::core::config::Language],
config: &crate::core::config::ResolvedCrateConfig,
base_dir: &std::path::Path,
) -> Result<()> {
let mut failures: Vec<String> = Vec::new();
for &language in languages {
let Some(backend) = crate::cli::registry::try_get_backend(language) else {
continue;
};
let Some(build_config) = backend.build_config_with_config(config) else {
continue;
};
if build_config.post_build.is_empty() {
continue;
}
tracing::info!(" [{language}] running post-build...");
match crate::cli::pipeline::run_post_build(language, &build_config, config, base_dir) {
Ok(()) => tracing::info!(" [{language}] post-build processing complete"),
Err(error) => {
tracing::warn!("[{language}] post-build failed, continuing with remaining languages: {error:#}");
failures.push(format!("[{language}] {error:#}"));
}
}
}
if failures.is_empty() {
return Ok(());
}
anyhow::bail!(
"post-build failed for {} of {} language(s): {}",
failures.len(),
languages.len(),
failures.join("; ")
);
}
#[cfg(test)]
mod tests {
use super::run_required_post_builds;
use crate::core::config::Language;
#[test]
fn required_post_build_failure_is_propagated_with_language_context() {
let directory = tempfile::tempdir().expect("temporary project");
let error = run_required_post_builds(
&[Language::Swift],
&crate::core::config::ResolvedCrateConfig::default(),
directory.path(),
)
.expect_err("missing Swift build project must fail");
assert!(error.to_string().contains("swift"));
}
#[test]
fn a_failing_language_does_not_abort_the_remaining_post_builds() {
let directory = tempfile::tempdir().expect("temporary project");
let error = run_required_post_builds(
&[Language::Swift, Language::Dart],
&crate::core::config::ResolvedCrateConfig::default(),
directory.path(),
)
.expect_err("missing build projects for both languages must fail");
let message = error.to_string();
assert!(message.contains("swift"), "got: {message}");
assert!(message.contains("dart"), "got: {message}");
assert!(message.contains("2 of 2"), "got: {message}");
}
}