vdev/commands/compose_tests/
show.rs

1use anyhow::Result;
2use std::collections::HashSet;
3
4use crate::{testing::config::ComposeTestConfig, utils::environment::Environment};
5
6use super::active_projects::{find_active_environment, load_active_projects};
7
8pub fn exec(integration: Option<&String>, path: &str) -> Result<()> {
9    let show = Show::new(path)?;
10    match integration {
11        None => show.show_all(),
12        Some(integration) => show.show_one(integration),
13    }
14}
15
16/// Print only the environment names for a single integration, one per line.
17pub fn exec_environments_only(integration: &str, path: &str) -> Result<()> {
18    let (_test_dir, config) = ComposeTestConfig::load(path, integration)?;
19    for environment in config.environments().keys() {
20        println!("{environment}");
21    }
22    Ok(())
23}
24
25struct Show {
26    path: String,
27    active_projects: HashSet<String>,
28}
29
30impl Show {
31    fn new(path: &str) -> Result<Self> {
32        Ok(Self {
33            path: path.to_string(),
34            active_projects: load_active_projects()?,
35        })
36    }
37
38    fn show_all(&self) -> Result<()> {
39        let entries = ComposeTestConfig::collect_all(&self.path)?;
40
41        let width = entries
42            .keys()
43            .fold(16, |width, entry| width.max(entry.len()));
44        println!("{:width$}  Environment Name(s)", "Integration Name");
45        println!("{:width$}  -------------------", "----------------");
46        for (integration, config) in entries {
47            let prefix = format!("vector-{}-{integration}-", self.path);
48            let active_env = find_active_environment(&self.active_projects, &prefix, &config);
49            let environments = config
50                .environments()
51                .keys()
52                .map(|environment| format_env(active_env.as_ref(), environment))
53                .collect::<Vec<_>>()
54                .join("  ");
55            println!("{integration:width$}  {environments}");
56        }
57        Ok(())
58    }
59
60    fn show_one(&self, integration: &str) -> Result<()> {
61        let (_test_dir, config) = ComposeTestConfig::load(&self.path, integration)?;
62        let prefix = format!("vector-{}-{integration}-", self.path);
63        let active_env = find_active_environment(&self.active_projects, &prefix, &config);
64
65        if let Some(args) = &config.args {
66            println!("Test args: {}", args.join(" "));
67        } else {
68            println!("Test args: N/A");
69        }
70
71        if config.features.is_empty() {
72            println!("Features: N/A");
73        } else {
74            println!("Features: {}", config.features.join(","));
75        }
76
77        println!(
78            "Test filter: {}",
79            config.test_filter.as_deref().unwrap_or("N/A")
80        );
81
82        println!("Environment:");
83        print_env("  ", &config.env);
84        println!("Runner:");
85        println!("  Environment:");
86        print_env("    ", &config.runner.env);
87        println!("  Volumes:");
88        if config.runner.volumes.is_empty() {
89            println!("    N/A");
90        } else {
91            for (target, mount) in &config.runner.volumes {
92                println!("    {target} => {mount}");
93            }
94        }
95        println!(
96            "  Needs docker socket: {}",
97            config.runner.needs_docker_socket
98        );
99
100        println!("Environments:");
101        for environment in config.environments().keys() {
102            println!("  {}", format_env(active_env.as_ref(), environment));
103        }
104
105        Ok(())
106    }
107}
108
109fn print_env(prefix: &str, environment: &Environment) {
110    if environment.is_empty() {
111        println!("{prefix} N/A");
112    } else {
113        for (key, value) in environment {
114            match value {
115                Some(value) => println!("{prefix}{key}={value:?}"),
116                None => println!("{prefix}{key} (passthrough)"),
117            }
118        }
119    }
120}
121
122fn format_env(active_env: Option<&String>, environment: &str) -> String {
123    match active_env {
124        Some(active) if active == environment => format!("{environment} (active)"),
125        _ => environment.into(),
126    }
127}