crax 0.1.8

An interesting CLI for frontend programmer
Documentation
// mod git;
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
    })
}