mod commands;
mod error;
mod net;
mod project;
mod registry;
mod sys;
mod tools;
mod ui;
use clap::{Parser, Subcommand};
use commands::self_cmd::SelfCommand;
#[derive(Parser, Debug)]
#[command(name = "lpm", bin_name = "lpm", version, about, styles = ui::help_styles())]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
Init,
Run(commands::run::RunArgs),
Studio,
Add(commands::add::AddArgs),
#[command(subcommand)]
Tool(commands::tool::ToolCommand),
#[command(subcommand)]
Index(commands::index::IndexCommand),
#[command(visible_alias = "i")]
Install(commands::install::InstallArgs),
Publish(commands::publish::PublishArgs),
#[command(subcommand, name = "self")]
SelfManage(SelfCommand),
}
fn main() {
if let Some(alias) = tools::shim::shim_alias() {
match tools::shim::run(&alias) {
Ok(code) => std::process::exit(code),
Err(err) => {
ui::print_error(&err.to_string());
std::process::exit(1);
}
}
}
let cli = parse_cli();
let started = std::time::Instant::now();
let result = match cli.command {
Commands::Init => commands::init::run(),
Commands::Add(args) => commands::add::run(args),
Commands::Index(command) => commands::index::run(command),
Commands::Install(args) => commands::install::run(args),
Commands::Publish(args) => commands::publish::run(args),
Commands::SelfManage(command) => commands::self_cmd::run(command),
Commands::Tool(command) => commands::tool::run(command),
Commands::Studio => commands::studio::run(),
Commands::Run(args) => commands::run::run(args),
};
match result {
Ok(()) => ui::print_elapsed(started.elapsed()),
Err(err) => {
ui::print_error(&err.to_string());
std::process::exit(1);
}
}
}
fn parse_cli() -> Cli {
Cli::try_parse().unwrap_or_else(|err| {
let plain = err.render().to_string();
let Some(rest) = plain.strip_prefix("error: ") else {
err.exit()
};
let message = rest.lines().next().unwrap_or(rest);
let mut chars = message.chars();
let capitalized = match chars.next() {
Some(first) => first.to_uppercase().to_string() + chars.as_str(),
None => String::new(),
};
ui::print_error(&capitalized);
let styled = err.render().ansi().to_string();
if let Some((_error_line, extra)) = styled.split_once('\n') {
let extra = extra
.replace("tip:", "")
.replace(" a similar", "A similar")
.replace(" some similar", "Some similar");
eprint!("{extra}");
}
std::process::exit(2)
})
}