use crate::commands::{
tool::{AddToolArgs, ListToolPluginsArgs, ListToolsArgs, RemoveToolArgs, ToolInfoArgs},
AliasArgs, BinArgs, CleanArgs, CompletionsArgs, InstallArgs, InstallGlobalArgs, ListArgs,
ListGlobalArgs, ListRemoteArgs, MigrateArgs, OutdatedArgs, PinArgs, RunArgs, SetupArgs,
UnaliasArgs, UninstallArgs, UninstallGlobalArgs,
};
use clap::builder::styling::{Color, Style, Styles};
use clap::{Parser, Subcommand, ValueEnum};
use starbase_styles::color::Color as ColorType;
use std::fmt::{Display, Error, Formatter};
#[derive(ValueEnum, Clone, Debug, Default)]
pub enum LogLevel {
Off,
Error,
Warn,
#[default]
Info,
Debug,
Trace,
}
impl Display for LogLevel {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(
f,
"{}",
match self {
LogLevel::Off => "off",
LogLevel::Error => "error",
LogLevel::Warn => "warn",
LogLevel::Info => "info",
LogLevel::Debug => "debug",
LogLevel::Trace => "trace",
}
)?;
Ok(())
}
}
fn fg(ty: ColorType) -> Style {
Style::new().fg_color(Some(Color::from(ty as u8)))
}
fn create_styles() -> Styles {
Styles::default()
.error(fg(ColorType::Red))
.header(Style::new().bold())
.invalid(fg(ColorType::Yellow))
.literal(fg(ColorType::Pink)) .placeholder(fg(ColorType::GrayLight))
.usage(fg(ColorType::Purple).bold())
.valid(fg(ColorType::Green))
}
#[derive(Debug, Parser)]
#[command(
name = "proto",
version,
about,
long_about = None,
disable_help_subcommand = true,
propagate_version = true,
next_line_help = false,
styles = create_styles()
)]
pub struct App {
#[arg(
value_enum,
long,
global = true,
env = "PROTO_LOG",
help = "Lowest log level to output"
)]
pub log: Option<LogLevel>,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Clone, Debug, Subcommand)]
pub enum Commands {
#[command(
alias = "ap",
name = "add-plugin",
about = "Add a plugin.",
long_about = "Add a plugin to the local .prototools config, or global ~/.proto/config.toml config.",
hide = true
)]
AddPlugin(AddToolArgs),
#[command(
alias = "a",
name = "alias",
about = "Add an alias to a tool.",
long_about = "Add an alias to a tool, that maps to a specific version, or another alias."
)]
Alias(AliasArgs),
#[command(
name = "bin",
about = "Display the absolute path to a tools executable.",
long_about = "Display the absolute path to a tools executable. If no version is provided,\nit will be detected from the current environment."
)]
Bin(BinArgs),
#[command(
name = "clean",
about = "Clean the ~/.proto directory by removing stale tools, plugins, and files."
)]
Clean(CleanArgs),
#[command(
name = "completions",
about = "Generate command completions for your current shell."
)]
Completions(CompletionsArgs),
#[command(
alias = "i",
name = "install",
about = "Download and install a tool.",
long_about = "Download and install a tool by unpacking the archive to ~/.proto/tools."
)]
Install(InstallArgs),
#[command(
alias = "ig",
name = "install-global",
about = "Install a global dependency for the specified tool.",
long_about = "Install a global dependency for the specified tool. Depending on the tool, the dependency will either be installed to ~/.proto/tools/<tool>/globals or ~/<tool>."
)]
InstallGlobal(InstallGlobalArgs),
#[command(
alias = "ls",
name = "list",
about = "List installed versions.",
long_about = "List installed versions by scanning the ~/.proto/tools directory for possible versions."
)]
List(ListArgs),
#[command(
alias = "lsg",
name = "list-global",
about = "List installed globals.",
long_about = "List installed globals by scanning the global packages installation directory. Will return the canonical source path."
)]
ListGlobal(ListGlobalArgs),
#[command(
alias = "lsr",
name = "list-remote",
about = "List available versions.",
long_about = "List available versions by resolving versions from the tool's remote release manifest."
)]
ListRemote(ListRemoteArgs),
#[command(
name = "migrate",
about = "Migrate breaking changes for the proto installation."
)]
Migrate(MigrateArgs),
#[command(
name = "outdated",
about = "Check if configured tool versions are out of date."
)]
Outdated(OutdatedArgs),
#[command(
alias = "p",
name = "pin",
about = "Pin a default global or local version of a tool.",
long_about = "Pin a default version of a tool globally to ~/.proto/tools, or locally to .prototools (in the current working directory)."
)]
Pin(PinArgs),
#[command(
name = "plugins",
about = "List all active and configured plugins.",
hide = true
)]
Plugins(ListToolPluginsArgs),
#[command(
alias = "rp",
name = "remove-plugin",
about = "Remove a plugin.",
long_about = "Remove a plugin from the local .prototools config, or global ~/.proto/config.toml config.",
hide = true
)]
RemovePlugin(RemoveToolArgs),
#[command(
alias = "r",
name = "run",
about = "Run a tool after detecting a version from the environment.",
long_about = "Run a tool after detecting a version from the environment. In order of priority,\na version will be resolved from a provided CLI argument, a PROTO_VERSION environment variable,\na local version file (.prototools), and lastly a global version file (~/.proto/tools).\n\nIf no version can be found, the program will exit with an error."
)]
Run(RunArgs),
#[command(name = "setup", about = "Setup proto for your current shell.")]
Setup(SetupArgs),
#[command(name = "tool", about = "Operations for managing tools and plugins.")]
Tool {
#[command(subcommand)]
command: ToolCommands,
},
#[command(
name = "tools",
about = "List all installed tools and their versions.",
hide = true
)]
Tools(ListToolsArgs),
#[command(alias = "ua", name = "unalias", about = "Remove an alias from a tool.")]
Unalias(UnaliasArgs),
#[command(
alias = "ui",
name = "uninstall",
about = "Uninstall a tool.",
long_about = "Uninstall a tool and remove the installation from ~/.proto/tools."
)]
Uninstall(UninstallArgs),
#[command(
alias = "ug",
name = "uninstall-global",
about = "Uninstall a global dependency from the specified tool."
)]
UninstallGlobal(UninstallGlobalArgs),
#[command(
alias = "up",
name = "upgrade",
about = "Upgrade proto to the latest version."
)]
Upgrade,
#[command(
alias = "u",
name = "use",
about = "Download and install all tools from the closest .prototools."
)]
Use,
}
#[derive(Clone, Debug, Subcommand)]
pub enum ToolCommands {
#[command(
name = "add",
about = "Add a tool plugin.",
long_about = "Add a plugin to the local .prototools config, or global ~/.proto/config.toml config."
)]
Add(AddToolArgs),
#[command(
name = "info",
about = "Display information about a tool and its plugin."
)]
Info(ToolInfoArgs),
#[command(name = "list", about = "List all installed tools and their versions.")]
List(ListToolsArgs),
#[command(
alias = "plugins",
name = "list-plugins",
about = "List all active and configured plugins."
)]
ListPlugins(ListToolPluginsArgs),
#[command(
name = "remove",
about = "Remove a tool plugin.",
long_about = "Remove a plugin from the local .prototools config, or global ~/.proto/config.toml config."
)]
Remove(RemoveToolArgs),
}