1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
//! Pace Subcommands
//!
//! This is where you specify the subcommands of your application.
//!
//! The default application comes with two subcommands:
//!
//! - `start`: launches the application
//! - `--version`: print application version
//!
//! See the `impl Configurable` below for how to specify the path to the
//! application's configuration file.
mod begin;
mod end;
mod export;
// TODO: mod import;
mod craft;
mod hold;
mod now;
mod pomo;
mod resume;
mod review;
mod set;
mod tasks;
use abscissa_core::{Command, Configurable, FrameworkError, Runnable};
use clap::builder::{styling::AnsiColor, Styles};
use std::path::PathBuf;
use pace_core::config::PaceConfig;
/// Pace Configuration Filename
/// FIXME: Make this configurable
pub const CONFIG_FILE: &str = "config/pace.toml";
/// Pace Subcommands
/// Subcommands need to be listed in an enum.
#[derive(clap::Parser, Command, Debug, Runnable)]
pub enum PaceCmd {
/// Starts tracking time for the specified task. You can
/// optionally specify a category or project to help organize
/// your tasks.
Begin(begin::BeginCmd),
/// Stops time tracking for the specified task, marking it as completed or finished for the day.
End(end::EndCmd),
/// Exports your tracked data and reviews in JSON or CSV format, suitable for analysis or record-keeping.
Export(export::ExportCmd),
/// Crafts a pace configuration, a new project or shell completions
Craft(craft::CraftCmd),
/// Pauses the time tracking for the specified task. This is
/// useful for taking breaks without ending the task.
Hold(hold::HoldCmd),
/// Displays the currently running task, showing you at a glance what you're currently tracking.
Now(now::NowCmd),
/// Starts a Pomodoro session for the specified task, integrating the Pomodoro technique directly with your tasks.
Pomo(pomo::PomoCmd),
/// Resumes time tracking for a previously paused task, allowing you to continue where you left off.
Resume(resume::ResumeCmd),
/// Get insights on your activities and tasks. You can specify the time frame for daily, weekly, or monthly insights.
Review(review::ReviewCmd),
/// Sets various application configurations, including Pomodoro lengths and preferred review formats.
Set(set::SetCmd),
/// Lists all tasks with optional filters. Use this to view active, completed, or today's tasks.
Tasks(tasks::TasksCmd),
}
/// Define CLI colour styles for the application
fn cli_colour_styles() -> Styles {
Styles::styled()
.header(AnsiColor::BrightBlue.on_default())
.usage(AnsiColor::BrightYellow.on_default())
.literal(AnsiColor::BrightGreen.on_default())
.placeholder(AnsiColor::Magenta.on_default())
}
/// Entry point for the application. It needs to be a struct to allow using subcommands!
#[derive(clap::Parser, Command, Debug)]
#[command(author, about, styles=cli_colour_styles(), version)]
pub struct EntryPoint {
#[command(subcommand)]
cmd: PaceCmd,
/// Enable verbose logging
#[arg(short, long)]
pub verbose: bool,
/// Use the specified config file
#[arg(short, long)]
pub config: Option<String>,
/// Use the specified activity log file
#[arg(short, long)]
pub activity_log_file: Option<String>,
}
impl Runnable for EntryPoint {
fn run(&self) {
self.cmd.run()
}
}
/// This trait allows you to define how application configuration is loaded.
impl Configurable<PaceConfig> for EntryPoint {
/// Location of the configuration file
fn config_path(&self) -> Option<PathBuf> {
// Check if the config file exists, and if it does not, ignore it.
// If you'd like for a missing configuration file to be a hard error
// instead, always return `Some(CONFIG_FILE)` here.
let filename = self
.config
.as_ref()
.map(PathBuf::from)
.unwrap_or_else(|| CONFIG_FILE.into());
if filename.exists() {
Some(filename)
} else {
None
}
}
/// Apply changes to the config after it's been loaded, e.g. overriding
/// values in a config file using command-line options.
///
/// This can be safely deleted if you don't want to override config
/// settings from command-line options.
fn process_config(&self, config: PaceConfig) -> Result<PaceConfig, FrameworkError> {
// match &self.cmd {
// PaceCmd::Start(cmd) => cmd.override_config(config),
//
// If you don't need special overrides for some
// subcommands, you can just use a catch all
// _ => Ok(config),
// }
Ok(config)
}
}