From 5927b657f98d443c975ec720950bf8b449b8a786 Mon Sep 17 00:00:00 2001 From: Olivier Tremblay Date: Thu, 26 May 2016 15:33:47 -0400 Subject: [PATCH] Some fixes --- cmd/jkl/edit.go | 4 ++-- cmd/jkl/jkl.go | 6 +++++- cmd/jkl/list.go | 37 ++++++++++++++++++++++++++----------- issue.go | 49 ++++++++++++++++++++++++++++++++++++++----------- jkl.go | 2 +- 5 files changed, 72 insertions(+), 26 deletions(-) diff --git a/cmd/jkl/edit.go b/cmd/jkl/edit.go index 8589032..87aef2d 100644 --- a/cmd/jkl/edit.go +++ b/cmd/jkl/edit.go @@ -16,8 +16,8 @@ type EditCmd struct { file string } -func NewEditCmd(args []string) (*CreateCmd, error) { - ccmd := &CreateCmd{project: os.Getenv("JIRA_PROJECT")} +func NewEditCmd(args []string) (*EditCmd, error) { + ccmd := &EditCmd{project: os.Getenv("JIRA_PROJECT")} f := flag.NewFlagSet("x", flag.ExitOnError) f.StringVar(&ccmd.project, "p", "", "Jira project key") f.StringVar(&ccmd.file, "f", "filename", "File to get issue description from") diff --git a/cmd/jkl/jkl.go b/cmd/jkl/jkl.go index deca4a3..9a40813 100644 --- a/cmd/jkl/jkl.go +++ b/cmd/jkl/jkl.go @@ -41,7 +41,11 @@ func findRCFile() { func runcmd(args []string) error { switch args[0] { case "list": - return List(flag.Args()[1:]) + lcmd, err := NewListCmd(flag.Args()[1:]) + if err != nil { + return err + } + return lcmd.List() case "create": ccmd, err := NewCreateCmd(flag.Args()[1:]) if err != nil { diff --git a/cmd/jkl/list.go b/cmd/jkl/list.go index 14640c8..b168417 100644 --- a/cmd/jkl/list.go +++ b/cmd/jkl/list.go @@ -12,14 +12,6 @@ import ( "otremblay.com/jkl" ) -var listTemplateStr string -var listTemplate *template.Template - -func init() { - flag.StringVar(&listTemplateStr, "listTemplate", "{{.Color}}{{.Key}}{{if .Color}}\x1b[39m{{end}}\t({{.Fields.IssueType.Name}}{{if .Fields.Parent}} of {{.Fields.Parent.Key}}{{end}})\t{{.Fields.Summary}}\t[{{.Fields.Assignee.Name}}]\n", "Go template used in list command") - listTemplate = template.Must(template.New("listTemplate").Parse(listTemplateStr)) -} - type listissue jkl.Issue func (l *listissue) Color() string { @@ -42,14 +34,37 @@ func (l *listissue) Color() string { return "" } -func List(args []string) error { - if issues, err := jkl.List(strings.Join(args, " ")); err != nil { +type ListCmd struct { + args []string + tmplstr string + tmpl *template.Template +} + +func NewListCmd(args []string) (*ListCmd, error) { + ccmd := &ListCmd{} + f := flag.NewFlagSet("x", flag.ExitOnError) + f.StringVar(&ccmd.tmplstr, "listTemplate", "{{.Color}}{{.Key}}{{if .Color}}\x1b[39m{{end}}\t({{.Fields.IssueType.Name}}{{if .Fields.Parent}} of {{.Fields.Parent.Key}}{{end}})\t{{.Fields.Summary}}\t{{if .Fields.Assignee}}[{{.Fields.Assignee.Name}}]{{end}}\n", "Go template used in list command") + f.Parse(args) + ccmd.args = f.Args() + if len(ccmd.args) == 0 { + proj := os.Getenv("JIRA_PROJECT") + if proj != "" { + proj = fmt.Sprintf(" and project = %s ", proj) + } + ccmd.args = []string{fmt.Sprintf("sprint in openSprints() %s order by rank", proj)} + } + ccmd.tmpl = template.Must(template.New("listTemplate").Parse(ccmd.tmplstr)) + return ccmd, nil +} + +func (l *ListCmd) List() error { + if issues, err := jkl.List(strings.Join(l.args, " ")); err != nil { return err } else { for _, issue := range issues { var li listissue li = listissue(*issue) - err := listTemplate.Execute(os.Stdout, &li) + err := l.tmpl.Execute(os.Stdout, &li) if err != nil { fmt.Fprintln(os.Stderr, err) } diff --git a/issue.go b/issue.go index 9de94fd..df124cd 100644 --- a/issue.go +++ b/issue.go @@ -2,6 +2,7 @@ package jkl import ( "bytes" + "fmt" "log" "text/template" ) @@ -35,16 +36,41 @@ type Status struct { Name string } -type Fields struct { - *IssueType `json:"issuetype,omitempty"` - Assignee *Author `json:",omitempty"` - Project *Project `json:"project,omitempty"` - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - Comment *CommentColl `json:"comment,omitempty"` - Parent *Issue `json:",omitempty"` - Status *Status `json:",omitempty"` +type TimeTracking struct { + OriginalEstimateSeconds int + RemainingEstimateSeconds int } + +type Fields struct { + *IssueType `json:"issuetype,omitempty"` + Assignee *Author `json:",omitempty"` + Project *Project `json:"project,omitempty"` + Summary string `json:"summary,omitempty"` + Description string `json:"description,omitempty"` + Comment *CommentColl `json:"comment,omitempty"` + Parent *Issue `json:",omitempty"` + Status *Status `json:",omitempty"` + TimeTracking *TimeTracking `json:"timetracking,omitempty"` +} + +func (f *Fields) PrettyRemaining() string { + return PrettySeconds(f.TimeTracking.RemainingEstimateSeconds) +} + +func (f *Fields) PrettyOriginalEstimate() string { + return PrettySeconds(f.TimeTracking.OriginalEstimateSeconds) +} + +func PrettySeconds(seconds int) string { + //This works because it's an integer division. + days := seconds / 3600 / 8 + hours := seconds/3600 - (days * 8) + minutes := (seconds - (hours * 3600) - (days * 8 * 3600)) / 60 + seconds = (seconds - (hours * 3600) - (minutes * 60) - (days * 8 * 3600)) + + return fmt.Sprintf("%dd %2dh %2dm %2ds", days, hours, minutes, seconds) +} + type Issue struct { Key string `json:"key,omitempty"` Fields *Fields `json:"fields"` @@ -68,8 +94,9 @@ var commentTemplate = `{{if .Fields.Comment }}{{range .Fields.Comment.Comments}} {{end}}{{end}}` var issueTmplTxt = "\x1b[1m{{.Key}}\x1b[0m\t{{if .Fields.IssueType}}[{{.Fields.IssueType.Name}}]{{end}}\t{{.Fields.Summary}}\n\n" + - "\x1b[1mStatus\x1b[0m:\t {{.Fields.Status.Name}}\n" + - "\x1b[1mAssignee:\x1b[0m\t{{.Fields.Assignee.Name}}\n\n" + + "{{if .Fields.Status}}\x1b[1mStatus\x1b[0m:\t {{.Fields.Status.Name}}\n{{end}}" + + "{{if .Fields.Assignee}}\x1b[1mAssignee:\x1b[0m\t{{.Fields.Assignee.Name}}\n{{end}}\n" + + "\x1b[1mTime Remaining/Original Estimate:\x1b[0m\t{{.Fields.PrettyRemaining}} / {{.Fields.PrettyOriginalEstimate}}\n\n" + "\x1b[1mDescription:\x1b[0m {{.Fields.Description}} \n\n" + "\x1b[1mComments:\x1b[0m\n\n" + commentTemplate diff --git a/jkl.go b/jkl.go index 4557063..b0a5411 100644 --- a/jkl.go +++ b/jkl.go @@ -24,7 +24,7 @@ func Create(issue *Issue) error { if err != nil { return err } - fmt.Println(issue) + // fmt.Println(issue) resp, err := httpClient.Post("api/2/issue", payload) if err != nil { fmt.Println(resp.StatusCode)