Skip to main content

alef_e2e/
format.rs

1//! Post-generation formatter support for e2e test projects.
2//!
3//! Reads formatter commands from `E2eConfig.format` and runs them for each
4//! language that had files generated. The `{dir}` placeholder in the command
5//! is replaced with the actual output directory.
6
7use crate::config::E2eConfig;
8use alef_core::backend::GeneratedFile;
9use std::collections::HashSet;
10use std::path::Path;
11use tracing::warn;
12
13/// Run per-language formatters for all languages that had files generated.
14///
15/// For each language present in `files`, looks up `e2e_config.format[lang]` and
16/// runs the command with `{dir}` replaced by `{output}/{lang}`.
17/// Failures are logged as warnings and do not abort the process.
18pub fn run_formatters(files: &[GeneratedFile], e2e_config: &E2eConfig) {
19    if e2e_config.format.is_empty() {
20        return;
21    }
22
23    // Collect the set of languages that had files generated by inspecting
24    // file paths. E2e files are written to `{output}/{lang}/...`, so the
25    // first path component after the output prefix is the language name.
26    let output_prefix = Path::new(&e2e_config.output);
27    let languages: HashSet<String> = files
28        .iter()
29        .filter_map(|f| {
30            let remainder = f.path.strip_prefix(output_prefix).ok()?;
31            let first = remainder.components().next()?;
32            Some(first.as_os_str().to_string_lossy().into_owned())
33        })
34        .collect();
35
36    for (lang, cmd_template) in &e2e_config.format {
37        if !languages.contains(lang.as_str()) {
38            continue;
39        }
40
41        let dir = format!("{}/{}", e2e_config.output, lang);
42        let cmd = cmd_template.replace("{dir}", &dir);
43
44        eprintln!("  Formatting {lang}: {cmd}");
45        let status = std::process::Command::new("sh").args(["-c", &cmd]).status();
46
47        match status {
48            Ok(s) if s.success() => {}
49            Ok(s) => {
50                warn!("Formatter for {lang} exited with {s}: {cmd}");
51            }
52            Err(e) => {
53                warn!("Failed to run formatter for {lang}: {e}");
54            }
55        }
56    }
57}