@@ -12,10 +12,12 @@ import (
1212 "path"
1313 "path/filepath"
1414 "strings"
15+ "time"
1516
1617 "github.com/charmbracelet/lipgloss"
1718 c "github.com/dhth/hours/internal/common"
1819 pers "github.com/dhth/hours/internal/persistence"
20+ "github.com/dhth/hours/internal/types"
1921 "github.com/dhth/hours/internal/ui"
2022 "github.com/spf13/cobra"
2123)
@@ -150,6 +152,7 @@ func NewRootCommand() (*cobra.Command, error) {
150152 reportAgg bool
151153 recordsInteractive bool
152154 recordsOutputPlain bool
155+ taskStatusStr string
153156 activeTemplate string
154157 genNumDays uint8
155158 genNumTasks uint8
@@ -271,13 +274,15 @@ create dummy entries in it. You can run it on a throwaway database by passing a
271274path for it via --dbpath/-d (use it for all further invocations of 'hours' as
272275well).
273276` ))
274- fmt .Print (`
277+ fmt .Printf (`
275278The 'gen' subcommand is intended for new users of 'hours' so they can get a
276279sense of its capabilities without actually tracking any time.
277280
281+ Running with --dbpath set to: %q
282+
278283---
279284
280- ` )
285+ ` , dbPathFull )
281286 confirm , err := getConfirmation ()
282287 if err != nil {
283288 return err
@@ -294,9 +299,6 @@ sense of its capabilities without actually tracking any time.
294299 fmt .Printf (`
295300Successfully generated dummy data in the database file: %s
296301
297- If this is not the default database file path, use --dbpath/-d with 'hours' when
298- you want to access the dummy data.
299-
300302Go ahead and try the following!
301303
302304hours --dbpath=%s
@@ -309,7 +311,7 @@ hours --dbpath=%s stats today -i
309311 }
310312
311313 reportCmd := & cobra.Command {
312- Use : "report" ,
314+ Use : "report [PERIOD] " ,
313315 Short : "Output a report based on task log entries" ,
314316 Long : `Output a report based on task log entries.
315317
@@ -319,90 +321,132 @@ cumulative time spent on each task per day.
319321
320322Accepts an argument, which can be one of the following:
321323
322- today: for today's report
323- yest: for yesterday's report
324- 3d: for a report on the last 3 days (default)
325- week: for a report on the current week
326- date: for a report for a specific date (eg. "2024/06/08")
327- range: for a report for a date range (eg. "2024/06/08...2024/06/12")
324+ today for today's report
325+ yest for yesterday's report
326+ 3d for a report on the last 3 days (default)
327+ week for a report on the current week
328+ date for a report for a specific date (eg. "2024/06/08")
329+ range for a report for a date range (eg. "2024/06/08...2024/06/12")
328330
329331Note: If a task log continues past midnight in your local timezone, it
330332will be reported on the day it ends.
331333` ,
332334 Args : cobra .MaximumNArgs (1 ),
333335 PreRunE : preRun ,
334336 RunE : func (_ * cobra.Command , args []string ) error {
337+ taskStatus , err := types .ParseTaskStatus (taskStatusStr )
338+ if err != nil {
339+ return err
340+ }
341+
335342 var period string
336343 if len (args ) == 0 {
337344 period = "3d"
338345 } else {
339346 period = args [0 ]
340347 }
341348
342- return ui .RenderReport (db , style , os .Stdout , recordsOutputPlain , period , reportAgg , recordsInteractive )
349+ var fullWeek bool
350+ if recordsInteractive {
351+ fullWeek = true
352+ }
353+ dateRange , err := types .GetDateRangeFromPeriod (period , time .Now (), fullWeek )
354+ if err != nil {
355+ return err
356+ }
357+
358+ return ui .RenderReport (db , style , os .Stdout , recordsOutputPlain , dateRange , period , taskStatus , reportAgg , recordsInteractive )
343359 },
344360 }
345361
346362 logCmd := & cobra.Command {
347- Use : "log" ,
363+ Use : "log [PERIOD] " ,
348364 Short : "Output task log entries" ,
349365 Long : `Output task log entries.
350366
351367Accepts an argument, which can be one of the following:
352368
353- today: for log entries from today (default)
354- yest: for log entries from yesterday
355- 3d: for log entries from the last 3 days
356- week: for log entries from the current week
357- date: for log entries from a specific date (eg. "2024/06/08")
358- range: for log entries from a specific date range (eg. "2024/06/08...2024/06/12")
369+ today for log entries from today (default)
370+ yest for log entries from yesterday
371+ 3d for log entries from the last 3 days
372+ week for log entries from the current week
373+ date for log entries from a specific date (eg. "2024/06/08")
374+ range for log entries from a specific date range (eg. "2024/06/08...2024/06/12")
359375
360376Note: If a task log continues past midnight in your local timezone, it'll
361377appear in the log for the day it ends.
362378` ,
363379 Args : cobra .MaximumNArgs (1 ),
364380 PreRunE : preRun ,
365381 RunE : func (_ * cobra.Command , args []string ) error {
382+ taskStatus , err := types .ParseTaskStatus (taskStatusStr )
383+ if err != nil {
384+ return err
385+ }
386+
366387 var period string
367388 if len (args ) == 0 {
368389 period = "today"
369390 } else {
370391 period = args [0 ]
371392 }
372393
373- return ui .RenderTaskLog (db , style , os .Stdout , recordsOutputPlain , period , recordsInteractive )
394+ dateRange , err := types .GetDateRangeFromPeriod (period , time .Now (), false )
395+ if err != nil {
396+ return err
397+ }
398+
399+ return ui .RenderTaskLog (db , style , os .Stdout , recordsOutputPlain , dateRange , period , taskStatus , recordsInteractive )
374400 },
375401 }
376402
377403 statsCmd := & cobra.Command {
378- Use : "stats" ,
404+ Use : "stats [PERIOD] " ,
379405 Short : "Output statistics for tracked time" ,
380406 Long : `Output statistics for tracked time.
381407
382408Accepts an argument, which can be one of the following:
383409
384- today: show stats for today
385- yest: show stats for yesterday
386- 3d: show stats for the last 3 days (default)
387- week: show stats for the current week
388- date: show stats for a specific date (eg. "2024/06/08")
389- range: show stats for a specific date range (eg. "2024/06/08...2024/06/12")
390- all: show stats for all log entries
410+ today show stats for today
411+ yest show stats for yesterday
412+ 3d show stats for the last 3 days (default)
413+ week show stats for the current week
414+ date show stats for a specific date (eg. "2024/06/08")
415+ range show stats for a specific date range (eg. "2024/06/08...2024/06/12")
416+ all show stats for all log entries
391417
392418Note: If a task log continues past midnight in your local timezone, it'll
393419be considered in the stats for the day it ends.
394420` ,
395421 Args : cobra .MaximumNArgs (1 ),
396422 PreRunE : preRun ,
397423 RunE : func (_ * cobra.Command , args []string ) error {
424+ taskStatus , err := types .ParseTaskStatus (taskStatusStr )
425+ if err != nil {
426+ return err
427+ }
428+
398429 var period string
399430 if len (args ) == 0 {
400431 period = "3d"
401432 } else {
402433 period = args [0 ]
403434 }
404435
405- return ui .RenderStats (db , style , os .Stdout , recordsOutputPlain , period , recordsInteractive )
436+ var fullWeek bool
437+ if recordsInteractive {
438+ fullWeek = true
439+ }
440+ var dateRange types.DateRange
441+ if period != "all" {
442+ dateRange , err = types .GetDateRangeFromPeriod (period , time .Now (), fullWeek )
443+ if err != nil {
444+ return err
445+ }
446+
447+ }
448+
449+ return ui .RenderStats (db , style , os .Stdout , recordsOutputPlain , & dateRange , period , taskStatus , recordsInteractive )
406450 },
407451 }
408452
@@ -534,20 +578,23 @@ eg. hours active -t ' {{task}} ({{time}}) '
534578 reportCmd .Flags ().BoolVarP (& recordsInteractive , "interactive" , "i" , false , "whether to view report interactively" )
535579 reportCmd .Flags ().BoolVarP (& recordsOutputPlain , "plain" , "p" , false , "whether to output report without any formatting" )
536580 reportCmd .Flags ().StringVarP (& dbPath , "dbpath" , "d" , defaultDBPath , "location of hours' database file" )
581+ reportCmd .Flags ().StringVarP (& taskStatusStr , "task-status" , "s" , "any" , fmt .Sprintf ("only show data for tasks with this status [possible values: %q]" , types .ValidTaskStatusValues ))
537582 reportCmd .Flags ().StringVarP (& themeName , "theme" , "t" , defaultThemeName ,
538- fmt .Sprintf ("UI theme to use; themes live in %s " , themesDir ))
583+ fmt .Sprintf ("UI theme to use ( themes live in %q) " , themesDir ))
539584
540585 logCmd .Flags ().BoolVarP (& recordsOutputPlain , "plain" , "p" , false , "whether to output logs without any formatting" )
541586 logCmd .Flags ().BoolVarP (& recordsInteractive , "interactive" , "i" , false , "whether to view logs interactively" )
542587 logCmd .Flags ().StringVarP (& dbPath , "dbpath" , "d" , defaultDBPath , "location of hours' database file" )
588+ logCmd .Flags ().StringVarP (& taskStatusStr , "task-status" , "s" , "any" , fmt .Sprintf ("only show data for tasks with this status [possible values: %q]" , types .ValidTaskStatusValues ))
543589 logCmd .Flags ().StringVarP (& themeName , "theme" , "t" , defaultThemeName ,
544- fmt .Sprintf ("UI theme to use; themes live in %s " , themesDir ))
590+ fmt .Sprintf ("UI theme to use ( themes live in %q) " , themesDir ))
545591
546592 statsCmd .Flags ().BoolVarP (& recordsOutputPlain , "plain" , "p" , false , "whether to output stats without any formatting" )
547593 statsCmd .Flags ().BoolVarP (& recordsInteractive , "interactive" , "i" , false , "whether to view stats interactively" )
548594 statsCmd .Flags ().StringVarP (& dbPath , "dbpath" , "d" , defaultDBPath , "location of hours' database file" )
595+ statsCmd .Flags ().StringVarP (& taskStatusStr , "task-status" , "s" , "any" , fmt .Sprintf ("only show data for tasks with this status [possible values: %q]" , types .ValidTaskStatusValues ))
549596 statsCmd .Flags ().StringVarP (& themeName , "theme" , "t" , defaultThemeName ,
550- fmt .Sprintf ("UI theme to use; themes live in %s " , themesDir ))
597+ fmt .Sprintf ("UI theme to use ( themes live in %q) " , themesDir ))
551598
552599 activeCmd .Flags ().StringVarP (& activeTemplate , "template" , "t" , ui .ActiveTaskPlaceholder , "string template to use for outputting active task" )
553600 activeCmd .Flags ().StringVarP (& dbPath , "dbpath" , "d" , defaultDBPath , "location of hours' database file" )
@@ -572,7 +619,7 @@ func getRandomChars(length int) string {
572619 const charset = "abcdefghijklmnopqrstuvwxyz"
573620
574621 var code string
575- for i := 0 ; i < length ; i ++ {
622+ for range length {
576623 code += string (charset [rand .Intn (len (charset ))])
577624 }
578625 return code
0 commit comments