tiempo-rs/src/main.rs

254 lines
9.9 KiB
Rust
Raw Normal View History

2021-06-18 11:27:19 -05:00
use std::convert::TryInto;
use std::process::exit;
use std::io;
use clap::{App, Arg, SubCommand, AppSettings, crate_version, ArgMatches};
use tiempo::error;
use tiempo::database::SqliteDatabase;
use tiempo::config::Config;
2021-07-01 23:44:38 -05:00
use tiempo::commands::{
Command, r#in::InCommand, display::DisplayCommand, sheet::SheetCommand,
2021-07-07 13:44:19 -05:00
today::TodayCommand, yesterday::YesterdayCommand, week::WeekCommand,
2021-07-07 13:52:40 -05:00
month::MonthCommand,
2021-07-01 23:44:38 -05:00
};
2021-06-18 11:27:19 -05:00
fn error_trap(matches: ArgMatches) -> error::Result<()> {
let config = Config::read()?;
let mut conn = SqliteDatabase::from_path_or_create(&config.database_file)?;
2021-06-18 11:27:19 -05:00
let mut out = io::stdout();
2021-06-29 12:02:33 -05:00
let mut err = io::stderr();
2021-06-18 11:27:19 -05:00
match matches.subcommand() {
2021-06-29 12:02:33 -05:00
("in", Some(matches)) => InCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-06 22:52:20 -05:00
2021-06-29 12:02:33 -05:00
("display", Some(matches)) => DisplayCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-06 22:52:20 -05:00
("today", Some(matches)) => TodayCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-07 11:58:13 -05:00
("yesterday", Some(matches)) => YesterdayCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-07 13:44:19 -05:00
("week", Some(matches)) => WeekCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-07 13:52:40 -05:00
("month", Some(matches)) => MonthCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-06 22:52:20 -05:00
2021-07-01 23:44:38 -05:00
("sheet", Some(matches)) => SheetCommand::handle(matches.try_into()?, &mut conn, &mut out, &mut err, &config),
2021-07-06 22:52:20 -05:00
2021-06-18 11:27:19 -05:00
(cmd, _) => Err(error::Error::UnimplementedCommand(cmd.into())),
}
}
fn main() {
// Lets first declar some args that repeat here and there
let start_arg = Arg::with_name("start")
.long("start").short("s")
.takes_value(true).value_name("TIME")
.help("Include entries that start on this date or later");
let end_arg = Arg::with_name("end")
.long("end").short("e")
.takes_value(true).value_name("TIME")
.help("Include entries that start on this date or earlier");
let ids_arg = Arg::with_name("ids")
.short("v").long("ids")
.help("Print database ids (for use with edit)");
let grep_arg = Arg::with_name("grep")
.long("grep").short("g")
.takes_value(true).value_name("REGEXP")
.help("Include entries where the note matches this regexp.");
let format_arg = Arg::with_name("format")
.short("f").long("format")
.takes_value(true).value_name("FORMAT").default_value("text")
.help(
"The output format. Valid built-in formats are ical, csv, json, \
ids, and text. Documentation on defining custom formats can be \
2021-07-07 12:12:42 -05:00
found at https://gitlab.com/categulario/tiempo"
);
let sheet_arg = Arg::with_name("sheet")
.takes_value(true).value_name("SHEET")
.help(
"The sheet to display. Pass 'all' to see entries from all sheets \
or 'full' to see hidden entries"
);
2021-07-10 14:17:59 -05:00
let at_arg = Arg::with_name("at")
.long("at")
.takes_value(true).value_name("TIME")
.help("Use this time instead of now");
let id_arg = Arg::with_name("id")
.long("id")
.takes_value(true).value_name("ID")
.help("Use entry with ID instead of the last entry");
// Now declar this app's cli
2021-06-18 11:27:19 -05:00
let matches = App::new("Tiempo")
.name("t")
.setting(AppSettings::SubcommandRequired)
.version(crate_version!())
.author("Abraham Toriz <categulario@gmail.com>")
.about("Tiempo helps you keep track of time spent in different activities")
.subcommand(SubCommand::with_name("archive")
.visible_alias("a")
.about("Move entries to a hidden sheet (by default named '_[SHEET]') so they're out of the way.")
.arg(start_arg.clone())
.arg(end_arg.clone())
.arg(grep_arg.clone())
2021-06-18 11:27:19 -05:00
)
.subcommand(SubCommand::with_name("backend")
.visible_alias("b")
.about("Open an sqlite shell to the database.")
)
.subcommand(SubCommand::with_name("configure")
.visible_alias("c")
.about("Configure tiempo. Print path to config file.")
.arg(Arg::with_name("round_in_seconds")
.long("round-in-seconds")
.takes_value(true)
.value_name("SECONDS")
.help("The duration of time to use for rounding with the -r flag"))
.arg(Arg::with_name("database_file")
.long("database-file")
.takes_value(true)
.value_name("PATH")
.help("The file path of the sqlite database"))
.arg(Arg::with_name("append_notes_delimiter")
.long("append-notes-delimiter")
.takes_value(true)
.value_name("DELIMITER")
.help("delimiter used when appending notes via t edit --append"))
.arg(Arg::with_name("formatter_search_paths")
.long("formatter-search-paths")
.takes_value(true)
.value_name("PATHS")
.help("comma separated directories to search for user defined fomatter classes"))
.arg(Arg::with_name("default_formatter")
.long("default-formatter")
.takes_value(true)
.value_name("FORMATTER")
.help("The format to use when display is invoked without a `--format` option"))
.arg(Arg::with_name("require_note")
.long("require-note")
.help("Prompt for a note if one isn't provided when checking in"))
.arg(Arg::with_name("no_require_note")
.long("no-require-note")
.help("Prompt for a note if one isn't provided when checking in"))
.arg(Arg::with_name("note_editor")
.long("note-editor")
.takes_value(true)
.value_name("EDITOR")
.help("Command to launch notes editor or false if no editor use."))
.arg(Arg::with_name("week_start")
.long("week-start")
.takes_value(true)
.value_name("DAY")
.help("The day of the week to use as the start of the week for t week."))
)
.subcommand(SubCommand::with_name("display")
.visible_alias("d")
.about("Display the current timesheet or a specific. Pass `all' as SHEET to display all unarchived sheets or `full' to display archived and unarchived sheets.")
.arg(ids_arg.clone())
.arg(start_arg.clone())
.arg(end_arg.clone())
.arg(format_arg.clone())
.arg(grep_arg.clone())
.arg(sheet_arg.clone())
2021-07-06 22:52:20 -05:00
)
.subcommand(SubCommand::with_name("today")
.visible_alias("t")
.about("Display entries that started today")
.arg(ids_arg.clone())
.arg(end_arg.clone())
.arg(format_arg.clone())
.arg(grep_arg.clone())
.arg(sheet_arg.clone())
2021-06-18 11:27:19 -05:00
)
2021-07-07 11:58:13 -05:00
.subcommand(SubCommand::with_name("yesterday")
.visible_alias("y")
.about("Display entries that started yesterday")
.arg(ids_arg.clone())
.arg(format_arg.clone())
.arg(grep_arg.clone())
.arg(sheet_arg.clone())
2021-07-07 11:58:13 -05:00
)
2021-07-07 13:44:19 -05:00
.subcommand(SubCommand::with_name("week")
.visible_alias("w")
.about("Display entries starting last monday or later")
.arg(ids_arg.clone())
.arg(end_arg.clone())
.arg(format_arg.clone())
.arg(grep_arg.clone())
.arg(sheet_arg.clone())
)
2021-07-07 13:52:40 -05:00
.subcommand(SubCommand::with_name("month")
.visible_alias("m")
.about("Display entries starting this month")
.arg(ids_arg.clone())
.arg(format_arg.clone())
.arg(grep_arg.clone())
.arg(sheet_arg.clone())
2021-07-10 13:20:42 -05:00
.arg(Arg::with_name("month")
.long("month").short("m")
.takes_value(true).value_name("TIME")
.aliases(&["s", "start"])
.possible_values(&[
2021-07-10 13:27:38 -05:00
"this", "current", "last", "jan", "january", "feb",
"february", "mar", "march", "apr", "april", "may", "jun",
"june", "jul", "july", "aug", "august", "sep", "september",
"oct", "october", "nov", "november", "dic", "december",
2021-07-10 13:20:42 -05:00
])
.hide_possible_values(true)
.help(
"Include entries of the specified month instead of the \
current month"
)
)
2021-07-07 13:52:40 -05:00
)
2021-06-18 11:27:19 -05:00
.subcommand(SubCommand::with_name("in")
.visible_alias("i")
.about("Start an activity in the current timesheet")
2021-07-10 14:17:59 -05:00
.arg(at_arg.clone())
2021-06-18 11:27:19 -05:00
.arg(Arg::with_name("note")
.takes_value(true)
.value_name("NOTE")
.help("Text describing the activity to start"))
)
2021-07-10 14:17:59 -05:00
.subcommand(SubCommand::with_name("resume")
.visible_alias("r")
.about("Restart the timer for an entry. Defaults to the last active entry")
.arg(at_arg.clone())
.arg(id_arg.clone())
)
2021-06-18 11:27:19 -05:00
.subcommand(SubCommand::with_name("out")
.visible_alias("o")
.about("end the active entry in the current timesheet")
)
.subcommand(SubCommand::with_name("sheet")
.visible_alias("s")
.about("Change active timesheet or list existing timesheets")
2021-07-01 23:44:38 -05:00
.arg(Arg::with_name("sheet")
.takes_value(true).value_name("SHEET")
.help("The sheet to switch to, creating it if necessary"))
2021-06-18 11:27:19 -05:00
)
.get_matches();
if let Err(e) = error_trap(matches) {
eprintln!("{}", e);
exit(1);
}
}