proto_cli 0.57.3

A multi-language version manager, a unified toolchain.
use crate::error::ProtoCliError;
use crate::session::ProtoSession;
use clap::Args;
use iocraft::prelude::element;
use proto_core::{
    PinLocation, ProtoConfig, ToolContext, ToolSpec, UnresolvedVersionSpec, cfg, is_alias_name,
};
use starbase::AppResult;
use starbase_console::ui::*;
use starbase_styles::encode_style_tags;

#[derive(Args, Clone, Debug)]
pub struct AliasArgs {
    #[arg(required = true, help = "Tool to alias")]
    context: ToolContext,

    #[arg(required = true, help = "Alias name")]
    alias: String,

    #[arg(required = true, help = "Version specification to alias")]
    spec: ToolSpec,

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

#[tracing::instrument(skip_all)]
pub async fn alias(session: ProtoSession, args: AliasArgs) -> AppResult {
    if let UnresolvedVersionSpec::Alias(inner_alias) = &args.spec.req
        && args.alias == inner_alias
    {
        return Err(ProtoCliError::AliasNoMatchingToVersion.into());
    }

    if !is_alias_name(&args.alias) {
        return Err(ProtoCliError::AliasInvalidName {
            alias: args.alias.clone(),
        }
        .into());
    }

    let tool = session.load_tool(&args.context).await?;

    let config_path = ProtoConfig::update_document(tool.proto.get_config_dir(args.to), |doc| {
        let tools = doc["tools"].or_insert(cfg::implicit_table());
        let record = tools[tool.context.as_str()].or_insert(cfg::implicit_table());
        let aliases = record["aliases"].or_insert(cfg::implicit_table());

        aliases[&args.alias] = cfg::value(args.spec.to_string());
    })?;

    session.console.render(element! {
        Notice(variant: Variant::Success) {
            StyledText(
                content: format!(
                    "Added <id>{}</id> alias <id>{}</id> <mutedlight>(with specification <versionalt>{}</versionalt>)</mutedlight> to config <path>{}</path>",
                    args.context,
                    args.alias,
                    encode_style_tags(args.spec.to_string()),
                    config_path.display()
                ),
            )
        }
    })?;

    Ok(None)
}