1
1
Fork 0
mirror of https://gitea.com/gitea/tea synced 2024-03-28 09:50:08 +01:00

Improve `tea time` (#319)

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 <git@nroo.de>
Reviewed-on: https://gitea.com/gitea/tea/pulls/319
Reviewed-by: 6543 <6543@obermui.de>
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-Authored-By: Norwin <noerw@noreply.gitea.io>
Co-Committed-By: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
Norwin 2020-12-23 12:58:36 +08:00 committed by Lunny Xiao
parent 95ef061711
commit b5c670ebf8
3 changed files with 104 additions and 56 deletions

View File

@ -26,4 +26,5 @@ var CmdTrackedTimes = cli.Command{
&times.CmdTrackedTimesReset,
&times.CmdTrackedTimesList,
},
Flags: times.CmdTrackedTimesList.Flags,
}

View File

@ -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
}

View File

@ -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 ""
}