Improve CLI arguments and help text

This commit is contained in:
Campbell Alden 2023-07-24 20:00:23 +09:00
parent b7cedea8eb
commit 30b22de2b9
3 changed files with 25 additions and 25 deletions

2
Cargo.lock generated
View file

@ -173,7 +173,7 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]] [[package]]
name = "day-reporter" name = "day-reporter"
version = "1.1.0" version = "1.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "day-reporter" name = "day-reporter"
version = "1.1.0" version = "1.2.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -10,20 +10,19 @@ use anyhow::Result;
use clap::{Parser, ValueEnum}; use clap::{Parser, ValueEnum};
#[derive(ValueEnum, Copy, Clone, Eq, PartialEq)] #[derive(ValueEnum, Copy, Clone, Eq, PartialEq)]
enum Modes { enum ReportTypes {
/// Generate a report containing projected work for the day and a morning message /// report projected work for the day and a morning message
Morning, Morning,
/// Generate a report that is intended to be used for sharing what major tasks were completed /// report what major tasks were completed in the last cycle.
/// in the last cycle.
Cycle, Cycle,
/// Generate a report for what was actually done today and a signoff message /// report what was actually done today and a signoff message
Signoff, Signoff,
} }
impl Modes { impl ReportTypes {
fn format_tasks(&self, tasks: Vec<Task>, tags: &Vec<String>, sanitize_names: bool) -> String { fn format_tasks(&self, tasks: Vec<Task>, tags: &Vec<String>, sanitize_names: bool) -> String {
match self { match self {
Modes::Morning => { ReportTypes::Morning => {
let task_report = MarkdownReporter.report(tasks, &ReportOptions { let task_report = MarkdownReporter.report(tasks, &ReportOptions {
resolution: Resolution::FullTask, resolution: Resolution::FullTask,
tags: tags.to_vec(), tags: tags.to_vec(),
@ -31,7 +30,7 @@ impl Modes {
}); });
format!("{}\n\n{}", emoji::pick(3).join(" "), task_report) format!("{}\n\n{}", emoji::pick(3).join(" "), task_report)
}, },
Modes::Signoff => { ReportTypes::Signoff => {
let task_report = MarkdownReporter.report(tasks, &ReportOptions { let task_report = MarkdownReporter.report(tasks, &ReportOptions {
resolution: Resolution::FullTask, resolution: Resolution::FullTask,
tags: tags.to_vec(), tags: tags.to_vec(),
@ -39,7 +38,7 @@ impl Modes {
}); });
format!("Stopping now\n\n{}", task_report) format!("Stopping now\n\n{}", task_report)
}, },
Modes::Cycle => { ReportTypes::Cycle => {
let further_filtered = tasks.into_iter().filter(|t| { let further_filtered = tasks.into_iter().filter(|t| {
if let Some(p) = &t.project { if let Some(p) = &t.project {
return p.status == Status::Completed; return p.status == Status::Completed;
@ -57,42 +56,43 @@ impl Modes {
} }
} }
impl Default for Modes { impl Default for ReportTypes {
fn default() -> Modes { fn default() -> ReportTypes {
Modes::Morning ReportTypes::Morning
} }
} }
/// A program that generates Slack flavor markdown reports from Things 3 todo list items.
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
struct CliArgs { struct CliArgs {
/// A list of tags to filter requests on /// A list of tags to filter todos by. Only todo list items with every tag will be reported
#[arg(short, long)] #[arg(short, long)]
tags: Vec<String>, tags: Vec<String>,
/// Control what type of report to generate /// Select the type of report to generate
#[arg(short, long, default_value_t = Modes::default())] #[arg(short, long, default_value_t = ReportTypes::default())]
#[clap(value_enum)] #[clap(value_enum)]
mode: Modes, report: ReportTypes,
/// By default, any @<name> style tags will be sanitized in the output to avoid @-mentions in /// By default, any @<name> style tags will be sanitized in the output to avoid @-mentions in
/// slack. This is done by replacing vowel characters with look unicode lookalikes. If this /// Slack. This is done by replacing vowel characters with unicode lookalikes. If this
/// flag is set then the names will be passed through unsanitized /// flag is set then the names will be passed through unsanitized.
#[arg(long, default_value_t = false)] #[arg(long, default_value_t = false)]
no_sanitize: bool, no_sanitize: bool,
} }
fn main() -> Result<()> { fn main() -> Result<()> {
let args = CliArgs::parse(); let args = CliArgs::parse();
let tasks = match args.mode { let tasks = match args.report {
Modes::Morning => Task::today(), ReportTypes::Morning => Task::today(),
Modes::Signoff => Task::logbook_today(), ReportTypes::Signoff => Task::logbook_today(),
Modes::Cycle => Task::logbook_this_cycle(), ReportTypes::Cycle => Task::logbook_this_cycle(),
}?; }?;
let reported: Vec<Task> = tasks.into_iter().filter(|task| { let reported: Vec<Task> = tasks.into_iter().filter(|task| {
args.tags.iter().all(|tag| task.has_tag(tag)) args.tags.iter().all(|tag| task.has_tag(tag))
}).collect(); }).collect();
let report = args.mode.format_tasks(reported, &args.tags, !args.no_sanitize); let report = args.report.format_tasks(reported, &args.tags, !args.no_sanitize);
println!("{report}"); println!("{report}");
Ok(()) Ok(())