From b5c670ebf8ef207ddec242490a57659edbc49e88 Mon Sep 17 00:00:00 2001 From: Norwin Date: Wed, 23 Dec 2020 12:58:36 +0800 Subject: [PATCH] Improve `tea time` (#319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit better docs add --mine flag hm, is there a better name? 🤔 do time filtering serverside make printed fields dynamic add --fields to tea times ls code review Co-authored-by: Norwin Roosen Reviewed-on: https://gitea.com/gitea/tea/pulls/319 Reviewed-by: 6543 <6543@obermui.de> Reviewed-by: Lunny Xiao Co-Authored-By: Norwin Co-Committed-By: Norwin --- cmd/times.go | 1 + cmd/times/list.go | 88 ++++++++++++++++++++++++++++-------------- modules/print/times.go | 71 +++++++++++++++++++++------------- 3 files changed, 104 insertions(+), 56 deletions(-) diff --git a/cmd/times.go b/cmd/times.go index 3f4c5e5..ffc046c 100644 --- a/cmd/times.go +++ b/cmd/times.go @@ -26,4 +26,5 @@ var CmdTrackedTimes = cli.Command{ ×.CmdTrackedTimesReset, ×.CmdTrackedTimesList, }, + Flags: times.CmdTrackedTimesList.Flags, } diff --git a/cmd/times/list.go b/cmd/times/list.go index 7d225ee..b84ec47 100644 --- a/cmd/times/list.go +++ b/cmd/times/list.go @@ -5,6 +5,7 @@ package times import ( + "fmt" "strings" "time" @@ -23,10 +24,12 @@ var CmdTrackedTimesList = cli.Command{ Name: "list", Aliases: []string{"ls"}, Action: RunTimesList, - Usage: "Operate on tracked times of a repository's issues & pulls", - Description: `Operate on tracked times of a repository's issues & pulls. - Depending on your permissions on the repository, only your own tracked - times might be listed.`, + Usage: "List tracked times on issues & pulls", + Description: `List tracked times, across repos, or on a single repo or issue: +- given a username all times on a repo by that user are shown, +- given a issue index with '#' prefix, all times on that issue are listed, +- given --mine, your times are listed across all repositories. +Depending on your permissions on the repository, only your own tracked times might be listed.`, ArgsUsage: "[username | #issue]", Flags: append([]cli.Flag{ @@ -45,6 +48,17 @@ var CmdTrackedTimesList = cli.Command{ Aliases: []string{"t"}, Usage: "Print the total duration at the end", }, + &cli.BoolFlag{ + Name: "mine", + Aliases: []string{"m"}, + Usage: "Show all times tracked by you across all repositories (overrides command arguments)", + }, + &cli.StringFlag{ + Name: "fields", + Usage: fmt.Sprintf(`Comma-separated list of fields to print. Available values: + %s + `, strings.Join(print.TrackedTimeFields, ",")), + }, }, flags.AllDefaultFlags...), } @@ -56,43 +70,57 @@ func RunTimesList(cmd *cli.Context) error { var times []*gitea.TrackedTime var err error - - user := ctx.Args().First() - if user == "" { - // get all tracked times on the repo - times, _, err = client.ListRepoTrackedTimes(ctx.Owner, ctx.Repo, gitea.ListTrackedTimesOptions{}) - } else if strings.HasPrefix(user, "#") { - // get all tracked times on the specified issue - issue, err := utils.ArgToIndex(user) - if err != nil { - return err - } - times, _, err = client.ListIssueTrackedTimes(ctx.Owner, ctx.Repo, issue, gitea.ListTrackedTimesOptions{}) - } else { - // get all tracked times by the specified user - times, _, err = client.ListRepoTrackedTimes(ctx.Owner, ctx.Repo, gitea.ListTrackedTimesOptions{ - User: user, - }) - } - - if err != nil { - return err - } - var from, until time.Time - if ctx.String("from") != "" { + var fields []string + + if ctx.IsSet("from") { from, err = dateparse.ParseLocal(ctx.String("from")) if err != nil { return err } } - if ctx.String("until") != "" { + if ctx.IsSet("until") { until, err = dateparse.ParseLocal(ctx.String("until")) if err != nil { return err } } - print.TrackedTimesList(times, ctx.Output, from, until, ctx.Bool("total")) + opts := gitea.ListTrackedTimesOptions{Since: from, Before: until} + + user := ctx.Args().First() + if ctx.Bool("mine") { + times, _, err = client.GetMyTrackedTimes() + fields = []string{"created", "repo", "issue", "duration"} + } else if user == "" { + // get all tracked times on the repo + times, _, err = client.ListRepoTrackedTimes(ctx.Owner, ctx.Repo, opts) + fields = []string{"created", "issue", "user", "duration"} + } else if strings.HasPrefix(user, "#") { + // get all tracked times on the specified issue + issue, err := utils.ArgToIndex(user) + if err != nil { + return err + } + times, _, err = client.ListIssueTrackedTimes(ctx.Owner, ctx.Repo, issue, opts) + fields = []string{"created", "user", "duration"} + } else { + // get all tracked times by the specified user + opts.User = user + times, _, err = client.ListRepoTrackedTimes(ctx.Owner, ctx.Repo, opts) + fields = []string{"created", "issue", "duration"} + } + + if err != nil { + return err + } + + if ctx.IsSet("fields") { + if fields, err = flags.GetFields(cmd, print.TrackedTimeFields); err != nil { + return err + } + } + + print.TrackedTimesList(times, ctx.Output, fields, ctx.Bool("total")) return nil } diff --git a/modules/print/times.go b/modules/print/times.go index 9f3c787..0fbfc3b 100644 --- a/modules/print/times.go +++ b/modules/print/times.go @@ -5,41 +5,60 @@ package print import ( - "strconv" - "time" + "fmt" "code.gitea.io/sdk/gitea" ) // TrackedTimesList print list of tracked times to stdout -func TrackedTimesList(times []*gitea.TrackedTime, outputType string, from, until time.Time, printTotal bool) { - tab := tableWithHeader( - "Created", - "Issue", - "User", - "Duration", - ) +func TrackedTimesList(times []*gitea.TrackedTime, outputType string, fields []string, printTotal bool) { + var printables = make([]printable, len(times)) var totalDuration int64 - - for _, t := range times { - if !from.IsZero() && from.After(t.Created) { - continue - } - if !until.IsZero() && until.Before(t.Created) { - continue - } - + for i, t := range times { totalDuration += t.Time - tab.addRow( - FormatTime(t.Created), - "#"+strconv.FormatInt(t.Issue.Index, 10), - t.UserName, - formatDuration(t.Time, outputType), - ) + printables[i] = &printableTrackedTime{t, outputType} } + t := tableFromItems(fields, printables) if printTotal { - tab.addRow("TOTAL", "", "", formatDuration(totalDuration, outputType)) + total := make([]string, len(fields)) + total[0] = "TOTAL" + total[len(fields)-1] = formatDuration(totalDuration, outputType) + t.addRowSlice(total) } - tab.print(outputType) + + t.print(outputType) +} + +// TrackedTimeFields contains all available fields for printing of tracked times. +var TrackedTimeFields = []string{ + "id", + "created", + "repo", + "issue", + "user", + "duration", +} + +type printableTrackedTime struct { + *gitea.TrackedTime + outputFormat string +} + +func (t printableTrackedTime) FormatField(field string) string { + switch field { + case "id": + return fmt.Sprintf("%d", t.ID) + case "created": + return FormatTime(t.Created) + case "repo": + return t.Issue.Repository.FullName + case "issue": + return fmt.Sprintf("#%d", t.Issue.Index) + case "user": + return t.UserName + case "duration": + return formatDuration(t.Time, t.outputFormat) + } + return "" }