use crate::session::{ProtoSession, SessionResult};
use clap::Args;
use proto_core::{Id, PinLocation, PluginLocator, PluginType, ProtoConfig, cfg};
use starbase_console::ui::*;
use tracing::instrument;
#[derive(Args, Clone, Debug)]
pub struct PluginAddArgs {
#[arg(required = true, help = "ID of plugin")]
id: Id,
#[arg(required = true, help = "Locator string to find and load the plugin")]
plugin: PluginLocator,
#[arg(long, default_value_t, help = "Location of .prototools to add to")]
to: PinLocation,
#[arg(long = "type", default_value_t, help = "The type of plugin to add")]
ty: PluginType,
}
#[instrument(skip(session))]
pub async fn add(session: ProtoSession, args: PluginAddArgs) -> SessionResult {
let config_path = ProtoConfig::update_document(session.env.get_config_dir(args.to), |doc| {
let key = if args.ty == PluginType::Backend {
"backends"
} else {
"tools"
};
if doc.contains_key("plugins")
&& doc["plugins"].as_table().is_some_and(|table| {
!table.contains_key("backends") && !table.contains_key("tools")
})
{
let existing = doc["plugins"].clone();
doc.remove("plugins");
let plugins = doc["plugins"].or_insert(cfg::implicit_table());
plugins["tools"] = existing;
}
let plugins = doc["plugins"].or_insert(cfg::implicit_table());
let table = plugins[key].or_insert(cfg::table());
table[args.id.as_str()] = cfg::value(args.plugin.to_string());
})?;
#[cfg(not(debug_assertions))]
{
use proto_core::ToolContext;
use proto_core::reporter::NoticeOutput;
let tool = proto_core::load_tool_from_locator(
ToolContext::parse(&args.id)?,
&session.env,
&args.plugin,
)
.await?;
if !tool.metadata.deprecations.is_empty() {
session.console.notice_with(NoticeOutput {
variant: Variant::Info,
title: Some("Deprecations".into()),
items: tool.metadata.deprecations,
..Default::default()
})?;
}
}
session.console.notice(
Variant::Success,
format!(
"Added <id>{}</id> plugin to config <path>{}</path>",
args.id,
config_path.display(),
),
)?;
Ok(None)
}