proto_cli 0.59.0

A multi-language version manager, a unified toolchain.
use crate::error::ProtoCliError;
use crate::session::{ProtoSession, SessionResult};
use clap::Args;
use proto_core::{Id, PROTO_CONFIG_NAME, PinLocation, PluginType, ProtoConfig};
use starbase_console::ui::*;
use tracing::instrument;

#[derive(Args, Clone, Debug)]
pub struct PluginRemoveArgs {
    #[arg(required = true, help = "ID of plugin")]
    id: Id,

    #[arg(long, default_value_t, help = "Location of .prototools to remove from")]
    from: PinLocation,

    #[arg(long = "type", default_value_t, help = "The type of plugin to remove")]
    ty: PluginType,
}

#[instrument(skip(session))]
pub async fn remove(session: ProtoSession, args: PluginRemoveArgs) -> SessionResult {
    let config_dir = session.env.get_config_dir(args.from);
    let config_path = config_dir.join(PROTO_CONFIG_NAME);

    if !config_path.exists() {
        return Err(ProtoCliError::MissingToolsConfigInCwd { path: config_path }.into());
    }

    let config_path = ProtoConfig::update_document(config_dir, |doc| {
        let key = if args.ty == PluginType::Backend {
            "backends"
        } else {
            "tools"
        };

        if let Some(plugins) = doc.get_mut("plugins").and_then(|item| item.as_table_mut()) {
            plugins.remove(&args.id);

            if let Some(table) = plugins.get_mut(key).and_then(|item| item.as_table_mut()) {
                table.remove(&args.id);

                if table.is_empty() {
                    plugins.remove(key);
                }
            }

            if plugins.is_empty() {
                doc.as_table_mut().remove("plugins");
            }
        }

        if let Some(tools) = doc.get_mut("tools").and_then(|item| item.as_table_mut()) {
            tools.remove(&args.id);

            if tools.is_empty() {
                doc.as_table_mut().remove("tools");
            }
        }

        doc.as_table_mut().remove(&args.id);
    })?;

    session.console.notice(
        Variant::Success,
        format!(
            "Removed <id>{}</id> plugin from config <path>{}</path>",
            args.id,
            config_path.display(),
        ),
    )?;

    Ok(None)
}