fix(time): accept spaced durations and print whole-second times

tea time create 1 1h25m printed 2026-10-11T18:57:49.588823137Z while time
list printed whole seconds, and "1h 30m" or 2d failed with "duration
must be nonzero whole seconds". Durations may now contain spaces, and
errors name the problem: "invalid duration "2d": use h, m and s units
such as 1h25m". Tracked times are whole seconds everywhere.

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-12 00:14:52 +02:00
1 parent 1749d2f7f6
commit b5fecbde42
4 files changed
+54 -7

No files matched your search

+19 -4
View File
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"time"
"gitea.dev/tea/internal/clierr"
@@ -17,6 +18,20 @@ import (
func trackedDuration(seconds int64) time.Duration { return time.Duration(seconds) * time.Second }
// parseSpent reads time spent in whole seconds, written like 1h25m or "1h 25m".
func parseSpent(raw string) (int64, error) {
duration, err := time.ParseDuration(strings.Join(strings.Fields(raw), ""))
switch {
case err != nil:
return 0, clierr.Wrap(clierr.Usage, fmt.Errorf("invalid duration %q: use h, m and s units such as 1h25m", raw))
case duration <= 0:
return 0, clierr.Wrap(clierr.Usage, fmt.Errorf("invalid duration %q: time spent must be positive, such as 1h25m", raw))
case duration%time.Second != 0:
return 0, clierr.Wrap(clierr.Usage, fmt.Errorf("invalid duration %q: use whole seconds, such as 1h25m", raw))
}
return int64(duration / time.Second), nil
}
func (a *application) timeCommand() *cobra.Command {
group := &cobra.Command{Use: "time", Short: "Track time spent on issues and pull requests"}
opts := services.TimeOptions{}
@@ -65,15 +80,15 @@ func (a *application) timeCommand() *cobra.Command {
if err != nil {
return err
}
duration, err := time.ParseDuration(args[1])
if err != nil || duration == 0 || duration%time.Second != 0 {
return clierr.Wrap(clierr.Usage, errors.New("duration must be nonzero whole seconds, for example 1h25m"))
seconds, err := parseSpent(args[1])
if err != nil {
return err
}
target, err := a.resolve(cmd.Context(), true)
if err != nil {
return err
}
item, err := (services.Times{Client: target.client, Repository: target.Repo}).Create(cmd.Context(), n, int64(duration/time.Second))
item, err := (services.Times{Client: target.client, Repository: target.Repo}).Create(cmd.Context(), n, seconds)
if err != nil {
return err
}