diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 7c93504..755c0d5 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -2,8 +2,6 @@ name: Release on: push: - branches: - - main workflow_dispatch: jobs: diff --git a/Cargo.lock b/Cargo.lock index f42563f..f858312 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.4.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" [[package]] name = "find-msvc-tools" @@ -787,7 +787,7 @@ checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "streamd" -version = "0.2.0" +version = "0.1.1" dependencies = [ "chrono", "chrono-tz", diff --git a/Cargo.toml b/Cargo.toml index c073e7e..cb39165 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "streamd" -version = "0.2.0" +version = "0.1.1" edition = "2021" description = "Personal knowledge management and time-tracking CLI using @Tag annotations" license = "AGPL-3.0-only" diff --git a/src/cli/args.rs b/src/cli/args.rs index 83c762c..be56ee3 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -50,11 +50,7 @@ pub enum Commands { }, /// Display extracted timesheets - Timesheet { - /// Display time as minutes (HH:MM) instead of decimal hours (H.Hh) - #[arg(short, long)] - minutes: bool, - }, + Timesheet, /// Generate shell completions Completions { diff --git a/src/cli/commands/timesheet.rs b/src/cli/commands/timesheet.rs index f2571dc..80346b4 100644 --- a/src/cli/commands/timesheet.rs +++ b/src/cli/commands/timesheet.rs @@ -41,14 +41,8 @@ fn load_all_shards(base_folder: &Path) -> Result, StreamdErr } /// Format hours with sign for display. -fn format_diff(hours: f64, use_minutes: bool) -> String { - if use_minutes { - let total_minutes = (hours * 60.0).round() as i32; - let h = total_minutes.abs() / 60; - let m = total_minutes.abs() % 60; - let sign = if hours >= 0.0 { "+" } else { "-" }; - format!("{}{}:{:02}", sign, h, m) - } else if hours >= 0.0 { +fn format_diff(hours: f64) -> String { + if hours >= 0.0 { format!("+{:.1}h", hours.abs()) } else { format!("{:.1}h", hours) @@ -56,15 +50,8 @@ fn format_diff(hours: f64, use_minutes: bool) -> String { } /// Format hours for display without sign. -fn format_hours(hours: f64, use_minutes: bool) -> String { - if use_minutes { - let total_minutes = (hours * 60.0).round() as i32; - let h = total_minutes.abs() / 60; - let m = total_minutes.abs() % 60; - format!("{}:{:02}", h, m) - } else { - format!("{:.1}h", hours.abs()) - } +fn format_hours(hours: f64) -> String { + format!("{:.1}h", hours.abs()) } /// Get the weekday abbreviation. @@ -90,8 +77,8 @@ fn print_header() { } /// Print a month report. -fn print_month(month: &MonthReport, use_minutes: bool) { - let diff_str = format_diff(month.diff(), use_minutes); +fn print_month(month: &MonthReport) { + let diff_str = format_diff(month.diff()); let month_title = format!("{} {}", month.month_name(), month.year); // Month header with diff @@ -112,9 +99,9 @@ fn print_month(month: &MonthReport, use_minutes: bool) { for day in &month.days { let date_str = day.date.format("%Y-%m-%d").to_string(); let weekday = weekday_abbrev(day.date); - let expected = format_hours(day.expected_hours, use_minutes); - let actual = format_hours(day.actual_hours, use_minutes); - let diff = format_diff(day.diff(), use_minutes); + let expected = format_hours(day.expected_hours); + let actual = format_hours(day.actual_hours); + let diff = format_diff(day.diff()); let type_str = match day.day_type { DayType::Regular => String::new(), @@ -147,26 +134,26 @@ fn print_month(month: &MonthReport, use_minutes: bool) { println!(" {}", light_line); println!( " Monthly: {:>7} {:>7} {:>6}", - format_hours(month.total_expected(), use_minutes), - format_hours(month.total_actual(), use_minutes), - format_diff(month.diff(), use_minutes) + format_hours(month.total_expected()), + format_hours(month.total_actual()), + format_diff(month.diff()) ); println!(); } /// Print the cumulative balance. -fn print_cumulative_balance(balance: f64, use_minutes: bool) { +fn print_cumulative_balance(balance: f64) { let light_line = "\u{2500}".repeat(SEPARATOR_WIDTH); println!("{}", light_line); println!( " CUMULATIVE BALANCE: {}", - format_diff(balance, use_minutes) + format_diff(balance) ); println!("{}", light_line); } /// Print warnings section. -fn print_warnings(report: &TimesheetReport, use_minutes: bool) { +fn print_warnings(report: &TimesheetReport) { if !report.has_warnings() { return; } @@ -229,9 +216,9 @@ fn print_warnings(report: &TimesheetReport, use_minutes: bool) { for w in &outside_period_warnings { if let DayWarning::OutsidePeriod { hours_worked } = &w.warning { println!( - " - {}: {} worked (no period configured)", + " - {}: {:.1}h worked (no period configured)", w.date.format("%Y-%m-%d"), - format_hours(*hours_worked, use_minutes) + hours_worked ); } } @@ -239,7 +226,7 @@ fn print_warnings(report: &TimesheetReport, use_minutes: bool) { } } -pub fn run(use_minutes: bool) -> Result<(), StreamdError> { +pub fn run() -> Result<(), StreamdError> { let settings = Settings::load()?; let base_folder = Path::new(&settings.base_folder); @@ -279,46 +266,11 @@ pub fn run(use_minutes: bool) -> Result<(), StreamdError> { print_header(); for month in &report.months { - print_month(month, use_minutes); + print_month(month); } - print_cumulative_balance(report.cumulative_balance, use_minutes); - print_warnings(&report, use_minutes); + print_cumulative_balance(report.cumulative_balance); + print_warnings(&report); Ok(()) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_format_hours_decimal() { - assert_eq!(format_hours(8.0, false), "8.0h"); - assert_eq!(format_hours(8.5, false), "8.5h"); - assert_eq!(format_hours(0.0, false), "0.0h"); - } - - #[test] - fn test_format_hours_minutes() { - assert_eq!(format_hours(8.0, true), "8:00"); - assert_eq!(format_hours(8.5, true), "8:30"); - assert_eq!(format_hours(0.0, true), "0:00"); - assert_eq!(format_hours(1.25, true), "1:15"); - } - - #[test] - fn test_format_diff_decimal() { - assert_eq!(format_diff(0.5, false), "+0.5h"); - assert_eq!(format_diff(-1.5, false), "-1.5h"); - assert_eq!(format_diff(0.0, false), "+0.0h"); - } - - #[test] - fn test_format_diff_minutes() { - assert_eq!(format_diff(0.5, true), "+0:30"); - assert_eq!(format_diff(-1.5, true), "-1:30"); - assert_eq!(format_diff(0.0, true), "+0:00"); - assert_eq!(format_diff(1.25, true), "+1:15"); - } -} diff --git a/src/main.rs b/src/main.rs index 2a7e1f6..e6325c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ fn main() -> miette::Result<()> { Some(TodoAction::Done { number }) => streamd::cli::commands::todo::run_done(number)?, }, Some(Commands::Edit { number }) => streamd::cli::commands::edit::run(number)?, - Some(Commands::Timesheet { minutes }) => streamd::cli::commands::timesheet::run(minutes)?, + Some(Commands::Timesheet) => streamd::cli::commands::timesheet::run()?, Some(Commands::Completions { shell }) => { streamd::cli::commands::completions::run(shell); }