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:
parent
95ef061711
commit
b5c670ebf8
|
@ -26,4 +26,5 @@ var CmdTrackedTimes = cli.Command{
|
||||||
×.CmdTrackedTimesReset,
|
×.CmdTrackedTimesReset,
|
||||||
×.CmdTrackedTimesList,
|
×.CmdTrackedTimesList,
|
||||||
},
|
},
|
||||||
|
Flags: times.CmdTrackedTimesList.Flags,
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package times
|
package times
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -23,10 +24,12 @@ var CmdTrackedTimesList = cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Action: RunTimesList,
|
Action: RunTimesList,
|
||||||
Usage: "Operate on tracked times of a repository's issues & pulls",
|
Usage: "List tracked times on issues & pulls",
|
||||||
Description: `Operate on tracked times of a repository's issues & pulls.
|
Description: `List tracked times, across repos, or on a single repo or issue:
|
||||||
Depending on your permissions on the repository, only your own tracked
|
- given a username all times on a repo by that user are shown,
|
||||||
times might be listed.`,
|
- 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]",
|
ArgsUsage: "[username | #issue]",
|
||||||
|
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
|
@ -45,6 +48,17 @@ var CmdTrackedTimesList = cli.Command{
|
||||||
Aliases: []string{"t"},
|
Aliases: []string{"t"},
|
||||||
Usage: "Print the total duration at the end",
|
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...),
|
}, flags.AllDefaultFlags...),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,43 +70,57 @@ func RunTimesList(cmd *cli.Context) error {
|
||||||
|
|
||||||
var times []*gitea.TrackedTime
|
var times []*gitea.TrackedTime
|
||||||
var err error
|
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
|
var from, until time.Time
|
||||||
if ctx.String("from") != "" {
|
var fields []string
|
||||||
|
|
||||||
|
if ctx.IsSet("from") {
|
||||||
from, err = dateparse.ParseLocal(ctx.String("from"))
|
from, err = dateparse.ParseLocal(ctx.String("from"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ctx.String("until") != "" {
|
if ctx.IsSet("until") {
|
||||||
until, err = dateparse.ParseLocal(ctx.String("until"))
|
until, err = dateparse.ParseLocal(ctx.String("until"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,41 +5,60 @@
|
||||||
package print
|
package print
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TrackedTimesList print list of tracked times to stdout
|
// TrackedTimesList print list of tracked times to stdout
|
||||||
func TrackedTimesList(times []*gitea.TrackedTime, outputType string, from, until time.Time, printTotal bool) {
|
func TrackedTimesList(times []*gitea.TrackedTime, outputType string, fields []string, printTotal bool) {
|
||||||
tab := tableWithHeader(
|
var printables = make([]printable, len(times))
|
||||||
"Created",
|
|
||||||
"Issue",
|
|
||||||
"User",
|
|
||||||
"Duration",
|
|
||||||
)
|
|
||||||
var totalDuration int64
|
var totalDuration int64
|
||||||
|
for i, t := range times {
|
||||||
for _, t := range times {
|
|
||||||
if !from.IsZero() && from.After(t.Created) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !until.IsZero() && until.Before(t.Created) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
totalDuration += t.Time
|
totalDuration += t.Time
|
||||||
tab.addRow(
|
printables[i] = &printableTrackedTime{t, outputType}
|
||||||
FormatTime(t.Created),
|
|
||||||
"#"+strconv.FormatInt(t.Issue.Index, 10),
|
|
||||||
t.UserName,
|
|
||||||
formatDuration(t.Time, outputType),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
t := tableFromItems(fields, printables)
|
||||||
|
|
||||||
if printTotal {
|
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 ""
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue