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 } ;
2021-07-16 12:45:27 -05:00
use chrono ::Utc ;
2021-06-18 11:27:19 -05:00
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-20 10:08:04 -05:00
month ::MonthCommand , list ::ListCommand , out ::OutCommand ,
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 ( ) ? ;
2021-07-03 18:17:26 -05:00
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-07-16 12:45:27 -05:00
let now = Utc ::now ( ) ;
2021-06-18 11:27:19 -05:00
match matches . subcommand ( ) {
2021-07-16 12:45:27 -05:00
( " in " , Some ( matches ) ) = > InCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
2021-07-20 10:08:04 -05:00
( " out " , Some ( matches ) ) = > OutCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
2021-07-06 22:52:20 -05:00
2021-07-16 12:45:27 -05:00
( " display " , Some ( matches ) ) = > DisplayCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
( " today " , Some ( matches ) ) = > TodayCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
( " yesterday " , Some ( matches ) ) = > YesterdayCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
( " week " , Some ( matches ) ) = > WeekCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
( " month " , Some ( matches ) ) = > MonthCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
2021-07-06 22:52:20 -05:00
2021-07-16 12:45:27 -05:00
( " sheet " , Some ( matches ) ) = > SheetCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
( " list " , Some ( matches ) ) = > ListCommand ::handle ( matches . try_into ( ) ? , & mut conn , & mut out , & mut err , & config , now ) ,
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 ( ) {
2021-07-07 12:10:57 -05:00
// 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"
2021-07-07 12:10:57 -05:00
) ;
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 " ) ;
2021-07-07 12:10:57 -05:00
// 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. " )
2021-07-07 12:10:57 -05:00
. 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 " )
2021-06-21 19:54:10 -05:00
. 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. " )
2021-07-07 12:10:57 -05:00
. 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 " )
2021-07-07 12:10:57 -05:00
. 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 " )
2021-07-07 12:10:57 -05:00
. 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-14 12:37:45 -05:00
. arg ( sheet_arg . clone ( ) )
)
. subcommand ( SubCommand ::with_name ( " list " )
. visible_alias ( " l " )
. about ( " List existing sheets " )
. arg ( Arg ::with_name ( " all " )
2021-07-15 16:36:24 -05:00
. short ( " a " ) . long ( " all " )
2021-07-14 12:37:45 -05:00
. help ( " List archive sheets also " ) )
2021-06-18 11:27:19 -05:00
)
. get_matches ( ) ;
if let Err ( e ) = error_trap ( matches ) {
eprintln! ( " {} " , e ) ;
exit ( 1 ) ;
}
}