flyboat 2.0.0

Container environment manager for development
Documentation
use crate::Result;
use crate::cli::ListArgs;
use crate::environment::EnvironmentManager;
use colored::Colorize;
use serde::Serialize;

#[derive(Serialize)]
struct EnvInfo {
    name: String,
    description: String,
    aliases: Vec<String>,
    network: String,
    disk_access: String,
}

pub fn execute_list(args: &ListArgs, verbose: bool) -> Result<()> {
    if verbose {
        eprintln!("Listing environments");
    }

    let manager = EnvironmentManager::new()?;
    let env_dir = manager.paths().env_dir();

    if manager.is_empty() {
        eprintln!(
            "{}: No environments found in {}",
            "Warning".yellow(),
            env_dir.display()
        );
        eprintln!();
        eprintln!("To create an environment:");
        eprintln!(
            "  1. Create a folder: mkdir -p {}/<name>",
            env_dir.display()
        );
        eprintln!("  2. Add a Dockerfile and dev_env.yaml");
        return Ok(());
    }

    let mut envs: Vec<EnvInfo> = manager
        .list()
        .iter()
        .map(|env| EnvInfo {
            name: env.full_name(),
            description: env.config.description.clone(),
            aliases: env.config.aliases.clone(),
            network: env.config.settings.network.clone(),
            disk_access: env.config.settings.disk_access.clone(),
        })
        .collect();
    envs.sort_by(|a, b| a.name.cmp(&b.name));

    if args.json {
        let json = serde_json::to_string_pretty(&envs)?;
        println!("{}", json);
    } else {
        println!(
            "{:<28} {:<35} {:<10} {:<12} {}",
            "NAME".bold(),
            "DESCRIPTION".bold(),
            "NETWORK".bold(),
            "DISK".bold(),
            "ALIASES".bold()
        );
        println!("{}", "-".repeat(105));

        for env in envs {
            let aliases = if env.aliases.is_empty() {
                "-".to_string()
            } else {
                env.aliases.join(", ")
            };

            let desc = if env.description.len() > 33 {
                format!("{}...", &env.description[..30])
            } else {
                env.description
            };

            println!(
                "{:<28} {:<35} {:<10} {:<12} {}",
                env.name.green(),
                desc,
                env.network,
                env.disk_access,
                aliases.dimmed()
            );
        }

        eprintln!();
        eprintln!("To create an environment:");
        eprintln!(
            "  1. Create a folder: mkdir -p {}/<name>",
            env_dir.display()
        );
        eprintln!("  2. Add a Dockerfile and dev_env.yaml");

        if verbose {
            eprintln!("\nName Env Mapping:");
            let display_max = 5;

            let mut reference_mapping = manager.reference_mapping();
            reference_mapping.sort_keys();

            for (key, envs) in reference_mapping {
                let x_more = if envs.len() > display_max {
                    format!(", .. and {} more", envs.len() - display_max)
                } else {
                    "".to_owned()
                };
                eprintln!(
                    "  - {key:<25} -> [{}{}]",
                    envs.iter()
                        .map(|env| env.full_name())
                        .take(display_max)
                        .collect::<Vec<_>>()
                        .join(", "),
                    x_more
                );
            }
        }
    }

    Ok(())
}