use std::path::PathBuf;
use std::process::ExitCode;
use anyhow::Result;
use clap::builder::styling::{Style, Styles};
use clap::{Parser, Subcommand};
use tracing::error;
mod cmd;
mod store;
mod trace;
use store::Store;
const STYLES: Styles = Styles::styled().usage(Style::new());
const HELP_TEMPLATE_OPT_ARG: &str = "\
{about}
USAGE
{usage}
ARGUMENTS
{positionals}
OPTIONS
{options}
";
const HELP_TEMPLATE_OPT: &str = "\
{about}
USAGE
{usage}
OPTIONS
{options}
";
const HELP_TEMPLATE_CMD: &str = "\
{about}
USAGE
{usage}
COMMANDS
{subcommands}
OPTIONS
{options}
";
const TERM_WIDTH: usize = 80;
#[derive(Debug, Parser)]
#[clap(
about,
help_template = HELP_TEMPLATE_CMD,
styles = STYLES,
term_width = TERM_WIDTH,
version
)]
pub struct CliConfig {
#[arg(long, global = true, env = "KT_DATA_DIR")]
data_dir: Option<PathBuf>,
#[clap(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
pub enum Command {
#[clap(visible_alias = "a")]
Add(cmd::CommandAdd),
#[clap(visible_alias = "ls")]
List(cmd::CommandList),
#[clap(visible_alias = "l")]
Log(cmd::CommandLog),
#[clap(visible_alias = "i")]
In(cmd::CommandIn),
#[clap(visible_alias = "n")]
New(cmd::CommandNew),
#[clap(visible_alias = "o")]
Out(cmd::CommandOut),
#[clap(visible_alias = "s")]
Switch(cmd::CommandSwitch),
}
fn main() -> ExitCode {
if let Err(e) = run_main() {
error!("{e}");
ExitCode::FAILURE
} else {
ExitCode::SUCCESS
}
}
fn run_main() -> Result<()> {
let config = CliConfig::parse();
trace::init();
let store = match config.data_dir {
Some(dir) => Store::new(&dir)?,
None => Store::with_project_dir()?,
};
match config.command {
Command::Add(cmd) => cmd.execute(&store),
Command::List(cmd) => cmd.execute(&store),
Command::Log(cmd) => cmd.execute(&store),
Command::In(cmd) => cmd.execute(&store),
Command::New(cmd) => cmd.execute(&store),
Command::Out(cmd) => cmd.execute(&store),
Command::Switch(cmd) => cmd.execute(&store),
}
}