From fc7b4109c75299a2ee8debaccc73721338946cfa Mon Sep 17 00:00:00 2001 From: Mx Kookie Date: Fri, 11 Dec 2020 18:35:07 +0000 Subject: [PATCH] cassiopeia: changing project structure and adding CLI parsing --- apps/cassiopeia/README.md | 2 +- apps/cassiopeia/src/bin/cass.rs | 62 ++++++++++++++++++++++++++++ apps/cassiopeia/src/format/mod.rs | 5 +-- apps/cassiopeia/src/format/parser.rs | 9 ++-- apps/cassiopeia/src/lib.rs | 8 ++++ apps/cassiopeia/src/main.rs | 9 ---- apps/cassiopeia/src/meta.rs | 34 +++++++++++++++ 7 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 apps/cassiopeia/src/bin/cass.rs create mode 100644 apps/cassiopeia/src/lib.rs delete mode 100644 apps/cassiopeia/src/main.rs create mode 100644 apps/cassiopeia/src/meta.rs diff --git a/apps/cassiopeia/README.md b/apps/cassiopeia/README.md index d6456bf7f40..939a86e51eb 100644 --- a/apps/cassiopeia/README.md +++ b/apps/cassiopeia/README.md @@ -40,7 +40,7 @@ in the current working directory is tried. If this does not exist, the program exits with an error. By default time values are rounded to the next 15 minutes. To disable -this, pass `-r` to any command. +this, pass `-r` to either the `start` or `stop` commands. ## Interaction with invoice diff --git a/apps/cassiopeia/src/bin/cass.rs b/apps/cassiopeia/src/bin/cass.rs new file mode 100644 index 00000000000..cb799d18ccc --- /dev/null +++ b/apps/cassiopeia/src/bin/cass.rs @@ -0,0 +1,62 @@ +use cassiopeia::{self as cass, meta}; +use clap::{App, Arg, SubCommand}; + +fn main() { + let app = App::new(meta::NAME) + .version(meta::VERSION) + .about(meta::ABOUT) + .after_help("To learn more on how to use cassiopeia, check out the documentation \ + at https://git.spacekookie.de/kookienomicon/tree/apps/cassiopeia +If you want to report a bug, please do so on my mailing list: lists.sr.ht/~spacekookie/public-inbox") + .author(meta::AUTHOR) + .setting(clap::AppSettings::SubcommandRequiredElseHelp) + .global_settings(&[ + clap::AppSettings::DisableHelpSubcommand, + clap::AppSettings::VersionlessSubcommands, + ]) + .arg( + Arg::with_name(meta::ARG_FILE) + .short("f") + .long("file") + .help(meta::ARG_FILE_ABOUT) + .default_value("./time.cass") + .takes_value(true), + ) + .subcommand( + SubCommand::with_name(meta::CMD_START) + .about(meta::CMD_START_ABOUT) + .arg(Arg::with_name(meta::ARG_ROUNDING).help(meta::ARG_ROUNDING_ABOUT)), + ) + .subcommand( + SubCommand::with_name(meta::CMD_STOP) + .about(meta::CMD_STOP_ABOUT) + .arg(Arg::with_name(meta::ARG_ROUNDING).help(meta::ARG_ROUNDING_ABOUT)), + ) + .subcommand( + SubCommand::with_name(meta::CMD_INVOICE) + .about(meta::CMD_INVOICE_ABOUT) + .arg( + Arg::with_name(meta::ARG_CLIENT) + .short("c") + .long("client") + .takes_value(true) + .help(meta::ARG_CLIENT_ABOUT), + ) + .arg( + Arg::with_name(meta::ARG_PROJECT) + .short("p") + .long("project") + .takes_value(true) + .help(meta::ARG_PROJECT_ABOUT), + ) + .arg( + Arg::with_name(meta::ARG_GEN_YAML) + .short("g") + .long("gen") + .help(meta::ARG_GEN_YAML_ABOUT), + ), + ) + .get_matches(); + + let file = cass::load_file("/home/projects/clients/nyantec-nix-workshops/time.cass"); +} diff --git a/apps/cassiopeia/src/format/mod.rs b/apps/cassiopeia/src/format/mod.rs index bac0445d838..b5342d62da1 100644 --- a/apps/cassiopeia/src/format/mod.rs +++ b/apps/cassiopeia/src/format/mod.rs @@ -9,10 +9,7 @@ pub(crate) use parser::LineCfg; use crate::TimeFile; use std::{fs::File, io::Read}; -/// The cassiopeia parser/generator version to be written back into the file -pub const CASS_VERSION: &str = env!("CARGO_PKG_VERSION"); - -pub(crate) fn load_file(path: &str) -> TimeFile { +pub fn load_file(path: &str) -> TimeFile { let mut f = File::open(path).unwrap(); let mut content = String::new(); f.read_to_string(&mut content).unwrap(); diff --git a/apps/cassiopeia/src/format/parser.rs b/apps/cassiopeia/src/format/parser.rs index bb2c56be0f3..430fee6332a 100644 --- a/apps/cassiopeia/src/format/parser.rs +++ b/apps/cassiopeia/src/format/parser.rs @@ -4,7 +4,7 @@ //! parsed time file. use crate::format::{LineLexer, LineToken, Token}; -use chrono::{NaiveDate, DateTime, FixedOffset as Offset}; +use chrono::{DateTime, FixedOffset as Offset, NaiveDate}; use std::collections::BTreeMap; use std::iter::Iterator; @@ -36,7 +36,7 @@ impl LineCfg { pub(crate) fn parse<'l>(lex: LineLexer<'l>) -> LineCfg { use LineCfg::*; use Token as T; - + #[cfg_attr(rustfmt, rustfmt_skip)] lex.get_all().into_iter().fold(Ignore, |cfg, tok| match (cfg, tok) { // If the first token is a comment, we ignore it @@ -72,5 +72,8 @@ fn parse_datetime(slice: &str) -> Option> { } fn parse_date(slice: &str) -> Option { - Some(NaiveDate::parse_from_str(slice, "%Y-%m-%d").expect("Failed to parse date; invalid format!")) + Some( + NaiveDate::parse_from_str(slice, "%Y-%m-%d") + .expect("Failed to parse date; invalid format!"), + ) } diff --git a/apps/cassiopeia/src/lib.rs b/apps/cassiopeia/src/lib.rs new file mode 100644 index 00000000000..d7b602bd1c5 --- /dev/null +++ b/apps/cassiopeia/src/lib.rs @@ -0,0 +1,8 @@ +//! Cassiopeia plain text time tracking tool + +mod data; +mod format; +pub mod meta; + +pub use data::{Session, TimeFile}; +pub use format::load_file; diff --git a/apps/cassiopeia/src/main.rs b/apps/cassiopeia/src/main.rs deleted file mode 100644 index ff942731c3d..00000000000 --- a/apps/cassiopeia/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod format; -mod data; - -pub use data::{TimeFile, Session}; - -fn main() { - let file = format::load_file("/home/projects/clients/nyantec-nix-workshops/time.cass"); - -} diff --git a/apps/cassiopeia/src/meta.rs b/apps/cassiopeia/src/meta.rs new file mode 100644 index 00000000000..835444f9bdc --- /dev/null +++ b/apps/cassiopeia/src/meta.rs @@ -0,0 +1,34 @@ +//! Metadata and strings for this application +// TODO: translate this + +pub const NAME: &'static str = env!("CARGO_PKG_NAME"); +pub const VERSION: &'static str = env!("CARGO_PKG_VERSION"); +pub const AUTHOR: &'static str = env!("CARGO_PKG_AUTHORS"); +pub const ABOUT: &'static str = env!("CARGO_PKG_DESCRIPTION"); + +pub const ARG_FILE: &'static str = "CASS_FILE"; +pub const ARG_FILE_ABOUT: &'static str = "Provide a .cass file to operate on"; + +pub const CMD_START: &'static str = "start"; +pub const CMD_START_ABOUT: &'static str = "Start a work session"; + +pub const CMD_STOP: &'static str = "stop"; +pub const CMD_STOP_ABOUT: &'static str = "Stop the current work session"; + +pub const ARG_ROUNDING: &'static str = "CASS_ROUNDING"; +pub const ARG_ROUNDING_ABOUT: &'static str = "Disable the (default) 15 minute rounding period"; + +pub const CMD_INVOICE: &'static str = "invoice"; +pub const CMD_INVOICE_ABOUT: &'static str = "Create an invoice"; + +pub const ARG_CLIENT: &'static str = "CLIENT"; +pub const ARG_CLIENT_ABOUT: &'static str = + "Provide the name of the current client for invoice generation"; + +pub const ARG_PROJECT: &'static str = "PROJECT"; +pub const ARG_PROJECT_ABOUT: &'static str = + "Provide the name of the current project for invoice generation"; + +pub const ARG_GEN_YAML: &'static str = "GEN_YAML"; +pub const ARG_GEN_YAML_ABOUT: &'static str = + "Specify whether to generate a .yml invoice configuration";