mod dts;
mod mono;
pub mod open;
mod pkg;
use std::{
ffi::OsString,
path::{PathBuf, absolute},
};
use anyhow::Ok;
use clap::{Parser, Subcommand};
use crax_monorepo::ctx;
use dialoguer::console::Term;
pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled()
.header(clap_cargo::style::HEADER)
.usage(clap_cargo::style::USAGE)
.literal(clap_cargo::style::LITERAL)
.placeholder(clap_cargo::style::PLACEHOLDER)
.error(clap_cargo::style::ERROR)
.valid(clap_cargo::style::VALID)
.invalid(clap_cargo::style::INVALID);
#[derive(Parser)]
#[command(
name = "crax",
author = "wangxd <lovingskymm@foxmail.com>",
version,
about = "😜 A CLI for frontend programmer based on pnpm",
styles = CLAP_STYLING
)]
pub struct Crax {
#[command(subcommand)]
pub command: Option<Command>,
#[arg(short = 'R', long, help = "Crax config path. support: Crax.toml")]
root: Option<OsString>,
}
#[derive(Subcommand)]
pub enum Command {
#[command(about = "Create a new empty config file Crax.toml at current directory")]
INIT {},
#[command(
about = "A series of effective operations. e.g. 'pkg cls' will delete all node_modules"
)]
PKG {
#[command(subcommand)]
command: Option<pkg::Cmd>,
},
#[command(about = "Generate type files by tsc")]
DTS(dts::Cmd),
#[command(
about = "Open url, playground and repository easily. e.g. 'crax open vue' will open vuejs api"
)]
OPEN(open::cli::Cmd),
#[command(about = "A series of monorepo operations based on pnpm. e.g. 'crax mono info'")]
MONO {
#[arg(long, help = "Whether include root package")]
root: bool,
#[command(subcommand)]
command: Option<mono::Cmd>,
},
}
pub async fn run(ctx: &mut ctx::Ctx) -> anyhow::Result<()> {
ctrlc::set_handler(move || println!("")).expect("Error setting Ctrl-C handler");
let crax = Crax::parse();
let cwd_str = ctx.cwd.as_os_str().to_os_string();
let conf_path = &absolute(crax.root.as_ref().unwrap_or(&cwd_str))?;
if let Some(c) = &crax.root {
ctx.cwd = PathBuf::from(c.clone())
}
ctx.update_config_by_path(conf_path);
match &crax.command {
Some(Command::INIT {}) => ctx.create_empty_config(conf_path),
Some(Command::PKG { command }) => pkg::run(ctx, command).await,
Some(Command::OPEN(def)) => open::cli::run(def).await,
Some(Command::MONO { command, root }) => mono::run(ctx, command.clone(), *root).await,
Some(Command::DTS(cmd)) => dts::run(cmd, conf_path).await,
None => Ok(()),
}
.map_err(|e| {
let _ = Term::stdout().show_cursor();
e
})
}