From 424e82ebc475f03da57a4acd1c930feef5c97ec7 Mon Sep 17 00:00:00 2001 From: tavo Date: Wed, 16 Dec 2020 11:52:36 +0200 Subject: [PATCH] CORE-47 Jira autolog time (#50) Squashed commit of the following: commit c30d3acd06b1235e6fc9c668b7da57fc788cae13 Author: tavo Date: Tue Dec 15 15:48:00 2020 +0200 Style fixes commit d6883403c301a488350c9289ca7782d532cac388 Author: tavo Date: Tue Dec 15 11:45:23 2020 +0200 Add jira auto-log commit 77d0412f45cd57ed78882a6398d5b20c8963325a Author: tavo Date: Tue Dec 15 10:28:30 2020 +0200 no ssh? commit 1463cd9ff810f2c7ed1646c6b15e105bced940af Author: tavo Date: Tue Dec 15 10:23:19 2020 +0200 test with older git2go commit a9f1cf21841952cacbe966f7c33fa8d642c3307e Author: tavo Date: Tue Dec 15 10:11:08 2020 +0200 test with zlib commit 3700484550226305c69745e2b59d1fc4203a7bed Author: tavo Date: Tue Dec 15 09:57:27 2020 +0200 test with win-2019 commit 1783bb62857acf74a9a0430714b62ee1947ec2ed Author: tavo Date: Tue Dec 15 09:37:50 2020 +0200 Install openssl for windows --- command/init.go | 2 +- command/status.go | 5 ++++- project/project.go | 20 +++++++++++++++----- report/report.go | 8 ++++++++ util/string.go | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/command/init.go b/command/init.go index bff83fc..489a22b 100644 --- a/command/init.go +++ b/command/init.go @@ -34,7 +34,7 @@ Usage: gtm init [options] Options: -terminal=true Enable time tracking for terminal (requires Terminal plug-in). - -auto-log="" Enable automatic logging to commits for platform [gitlab]. + -auto-log="" Enable automatic logging to commits for platform [gitlab, jira]. -local=false Initialize gtm locally, ak no push / fetch hooks are added. -tags=tag1,tag2 Add tags to projects, multiple calls appends tags. -clear-tags Clear all tags. diff --git a/command/status.go b/command/status.go index 45f147a..c9f133d 100644 --- a/command/status.go +++ b/command/status.go @@ -43,6 +43,7 @@ Options: -long-duration If total-only, display total pending time in long duration format -tags="" Project tags to report status for, i.e --tags tag1,tag2 -all=false Show status for all projects + -auto-log="" Format output for auto logging time [gitlab, jira] -cwd="" Set cwd (useful for plugins) ` return strings.TrimSpace(helpText) @@ -51,7 +52,7 @@ Options: // Run executes status command with args func (c StatusCmd) Run(args []string) int { var color, terminalOff, appOff, totalOnly, all, profile, longDuration bool - var tags, cwd string + var tags, cwd, autoLog string cmdFlags := flag.NewFlagSet("status", flag.ContinueOnError) cmdFlags.BoolVar(&color, "color", false, "Always output color even if no terminal is detected. Use this with pagers i.e 'less -R' or 'more -R'") cmdFlags.BoolVar(&terminalOff, "terminal-off", false, "Exclude time spent in terminal (Terminal plugin is required)") @@ -60,6 +61,7 @@ func (c StatusCmd) Run(args []string) int { cmdFlags.BoolVar(&longDuration, "long-duration", false, "Display total time in long duration format") cmdFlags.StringVar(&tags, "tags", "", "Project tags to show status on") cmdFlags.BoolVar(&all, "all", false, "Show status for all projects") + cmdFlags.StringVar(&autoLog, "auto-log", "", "Format time for auto logging") cmdFlags.StringVar(&cwd, "cwd", "", "Set cwd") cmdFlags.BoolVar(&profile, "profile", false, "Enable profiling") cmdFlags.Usage = func() { c.UI.Output(c.Help()) } @@ -102,6 +104,7 @@ func (c StatusCmd) Run(args []string) int { options := report.OutputOptions{ TotalOnly: totalOnly, + AutoLog: autoLog, LongDuration: longDuration, TerminalOff: terminalOff, AppOff: appOff, diff --git a/project/project.go b/project/project.go index 80b69d9..f7c7f41 100644 --- a/project/project.go +++ b/project/project.go @@ -64,10 +64,18 @@ var ( GitLabHooks = map[string]scm.GitHook{ "prepare-commit-msg": { Exe: "git", - Command: "echo -n \"/spend \" >> $1; gtm status -total-only >> $1", + Command: "gtm status --auto-log=gitlab >> $1", RE: regexp.MustCompile( - `(?s)[/:a-zA-Z0-9$_=()"\.\|\-\\ ]*echo\s+-n\s+"/spend\s+"\s+>>\s+\$1;` + - `\s+gtm(.exe"|)\s+status\s+-total-only\s+>>\s+\$1\.*`), + `(?s)[/:a-zA-Z0-9$_=()"\.\|\-\\ ]*gtm(.exe"|)\s+status\s+--auto-log=gitlab\s+>>\s+\$1\.*`), + }, + } + + JiraHooks = map[string]scm.GitHook{ + "prepare-commit-msg": { + Exe: "git", + Command: "gtm status --auto-log=jira >> $1", + RE: regexp.MustCompile( + `(?s)[/:a-zA-Z0-9$_=()"\.\|\-\\ ]*gtm(.exe"|)\s+status\s+--auto-log=jira\s+>>\s+\$1\.*`), }, } ) @@ -221,8 +229,10 @@ func SetupHooks(local bool, gitRepoPath, autoLog string) error { for k, v := range GitLabHooks { GitHooks[k] = v } - case "github": - // TODO Add hooks + case "jira": + for k, v := range JiraHooks { + GitHooks[k] = v + } } if err := scm.SetHooks(GitHooks, gitRepoPath); err != nil { diff --git a/report/report.go b/report/report.go index 3ce1cc4..1e01052 100644 --- a/report/report.go +++ b/report/report.go @@ -43,6 +43,7 @@ type OutputOptions struct { Color bool Limit int Subdir string + AutoLog string } func (o OutputOptions) limitNotes(notes commitNoteDetails) commitNoteDetails { @@ -64,6 +65,13 @@ func Status(n note.CommitNote, options OutputOptions, projPath ...string) (strin n = n.FilterOutApp() } + switch options.AutoLog { + case "gitlab": + return fmt.Sprintf("/spend %s", util.DurationStr(n.Total())), nil + case "jira": + return fmt.Sprintf("#time %s", util.DurationStrJira(n.Total())), nil + } + if options.TotalOnly { if options.LongDuration { return util.DurationStrLong(n.Total()), nil diff --git a/util/string.go b/util/string.go index c4daadc..65b56a6 100644 --- a/util/string.go +++ b/util/string.go @@ -14,6 +14,13 @@ import ( "github.com/hako/durafmt" ) +const ( + SecInMinute = 60 + MinInHour = 60 + HoursInDay = 8 + DaysInWeek = 5 +) + // Percent returns a values percent of the total func Percent(val, total int) float64 { if total == 0 { @@ -43,6 +50,16 @@ func DurationStr(secs int) string { return (time.Duration(secs) * time.Second).String() } +// DurationStrJira returns seconds as duration string, i.e. 1d 9h 10m +func DurationStrJira(secs int) string { + total := (time.Duration(secs) * time.Second).Truncate(time.Second).Seconds() + weeks := int(total / (DaysInWeek * HoursInDay * MinInHour * SecInMinute)) + days := int(total/(HoursInDay*MinInHour*SecInMinute)) % DaysInWeek + hours := int(total/(MinInHour*SecInMinute)) % HoursInDay + minutes := int(total/SecInMinute) % SecInMinute + return fmt.Sprintf("%dw %dd %dh %dm", weeks, days, hours, minutes) +} + // DurationStrLong returns a human readable format for the duration func DurationStrLong(secs int) string { d, err := durafmt.ParseString(DurationStr(secs))