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;
|
|
|
|
use tiempo::commands::{ Command, r#in::InCommand, display::DisplayCommand, };
|
|
|
|
|
|
|
|
fn error_trap(matches: ArgMatches) -> error::Result<()> {
|
|
|
|
let config = Config::read()?;
|
|
|
|
|
2021-06-21 11:12:30 -05:00
|
|
|
let mut conn = SqliteDatabase::from_path(config.database_file)?;
|
2021-06-18 11:27:19 -05:00
|
|
|
let mut out = io::stdout();
|
|
|
|
|
|
|
|
match matches.subcommand() {
|
|
|
|
("in", Some(matches)) => InCommand::handle(matches.try_into()?, &mut conn, &mut out),
|
|
|
|
("display", Some(matches)) => DisplayCommand::handle(matches.try_into()?, &mut conn, &mut out),
|
|
|
|
(cmd, _) => Err(error::Error::UnimplementedCommand(cmd.into())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
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(Arg::with_name("start")
|
|
|
|
.long("start")
|
|
|
|
.short("s")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("TIME")
|
|
|
|
.help("Include entries that start on this date or later"))
|
|
|
|
.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"))
|
|
|
|
.arg(Arg::with_name("grep")
|
|
|
|
.long("grep")
|
|
|
|
.short("g")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("REGEXP")
|
|
|
|
.help("Include entries where the note matches this regexp."))
|
|
|
|
)
|
|
|
|
|
|
|
|
.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.")
|
|
|
|
)
|
|
|
|
|
|
|
|
.subcommand(SubCommand::with_name("in")
|
|
|
|
.visible_alias("i")
|
|
|
|
.about("Start an activity in the current timesheet")
|
|
|
|
.arg(Arg::with_name("at")
|
|
|
|
.long("at")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("TIME")
|
|
|
|
.help("Use this time instead of now"))
|
|
|
|
.arg(Arg::with_name("note")
|
|
|
|
.takes_value(true)
|
|
|
|
.value_name("NOTE")
|
|
|
|
.help("Text describing the activity to start"))
|
|
|
|
)
|
|
|
|
|
|
|
|
.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")
|
|
|
|
)
|
|
|
|
|
|
|
|
.get_matches();
|
|
|
|
|
|
|
|
if let Err(e) = error_trap(matches) {
|
|
|
|
eprintln!("{}", e);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|