issues

Github, Jira, Gitlab issues from Plan 9's acme
Log | Files | Refs | README | LICENSE

commit d6f7698eb10147db56dfaaf77481c6e6f9170725
parent 9376b5f318f913ccda76c448ffb33691db1299fe
Author: Russ Cox <rsc@golang.org>
Date:   Wed, 11 Sep 2024 11:49:59 -0400

issue: add reactions

Diffstat:
Missue/acme.go | 2+-
Missue/edit.go | 9++++++---
Missue/issue.go | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 100 insertions(+), 20 deletions(-)

diff --git a/issue/acme.go b/issue/acme.go @@ -22,7 +22,7 @@ import ( "9fans.net/go/acme" "9fans.net/go/plumb" - "github.com/google/go-github/github" + "github.com/google/go-github/v62/github" ) func (w *awin) project() string { diff --git a/issue/edit.go b/issue/edit.go @@ -18,7 +18,7 @@ import ( "strings" "time" - "github.com/google/go-github/github" + "github.com/google/go-github/v62/github" ) func editIssue(project string, original []byte, issue *github.Issue) { @@ -138,6 +138,9 @@ func writeIssue(project string, old *github.Issue, updated []byte, isBulk bool) case strings.HasPrefix(line, "URL:"): continue + case strings.HasPrefix(line, "Reactions:"): + continue + default: fmt.Fprintf(&errbuf, "unknown summary line: %s\n", line) } @@ -426,7 +429,7 @@ func commonString(x, y string) string { return x } -func commonLabels(x, y []github.Label) []github.Label { +func commonLabels(x, y []*github.Label) []*github.Label { if len(x) == 0 || len(y) == 0 { return nil } @@ -434,7 +437,7 @@ func commonLabels(x, y []github.Label) []github.Label { for _, lab := range y { have[getString(lab.Name)] = true } - var out []github.Label + var out []*github.Label for _, lab := range x { if have[getString(lab.Name)] { out = append(out, lab) diff --git a/issue/issue.go b/issue/issue.go @@ -216,12 +216,25 @@ using these data structures: Created time.Time Text string Comments []*Comment + Reactions Reactions } type Comment struct { - Author string - Time time.Time - Text string + Author string + Time time.Time + Text string + Reactions Reactions + } + + type Reactions struct { + PlusOne int + MinusOne int + Laugh int + Confused int + Heart int + Hooray int + Rocket int + Eyes int } If asked for a specific issue, the output is an Issue with Comments. @@ -247,7 +260,7 @@ import ( "sync" "time" - "github.com/google/go-github/github" + "github.com/google/go-github/v62/github" "golang.org/x/oauth2" ) @@ -371,7 +384,7 @@ func printIssue(w io.Writer, project string, issue *github.Issue) error { fmt.Fprintf(w, "Labels: %s\n", strings.Join(getLabelNames(issue.Labels), " ")) fmt.Fprintf(w, "Milestone: %s\n", getMilestoneTitle(issue.Milestone)) fmt.Fprintf(w, "URL: %s\n", getString(issue.HTMLURL)) - + fmt.Fprintf(w, "Reactions: %v\n", getReactions(issue.Reactions)) fmt.Fprintf(w, "\nReported by %s (%s)\n", getUserLogin(issue.User), getTime(issue.CreatedAt).Format(timeFormat)) if issue.Body != nil { if *rawFlag { @@ -408,6 +421,10 @@ func printIssue(w io.Writer, project string, issue *github.Issue) error { } } } + if r := getReactions(com.Reactions); r != (Reactions{}) { + fmt.Fprintf(w, "\n\t%v\n", r) + } + output = append(output, buf.String()) } if err != nil { @@ -527,8 +544,8 @@ func searchIssues(project, q string) ([]*github.Issue, error) { }, }) for i := range x.Issues { - updateIssueCache(project, &x.Issues[i]) - all = append(all, &x.Issues[i]) + updateIssueCache(project, x.Issues[i]) + all = append(all, x.Issues[i]) } if err != nil { return all, err @@ -749,11 +766,11 @@ func getUserLogin(x *github.User) string { return *x.Login } -func getTime(x *time.Time) time.Time { +func getTime(x *github.Timestamp) time.Time { if x == nil { return time.Time{} } - return (*x).Local() + return x.Local() } func getMilestoneTitle(x *github.Milestone) string { @@ -763,7 +780,7 @@ func getMilestoneTitle(x *github.Milestone) string { return *x.Title } -func getLabelNames(x []github.Label) []string { +func getLabelNames(x []*github.Label) []string { var out []string for _, lab := range x { out = append(out, getString(lab.Name)) @@ -839,12 +856,25 @@ type Issue struct { Created time.Time Text string Comments []*Comment + Reactions Reactions } type Comment struct { - Author string - Time time.Time - Text string + Author string + Time time.Time + Text string + Reactions Reactions +} + +type Reactions struct { + PlusOne int + MinusOne int + Laugh int + Confused int + Heart int + Hooray int + Rocket int + Eyes int } func showJSONIssue(w io.Writer, project string, issue *github.Issue) { @@ -884,6 +914,7 @@ func toJSON(project string, issue *github.Issue) *Issue { Created: getTime(issue.CreatedAt), Text: getString(issue.Body), Comments: []*Comment{}, + Reactions: getReactions(issue.Reactions), } if j.Labels == nil { j.Labels = []string{} @@ -905,9 +936,10 @@ func toJSONWithComments(project string, issue *github.Issue) *Issue { } for _, com := range list { j.Comments = append(j.Comments, &Comment{ - Author: getUserLogin(com.User), - Time: getTime(com.CreatedAt), - Text: getString(com.Body), + Author: getUserLogin(com.User), + Time: getTime(com.CreatedAt), + Text: getString(com.Body), + Reactions: getReactions(com.Reactions), }) } if resp.NextPage < page { @@ -918,6 +950,51 @@ func toJSONWithComments(project string, issue *github.Issue) *Issue { return j } +func (r Reactions) String() string { + var buf bytes.Buffer + add := func(s string, n int) { + if n != 0 { + if buf.Len() != 0 { + buf.WriteString(" ") + } + fmt.Fprintf(&buf, "%s %d", s, n) + } + } + add("👍", r.PlusOne) + add("👎", r.MinusOne) + add("😆", r.Laugh) + add("😕", r.Confused) + add("♥", r.Heart) + add("🎉", r.Hooray) + add("🚀", r.Rocket) + add("👀", r.Eyes) + return buf.String() +} + +func getReactions(r *github.Reactions) Reactions { + if r == nil { + return Reactions{} + } + return Reactions{ + PlusOne: z(r.PlusOne), + MinusOne: z(r.MinusOne), + Laugh: z(r.Laugh), + Confused: z(r.Confused), + Heart: z(r.Heart), + Hooray: z(r.Hooray), + Rocket: z(r.Rocket), + Eyes: z(r.Eyes), + } +} + +func z[T any](x *T) T { + if x == nil { + var zero T + return zero + } + return *x +} + func newLogger(t http.RoundTripper) http.RoundTripper { return &loggingTransport{transport: t} }