1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use anyhow::Result;

use crate::testing::{config::ComposeTestConfig, config::Environment, state};

pub fn exec(integration: &Option<String>, path: &str) -> Result<()> {
    match integration {
        None => {
            let entries = ComposeTestConfig::collect_all(path)?;
            let width = entries
                .keys()
                .fold(16, |width, entry| width.max(entry.len()));
            println!("{:width$}  Environment Name(s)", "Integration Name");
            println!("{:width$}  -------------------", "----------------");
            for (integration, config) in entries {
                let envs_dir = state::EnvsDir::new(&integration);
                let active_env = envs_dir.active()?;
                let environments = config
                    .environments()
                    .keys()
                    .map(|environment| format(&active_env, environment))
                    .collect::<Vec<_>>()
                    .join("  ");
                println!("{integration:width$}  {environments}");
            }
        }
        Some(integration) => {
            let (_test_dir, config) = ComposeTestConfig::load(path, integration)?;
            let envs_dir = state::EnvsDir::new(integration);
            let active_env = envs_dir.active()?;

            if let Some(args) = &config.args {
                println!("Test args: {}", args.join(" "));
            } else {
                println!("Test args: N/A");
            }

            if config.features.is_empty() {
                println!("Features: N/A");
            } else {
                println!("Features: {}", config.features.join(","));
            }

            println!(
                "Test filter: {}",
                config.test_filter.as_deref().unwrap_or("N/A")
            );

            println!("Environment:");
            print_env("  ", &config.env);
            println!("Runner:");
            println!("  Environment:");
            print_env("    ", &config.runner.env);
            println!("  Volumes:");
            if config.runner.volumes.is_empty() {
                println!("    N/A");
            } else {
                for (target, mount) in &config.runner.volumes {
                    println!("    {target} => {mount}");
                }
            }
            println!(
                "  Needs docker socket: {}",
                config.runner.needs_docker_socket
            );

            println!("Environments:");
            for environment in config.environments().keys() {
                println!("  {}", format(&active_env, environment));
            }
        }
    }
    Ok(())
}

fn format(active_env: &Option<String>, environment: &str) -> String {
    match active_env {
        Some(active) if active == environment => format!("{environment} (active)"),
        _ => environment.into(),
    }
}

fn print_env(prefix: &str, environment: &Environment) {
    if environment.is_empty() {
        println!("{prefix}N/A");
    } else {
        for (key, value) in environment {
            match value {
                Some(value) => println!("{prefix}{key}={value:?}"),
                None => println!("{prefix}{key} (passthrough)"),
            }
        }
    }
}