use anyhow::Result;
use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::Shell;
use tracing_subscriber::EnvFilter;
mod commands;
mod output;
mod provider_context;
use commands::*;
#[derive(Parser)]
#[command(name = "gt")]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
#[arg(long, global = true)]
debug: bool,
#[arg(long, short, global = true)]
quiet: bool,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Init(init::InitArgs),
Create(create::CreateArgs),
Rename(rename::RenameArgs),
Delete(delete::DeleteArgs),
Track(track::TrackArgs),
Untrack(untrack::UntrackArgs),
Up(nav::UpArgs),
Down(nav::DownArgs),
Top(nav::TopArgs),
Bottom(nav::BottomArgs),
Checkout(checkout::CheckoutArgs),
Log(log::LogArgs),
Ls(log::LogArgs),
Ll(log::LogArgs),
Info(info::InfoArgs),
Status(status::StatusArgs),
Modify(modify::ModifyArgs),
Squash(squash::SquashArgs),
Fold(fold::FoldArgs),
Split(split::SplitArgs),
Sync(sync::SyncArgs),
Restack(restack::RestackArgs),
Submit(submit::SubmitArgs),
Land(land::LandArgs),
Continue(continue_cmd::ContinueArgs),
Abort(abort::AbortArgs),
Undo(undo::UndoArgs),
Redo(redo::RedoArgs),
Auth(auth::AuthArgs),
Config(config::ConfigArgs),
Completions {
#[arg(value_enum)]
shell: Shell,
},
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
let filter = if cli.debug {
EnvFilter::new("debug")
} else {
EnvFilter::new("info")
};
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.without_time()
.init();
output::set_quiet(cli.quiet);
let result = match cli.command {
Commands::Init(args) => init::execute(args).await,
Commands::Create(args) => create::execute(args).await,
Commands::Rename(args) => rename::execute(args).await,
Commands::Delete(args) => delete::execute(args).await,
Commands::Track(args) => track::execute(args).await,
Commands::Untrack(args) => untrack::execute(args).await,
Commands::Up(args) => nav::up(args).await,
Commands::Down(args) => nav::down(args).await,
Commands::Top(args) => nav::top(args).await,
Commands::Bottom(args) => nav::bottom(args).await,
Commands::Checkout(args) => checkout::execute(args).await,
Commands::Log(args) => log::execute(args, false).await,
Commands::Ls(args) => log::execute(args, true).await,
Commands::Ll(args) => log::execute_long(args).await,
Commands::Info(args) => info::execute(args).await,
Commands::Status(args) => status::execute(args).await,
Commands::Modify(args) => modify::execute(args).await,
Commands::Squash(args) => squash::execute(args).await,
Commands::Fold(args) => fold::execute(args).await,
Commands::Split(args) => split::execute(args).await,
Commands::Sync(args) => sync::execute(args).await,
Commands::Restack(args) => restack::execute(args).await,
Commands::Submit(args) => submit::execute(args).await,
Commands::Land(args) => land::execute(args).await,
Commands::Continue(args) => continue_cmd::execute(args).await,
Commands::Abort(args) => abort::execute(args).await,
Commands::Undo(args) => undo::execute(args).await,
Commands::Redo(args) => redo::execute(args).await,
Commands::Auth(args) => auth::execute(args).await,
Commands::Config(args) => config::execute(args).await,
Commands::Completions { shell } => {
let mut cmd = Cli::command();
completions::execute(completions::CompletionsArgs { shell }, &mut cmd)
}
};
if let Err(e) = result {
output::error(&format!("{:#}", e));
if let Some(stack_err) = e.downcast_ref::<stkd_core::Error>() {
if let Some(hint) = stack_err.hint() {
output::hint(hint);
}
}
std::process::exit(1);
}
Ok(())
}