use std::path::PathBuf;
use anyhow::Result;
use clap::{Parser, Subcommand};
use crate::commands;
#[derive(Debug, Parser)]
#[command(
version,
about,
long_about = None
)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
#[arg(short = 'C', long = "repo", global = true, value_name = "PATH")]
pub repo: Option<PathBuf>,
#[arg(short, long, global = true)]
pub verbose: bool,
#[arg(long, global = true, value_enum, default_value = "auto")]
pub theme: ThemeArg,
#[arg(long, global = true, value_enum, default_value = "auto")]
pub lang: LangArg,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LangArg {
Auto,
Zh,
En,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ThemeArg {
Auto,
Dark,
Light,
}
#[derive(Debug, Subcommand)]
pub enum Commands {
Merge(commands::run::MergeArgs),
Rebase(commands::run::RebaseArgs),
Pull(commands::run::PullArgs),
CherryPick(commands::run::CherryPickArgs),
Revert(commands::run::RevertArgs),
File(commands::file::FileArgs),
Abort,
Completions(commands::completions::CompletionsArgs),
}
impl Cli {
pub fn run(self) -> Result<()> {
if let Some(Commands::Completions(args)) = &self.command {
commands::completions::run(args.shell);
return Ok(());
}
match self.lang {
LangArg::Zh => crate::i18n::init(crate::i18n::Lang::Zh),
LangArg::En => crate::i18n::init(crate::i18n::Lang::En),
LangArg::Auto => {}
}
let config = crate::config::load()?;
crate::i18n::init(match config.ui.lang {
Some(LangArg::Zh) => crate::i18n::Lang::Zh,
Some(LangArg::En) => crate::i18n::Lang::En,
_ => crate::i18n::detect(),
});
crate::ui::keymap::init(&config.keys)?;
crate::ui::init_theme_overrides(&config.theme)?;
crate::ui::init_editor(config.ui.editor.clone());
let verbose = self.verbose || config.ui.verbose.unwrap_or(false);
let dir = self.repo.unwrap_or_else(|| PathBuf::from("."));
let theme = match self.theme {
ThemeArg::Auto => config.ui.theme.unwrap_or(ThemeArg::Auto),
explicit => explicit,
};
let light = match theme {
ThemeArg::Light => true,
ThemeArg::Dark => false,
ThemeArg::Auto => crate::ui::detect_light(),
};
match self.command {
None => commands::menu::run(verbose, &dir, light),
Some(Commands::Merge(args)) => commands::run::merge(args, verbose, &dir, light),
Some(Commands::Rebase(args)) => commands::run::rebase(args, verbose, &dir, light),
Some(Commands::Pull(args)) => commands::run::pull(args, verbose, &dir, light),
Some(Commands::CherryPick(args)) => {
commands::run::cherry_pick(args, verbose, &dir, light)
}
Some(Commands::Revert(args)) => commands::run::revert(args, verbose, &dir, light),
Some(Commands::File(args)) => commands::file::run(args, light),
Some(Commands::Abort) => commands::abort::run(verbose, &dir),
Some(Commands::Completions(_)) => Ok(()),
}
}
}