pub mod autostart;
pub mod export;
pub mod inbox;
pub mod init;
pub mod migrations;
pub mod pauses;
pub mod report;
pub mod server;
pub mod sum;
pub mod tag;
pub mod task;
pub mod template;
pub mod update;
pub mod watch;
use crate::{db::workdays::Workdays, libs::messages::types::Message, msg_info, msg_warning};
use anyhow::Result;
use chrono::Local;
use clap::{Parser, Subcommand};
#[derive(Debug, Subcommand)]
enum Commands {
#[command(about = "Manage autostart on system boot")]
Autostart(autostart::AutostartArgs),
#[command(about = "Set up configuration", alias = "init")]
Setup(init::SetupArgs),
#[command(about = "Create task")]
Task(task::TaskArgs),
#[command(about = "Write end timestamp to database")]
End,
#[command(about = "Get summary")]
Sum(sum::SumArgs),
#[command(name = "self-update", about = "Update kasl itself to the latest release", alias = "update")]
SelfUpdate,
#[command(about = "Prepare a report")]
Report(report::ReportArgs),
#[command(about = "Export data to various formats")]
Export(export::ExportArgs),
#[command(about = "Manage task templates")]
Template(template::TemplateArgs),
#[command(about = "Manage task tags")]
Tag(tag::TagArgs),
#[command(about = "Watch user activity in the background to record pauses")]
Watch(watch::WatchArgs),
#[command(about = "View pauses and record ones the monitor missed")]
Pauses(pauses::PausesArgs),
#[command(about = "Manage the connection to a kasl-server")]
Server(server::ServerArgs),
#[command(about = "Manage Jira inbox issues")]
Inbox(inbox::InboxArgs),
#[command(about = "Print a shell completion script (source it from your shell profile)")]
Completions {
shell: clap_complete::Shell,
},
#[cfg(debug_assertions)]
#[command(about = "Database migration management")]
Migrations(migrations::MigrationsArgs),
}
#[derive(Debug, Parser)]
#[command(name = "kasl", author, version, about, long_about = None)]
#[command(arg_required_else_help(true))]
pub struct Cli {
#[command(subcommand)]
command: Commands,
}
impl Cli {
pub async fn menu() -> Result<()> {
let cli = Self::parse();
match cli.command {
Commands::Autostart(args) => autostart::cmd(args),
Commands::Setup(args) => {
warn_if_deprecated_alias();
init::cmd(args)
}
Commands::Task(args) => task::cmd(args).await,
Commands::End => {
Workdays::new()?.insert_end(Local::now().date_naive())?;
msg_info!(Message::WorkdayEnded);
Ok(())
}
Commands::Sum(args) => sum::cmd(args).await,
Commands::Report(args) => report::cmd(args).await,
Commands::Export(args) => export::cmd(args).await,
Commands::Template(args) => template::cmd(args),
Commands::Tag(args) => tag::cmd(args).await,
Commands::SelfUpdate => {
warn_if_deprecated_alias();
update::cmd().await
}
Commands::Watch(args) => watch::cmd(args).await,
Commands::Pauses(args) => pauses::cmd(args).await,
Commands::Completions { shell } => {
use clap::CommandFactory;
clap_complete::generate(shell, &mut Self::command(), "kasl", &mut std::io::stdout());
Ok(())
}
Commands::Server(args) => server::cmd(args).await,
Commands::Inbox(args) => inbox::cmd(args).await,
#[cfg(debug_assertions)]
Commands::Migrations(args) => migrations::cmd(args),
}
}
}
const DEPRECATED_ALIASES: [(&str, &str); 2] = [("init", "setup"), ("update", "self-update")];
fn warn_if_deprecated_alias() {
let Some(typed) = std::env::args().nth(1) else {
return;
};
if let Some((old, new)) = DEPRECATED_ALIASES.iter().find(|(old, _)| *old == typed) {
msg_warning!(Message::DeprecatedCommand(old, new));
}
}