From 3598f7844c460a60eb608eb1267c3561f8f6aa29 Mon Sep 17 00:00:00 2001 From: Abraham Toriz Date: Wed, 25 Aug 2021 14:43:50 -0500 Subject: [PATCH] Don't write colorful output except in a colorful terminal --- src/commands/archive.rs | 2 +- src/commands/display.rs | 2 +- src/commands/edit.rs | 2 +- src/commands/list.rs | 25 ++++++++++++------------- src/commands/now.rs | 2 +- src/formatters.rs | 8 ++++---- src/formatters/text.rs | 40 +++++++++++++++++++++++----------------- src/tabulate.rs | 24 ++++++++++++++---------- 8 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/commands/archive.rs b/src/commands/archive.rs index f3cffef..848c63c 100644 --- a/src/commands/archive.rs +++ b/src/commands/archive.rs @@ -69,7 +69,7 @@ impl<'a> Command<'a> for ArchiveCommand { text::print_formatted( entries, &mut streams.out, - facts.now, + facts, true, )?; } else if ask(streams, &format!("Archive {} entries?", entries.len()))? { diff --git a/src/commands/display.rs b/src/commands/display.rs index c223951..e37175b 100644 --- a/src/commands/display.rs +++ b/src/commands/display.rs @@ -74,7 +74,7 @@ where format.print_formatted( entries, &mut streams.out, - facts.now, + facts, ids, )?; diff --git a/src/commands/edit.rs b/src/commands/edit.rs index 8994639..9e7d6b0 100644 --- a/src/commands/edit.rs +++ b/src/commands/edit.rs @@ -111,7 +111,7 @@ impl<'a> Command<'a> for EditCommand { text::print_formatted( updated_entry, &mut streams.out, - facts.now, + facts, true, )?; diff --git a/src/commands/list.rs b/src/commands/list.rs index 482b585..11f13ce 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -140,7 +140,7 @@ impl<'a> Command<'a> for ListCommand { format_duration(total), ]); - streams.out.write_all(tabs.print().as_bytes())?; + streams.out.write_all(tabs.print(facts.env.stdout_is_tty).as_bytes())?; warn_if_needed(&mut streams.err, needs_warning, &facts.env)?; @@ -152,7 +152,6 @@ impl<'a> Command<'a> for ListCommand { mod tests { use chrono::{Utc, TimeZone}; use pretty_assertions::assert_eq; - use ansi_term::Style; use crate::database::{SqliteDatabase, Database}; use crate::test_utils::Ps; @@ -180,15 +179,15 @@ mod tests { ListCommand::handle(args, &mut streams, &facts).unwrap(); - assert_eq!(Ps(&String::from_utf8_lossy(&streams.out)), Ps(&format!(" Timesheet Running Today Total Time + assert_eq!(Ps(&String::from_utf8_lossy(&streams.out)), Ps(" Timesheet Running Today Total Time - sheet1 {0} {0} 10:13:55 -* sheet2 {0} {0} 0:00:00 - sheet3 {0} 1:52:45 9:32:03 + sheet1 0:00:00 0:00:00 10:13:55 +* sheet2 0:00:00 0:00:00 0:00:00 + sheet3 0:00:00 1:52:45 9:32:03 - sheet4 1:52:45 1:52:45 1:52:45 -------------------------------------------- 1:52:45 3:45:30 21:38:43 -", Style::new().dimmed().paint(" 0:00:00")))); +")); // now show all the sheets streams.reset_io(); @@ -199,16 +198,16 @@ mod tests { ListCommand::handle(args, &mut streams, &facts).unwrap(); - assert_eq!(Ps(&String::from_utf8_lossy(&streams.out)), Ps(&format!(" Timesheet Running Today Total Time + assert_eq!(Ps(&String::from_utf8_lossy(&streams.out)), Ps(" Timesheet Running Today Total Time - _archived {0} {0} 1:00:00 - sheet1 {0} {0} 10:13:55 -* sheet2 {0} {0} 0:00:00 - sheet3 {0} 1:52:45 9:32:03 + _archived 0:00:00 0:00:00 1:00:00 + sheet1 0:00:00 0:00:00 10:13:55 +* sheet2 0:00:00 0:00:00 0:00:00 + sheet3 0:00:00 1:52:45 9:32:03 - sheet4 1:52:45 1:52:45 1:52:45 -------------------------------------------- 1:52:45 3:45:30 22:38:43 -", Style::new().dimmed().paint(" 0:00:00")))); +")); } #[test] diff --git a/src/commands/now.rs b/src/commands/now.rs index fcea0e2..b6f7751 100644 --- a/src/commands/now.rs +++ b/src/commands/now.rs @@ -75,7 +75,7 @@ impl<'a> Command<'a> for NowCommand { ]); } - streams.out.write_all(tabs.print().as_bytes())?; + streams.out.write_all(tabs.print(facts.env.stdout_is_tty).as_bytes())?; warn_if_needed(&mut streams.err, needs_warning, &facts.env)?; diff --git a/src/formatters.rs b/src/formatters.rs index 99a3942..b1a8064 100644 --- a/src/formatters.rs +++ b/src/formatters.rs @@ -2,10 +2,10 @@ use std::str::FromStr; use std::io::Write; use serde::{Serialize, Deserialize}; -use chrono::{DateTime, Utc}; use crate::error; use crate::models::Entry; +use crate::commands::Facts; pub mod text; pub mod csv; @@ -37,13 +37,13 @@ impl Formatter { /// to the local timezone is given in `offset` to prevent this function from /// using a secondary effect to retrieve the time and conver dates. This /// also makes it easier to test. - pub fn print_formatted(&self, entries: Vec, out: &mut W, now: DateTime, ids: bool) -> error::Result<()> { + pub fn print_formatted(&self, entries: Vec, out: &mut W, facts: &Facts, ids: bool) -> error::Result<()> { match &self { - Formatter::Text => text::print_formatted(entries, out, now, ids)?, + Formatter::Text => text::print_formatted(entries, out, facts, ids)?, Formatter::Csv => csv::print_formatted(entries, out, ids)?, Formatter::Json => json::print_formatted(entries, out)?, Formatter::Ids => ids::print_formatted(entries, out)?, - Formatter::Ical => ical::print_formatted(entries, out, now)?, + Formatter::Ical => ical::print_formatted(entries, out, facts.now)?, Formatter::Custom(name) => { panic!("attempted custom formatter with name {} which is not implemented", name); } diff --git a/src/formatters/text.rs b/src/formatters/text.rs index b7dd542..54e67ab 100644 --- a/src/formatters/text.rs +++ b/src/formatters/text.rs @@ -1,14 +1,12 @@ use std::io::Write; use itertools::Itertools; -use chrono::{ - DateTime, Utc, Duration, Local, NaiveTime, Timelike, - NaiveDateTime, -}; +use chrono::{ Duration, Local, NaiveTime, Timelike, NaiveDateTime }; use crate::models::Entry; use crate::error::Result; use crate::tabulate::{Tabulate, Col, Align::*}; +use crate::commands::Facts; pub fn format_duration(dur: Duration) -> String { format!("{}:{:02}:{:02}", dur.num_hours(), dur.num_minutes() % 60, dur.num_seconds() % 60) @@ -33,7 +31,7 @@ fn format_end(start: NaiveDateTime, end: NaiveDateTime) -> String { /// Print in the default text format. Assume entries are sorted by sheet and /// then by start -pub fn print_formatted(entries: Vec, out: &mut W, now: DateTime, ids: bool) -> Result<()> { +pub fn print_formatted(entries: Vec, out: &mut W, facts: &Facts, ids: bool) -> Result<()> { let grouped_entries = entries.into_iter().group_by(|e| e.sheet.to_string()); let mut num_sheets = 0; let mut grand_total = Duration::seconds(0); @@ -81,7 +79,7 @@ pub fn print_formatted(entries: Vec, out: &mut W, now: DateTime ) }).unwrap_or_else(|| "".into()) ); - let duration = entry.end.unwrap_or(now) - entry.start; + let duration = entry.end.unwrap_or(facts.now) - entry.start; daily = daily + duration; let duration = format_duration(duration); let note = entry.note.unwrap_or_else(|| "".into()); @@ -106,7 +104,7 @@ pub fn print_formatted(entries: Vec, out: &mut W, now: DateTime tabs.feed(vec!["".into(), "Total".into(), "".into(), format_duration(total)]); grand_total = grand_total + total; - out.write_all(tabs.print().as_bytes())?; + out.write_all(tabs.print(facts.env.stdout_is_tty).as_bytes())?; } if num_sheets > 1 { @@ -122,7 +120,7 @@ pub fn print_formatted(entries: Vec, out: &mut W, now: DateTime tabs.feed(vec!["".into(), "Grand total".into(), "".into(), format_duration(grand_total)]); - out.write_all(tabs.print().as_bytes())?; + out.write_all(tabs.print(facts.env.stdout_is_tty).as_bytes())?; } Ok(()) @@ -131,7 +129,7 @@ pub fn print_formatted(entries: Vec, out: &mut W, now: DateTime #[cfg(test)] mod tests { use pretty_assertions::assert_eq; - use chrono::TimeZone; + use chrono::{Utc, TimeZone}; use crate::test_utils::Ps; @@ -151,8 +149,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, false).unwrap(); + print_formatted(entries, &mut output, &facts, false).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default Day Start End Duration Notes @@ -176,8 +175,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, false).unwrap(); + print_formatted(entries, &mut output, &facts, false).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default Day Start End Duration Notes @@ -198,8 +198,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, false).unwrap(); + print_formatted(entries, &mut output, &facts, false).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default Day Start End Duration Notes @@ -224,8 +225,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, true).unwrap(); + print_formatted(entries, &mut output, &facts, true).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default ID Day Start End Duration Notes @@ -255,8 +257,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, true).unwrap(); + print_formatted(entries, &mut output, &facts, true).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default ID Day Start End Duration Notes @@ -289,8 +292,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, false).unwrap(); + print_formatted(entries, &mut output, &facts, false).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default Day Start End Duration Notes @@ -317,8 +321,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, false).unwrap(); + print_formatted(entries, &mut output, &facts, false).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: default Day Start End Duration Notes @@ -352,8 +357,9 @@ mod tests { ]; let now = Utc.ymd(2008, 10, 5).and_hms(20, 0, 0); + let facts = Facts::new().with_now(now); - print_formatted(entries, &mut output, now, false).unwrap(); + print_formatted(entries, &mut output, &facts, false).unwrap(); assert_eq!(Ps(&String::from_utf8_lossy(&output)), Ps("Timesheet: sheet1 Day Start End Duration Notes diff --git a/src/tabulate.rs b/src/tabulate.rs index d9cbb88..1c60753 100644 --- a/src/tabulate.rs +++ b/src/tabulate.rs @@ -150,7 +150,7 @@ impl Tabulate { self.data.push(DataOrSep::Sep(c)); } - pub fn print(self) -> String { + pub fn print(self, color: bool) -> String { let widths = self.widths; let cols = self.cols; @@ -174,7 +174,11 @@ impl Tabulate { }; if let Some(style) = style { - style.paint(s).to_string() + if color { + style.paint(s).to_string() + } else { + s + } } else { s } @@ -234,7 +238,7 @@ mod tests { tabs.separator('-'); tabs.feed(vec!["Total".into(), "".into(), "8:00:00".into(), "".into()]); - assert_eq!(Ps(&tabs.print()), Ps("\ + assert_eq!(Ps(&tabs.print(false)), Ps("\ Day Start End Duration Notes Fri Oct 03, 2008 12:00:00 - 14:00:00 2:00:00 entry 1 16:00:00 - 18:00:00 2:00:00 entry 2 @@ -264,7 +268,7 @@ Total 8:00:00 tabs.separator('-'); tabs.feed(vec!["Total".into(), "".into(), "52:00:00".into(), "".into()]); - assert_eq!(Ps(&tabs.print()), Ps("\ + assert_eq!(Ps(&tabs.print(false)), Ps("\ Day Start End Duration Notes Wed Oct 01, 2008 12:00:00 - 14:00:00+2d 50:00:00 entry 1 50:00:00 @@ -295,7 +299,7 @@ Total 52:00:00 tabs.separator('-'); tabs.feed(vec!["".into(), "Total".into(), "".into(), "8:00:00".into()]); - assert_eq!(Ps(&tabs.print()), Ps(" ID Day Start End Duration Notes + assert_eq!(Ps(&tabs.print(false)), Ps(" ID Day Start End Duration Notes 1 Fri Oct 03, 2008 12:00:00 - 14:00:00 2:00:00 entry 1 2 16:00:00 - 18:00:00 2:00:00 entry 2 4:00:00 @@ -323,7 +327,7 @@ Total 52:00:00 tabs.separator('-'); tabs.feed(vec!["".into(), "Total".into(), "".into(), "2:00:00".into()]); - assert_eq!(Ps(&tabs.print()), Ps(" ID Day Start End Duration Notes + assert_eq!(Ps(&tabs.print(false)), Ps(" ID Day Start End Duration Notes 60000 Sun Oct 05, 2008 16:00:00 - 18:00:00 2:00:00 chatting with bob about upcoming task, district sharing of images, how the user settings currently works etc. Discussing the @@ -353,7 +357,7 @@ Total 52:00:00 tabs.separator('-'); tabs.feed(vec!["Total".into(), "".into(), "2:00:00".into(), "".into()]); - assert_eq!(Ps(&tabs.print()), Ps("\ + assert_eq!(Ps(&tabs.print(false)), Ps("\ Day Start End Duration Notes Sun Oct 05, 2008 16:00:00 - 18:00:00 2:00:00 first line and a second line @@ -378,7 +382,7 @@ Total 2:00:00 tabs.separator('-'); tabs.feed(vec!["Total".into(), "".into(), "2:00:00".into(), "".into()]); - assert_eq!(Ps(&tabs.print()), Ps("\ + assert_eq!(Ps(&tabs.print(false)), Ps("\ Day Start End Duration Notes Sun Oct 05, 2008 16:00:00 - 18:00:00 2:00:00 quiúbole 2:00:00 @@ -399,7 +403,7 @@ Total 2:00:00 tabs.separator('-'); tabs.feed(vec!["ta güeno".into()]); - assert_eq!(Ps(&tabs.print()), Ps("\ + assert_eq!(Ps(&tabs.print(false)), Ps("\ Hola adiós @@ -420,7 +424,7 @@ ta güeno tabs.feed(vec!["foo".into(), "key".into()]); tabs.feed(vec!["key".into(), "foo".into()]); - assert_eq!(tabs.print(), format!("\ + assert_eq!(tabs.print(true), format!("\ foo key {} foo ", Style::new().dimmed().paint("key")));