From 7c72b72bae2c3e28f02aadaef00d5f44820e7e2c Mon Sep 17 00:00:00 2001 From: Elliott Stoneham Date: Mon, 22 Aug 2016 14:15:17 +0100 Subject: [PATCH] separate templates, continue to mangle data to new form --- core/section/github/commits.go | 108 +++++++++------------ core/section/github/commits_template.go | 74 ++++++++++++++ core/section/github/issues.go | 90 +++++++---------- core/section/github/issues_template.go | 64 ++++++++++++ core/section/github/milestones.go | 75 ++++---------- core/section/github/milestones_template.go | 64 ++++++++++++ core/section/github/model.go | 57 ++++++++--- core/section/github/summary.go | 25 +---- core/section/github/summary_template.go | 33 +++++++ 9 files changed, 374 insertions(+), 216 deletions(-) create mode 100644 core/section/github/commits_template.go create mode 100644 core/section/github/issues_template.go create mode 100644 core/section/github/milestones_template.go create mode 100644 core/section/github/summary_template.go diff --git a/core/section/github/commits.go b/core/section/github/commits.go index fbb2dbe5..b8e27db8 100644 --- a/core/section/github/commits.go +++ b/core/section/github/commits.go @@ -59,74 +59,49 @@ func (s asToSort) Less(i, j int) bool { return s[i].CommitCount > s[j].CommitCount } -const tagCommitsData = "commitsData" +// sort branches in order that that should be presented. +type branchByID []githubBranch -func init() { - reports[tagCommitsData] = report{refreshCommits, renderCommits, ` -

Contributor activity since {{.Config.Since}}{{.Config.DateMessage}}

-
- - - -    - - -    -    -  - {{range $stats := .AuthorStats}} - - - - - - - - - {{end}} -
AuthorOpen IssuesClosed Issues#commitsBranches
-
- @{{$stats.Author}} -
-
{{$stats.Author}}{{$stats.OpenIssues}}{{$stats.ClosedIssues}}{{$stats.CommitCount}} - {{range $repo := $stats.Repos}} - {{$repo}} - {{end}} -
- {{range $branch := .BranchCommits}} -

- There are {{ $branch.CommitCount }} commits for branch {{$branch.Name}}. -

-
- {{range $data := $branch.Days}} -
- Commits on {{ $data.Day }} -
- - {{end}} -
- {{end}} -
-`} +func (s branchByID) Len() int { return len(s) } +func (s branchByID) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s branchByID) Less(i, j int) bool { + return s[i].ID < s[j].ID } +const tagCommitsData = "commitsData" + func getCommits(client *gogithub.Client, config *githubConfig) ([]githubBranchCommits, []githubAuthorStats, error) { + // first make sure we've got all the branches + for _, orb := range config.Lists { + if orb.Included { + + branches, _, err := client.Repositories.ListBranches(orb.Owner, orb.Repo, + &gogithub.ListOptions{PerPage: 100}) + if err == nil { + render := make([]githubBranch, len(branches)) + for kc, vb := range branches { + for _, existing := range config.Lists { + if orb.Owner == existing.Owner && orb.Repo == existing.Repo && orb.Name == *vb.Name { + goto found + } + } + render[kc] = githubBranch{ + Owner: orb.Owner, + Repo: orb.Repo, + Name: *vb.Name, + ID: fmt.Sprintf("%s:%s:%s", orb.Owner, orb.Repo, *vb.Name), + Included: true, + URL: "https://github.com/" + orb.Owner + "/" + orb.Repo + "/tree/" + *vb.Name, + } + found: + } + config.Lists = append(config.Lists, render...) + } + } + } + sort.Stable(branchByID(config.Lists)) + authorStats := make(map[string]githubAuthorStats) contribBranch := make(map[string]map[string]struct{}) @@ -298,3 +273,10 @@ func renderCommits(payload *githubRender, c *githubConfig) error { return nil } + +// TODO(elliott5) - move to templates.go once working +// COMMITS + +func init() { + reports[tagCommitsData] = report{refreshCommits, renderCommits, commitsTemplate} +} diff --git a/core/section/github/commits_template.go b/core/section/github/commits_template.go new file mode 100644 index 00000000..532f6eb3 --- /dev/null +++ b/core/section/github/commits_template.go @@ -0,0 +1,74 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package github + +const commitsTemplate = ` +

Contributor activity since {{.Config.Since}}{{.Config.DateMessage}}

+
+ + + +    + + +    +    +  + {{range $stats := .AuthorStats}} + + + + + + + + + {{end}} +
AuthorOpen IssuesClosed Issues#commitsBranches
+
+ @{{$stats.Author}} +
+
{{$stats.Author}}{{$stats.OpenIssues}}{{$stats.ClosedIssues}}{{$stats.CommitCount}} + {{range $repo := $stats.Repos}} + {{$repo}}
+ {{end}} +
+ {{range $branch := .BranchCommits}} +

+ There are {{ $branch.CommitCount }} commits for branch {{$branch.Name}}. +

+
+ {{range $data := $branch.Days}} +
+ Commits on {{ $data.Day }} +
+ + {{end}} +
+ {{end}} +
+` diff --git a/core/section/github/issues.go b/core/section/github/issues.go index 489d9768..93e99547 100644 --- a/core/section/github/issues.go +++ b/core/section/github/issues.go @@ -36,12 +36,28 @@ type githubIssue struct { Milestone string `json:"milestone"` } +type githubSharedLabel struct { + Name string `json:"name"` + Count int `json:"count"` + Repos template.HTML `json:"Repos"` +} + // sort issues in order that that should be presented - by date updated. type issuesToSort []githubIssue func (s issuesToSort) Len() int { return len(s) } func (s issuesToSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s issuesToSort) Less(i, j int) bool { + if s[i].Milestone != noMilestone && s[j].Milestone == noMilestone { + return true + } + if s[i].Milestone == noMilestone && s[j].Milestone != noMilestone { + return false + } + if s[i].Milestone != s[j].Milestone { + // TODO should this order be by milestone completion? + return s[i].Milestone < s[j].Milestone + } if !s[i].IsOpen && s[j].IsOpen { return true } @@ -56,62 +72,20 @@ func (s issuesToSort) Less(i, j int) bool { return iDate.Before(jDate) } +// sort shared labels alphabetically +type sharedLabelsSort []githubSharedLabel + +func (s sharedLabelsSort) Len() int { return len(s) } +func (s sharedLabelsSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s sharedLabelsSort) Less(i, j int) bool { return s[i].Name < s[j].Name } + const ( tagIssuesData = "issuesData" issuesTimeFormat = "January 2 2006, 15:04" - - openIsvg = ` - - - -` - closedIsvg = ` - - - - ` ) func init() { - reports[tagIssuesData] = report{refreshIssues, renderIssues, ` -
-

Issues: {{.ClosedIssues}} closed, {{.OpenIssues}} open

-

- {{if .ShowList}} - Including issues labelled - {{range $label := .List}} - {{if $label.Included}} - {{$label.Name}} - {{end}} - {{end}} - {{end}} -

- -
-`} + reports[tagIssuesData] = report{refreshIssues, renderIssues, issuesTemplate} } func wrapLabels(labels []gogithub.Label) (l string, labelNames []string) { @@ -186,7 +160,7 @@ func getIssues(client *gogithub.Client, config *githubConfig) ([]githubIssue, er LabelNames: ln, ID: *v.Number, IsOpen: *v.State == "open", - Repo: rName, + Repo: repoName(rName), Milestone: ms, }) } @@ -224,21 +198,23 @@ func refreshIssues(gr *githubRender, config *githubConfig, client *gogithub.Clie } } - gr.SharedLabels = make([]template.HTML, 0, len(sharedLabels)) // will usually be too big + gr.SharedLabels = make([]githubSharedLabel, 0, len(sharedLabels)) // will usually be too big for name, repos := range sharedLabels { if len(repos) > 1 { - lab := name + ":[" + thisLab := githubSharedLabel{Name: name, Count: len(repos)} + show := "" for i, r := range repos { if i > 0 { - lab += " " + show += ", " } - lab += "" + r + "" } - lab += "] " - gr.SharedLabels = append(gr.SharedLabels, template.HTML(lab)) + thisLab.Repos = template.HTML(show) + gr.SharedLabels = append(gr.SharedLabels, thisLab) } } + sort.Stable(sharedLabelsSort(gr.SharedLabels)) return nil } diff --git a/core/section/github/issues_template.go b/core/section/github/issues_template.go new file mode 100644 index 00000000..2d09a5dc --- /dev/null +++ b/core/section/github/issues_template.go @@ -0,0 +1,64 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package github + +const ( + openIsvg = ` + + + +` + closedIsvg = ` + + + + ` + issuesTemplate = ` +
+

Issues: {{.ClosedIssues}} closed, {{.OpenIssues}} open

+

+ {{if .ShowList}} + Including issues labelled + {{range $label := .List}} + {{if $label.Included}} + {{$label.Name}} + {{end}} + {{end}} + {{end}} +

+ +
+` +) diff --git a/core/section/github/milestones.go b/core/section/github/milestones.go index 32b2279e..16114918 100644 --- a/core/section/github/milestones.go +++ b/core/section/github/milestones.go @@ -31,6 +31,7 @@ type githubMilestone struct { DueDate string `json:"dueDate"` UpdatedAt string `json:"updatedAt"` Progress uint `json:"progress"` + IsMilestone bool `json:"isMilestone"` } // sort milestones in order that that should be presented. @@ -52,6 +53,12 @@ func (s milestonesToSort) Less(i, j int) bool { if s[i].IsOpen && !s[j].IsOpen { return false } + if s[i].Name != noMilestone && s[j].Name == noMilestone { + return true + } + if s[i].Name == noMilestone && s[j].Name != noMilestone { + return false + } if s[i].Progress == s[j].Progress { // order equal progress milestones return s[i].Name < s[j].Name } @@ -62,57 +69,10 @@ const ( tagMilestonesData = "milestonesData" milestonesTimeFormat = "January 2 2006" noMilestone = "no milestone" - - rawMSsvg = `` - openMSsvg = ` - - - ` + rawMSsvg + ` - - -` - closedMSsvg = ` - - - ` + rawMSsvg + ` - - -` ) func init() { - reports[tagMilestonesData] = report{refreshMilestones, renderMilestones, ` - -`} + reports[tagMilestonesData] = report{refreshMilestones, renderMilestones, milestonesTemplate} } func getMilestones(client *gogithub.Client, config *githubConfig) ([]githubMilestone, error) { @@ -163,7 +123,7 @@ func getMilestones(client *gogithub.Client, config *githubConfig) ([]githubMiles progress := float64(*v.ClosedIssues*100) / float64(*v.OpenIssues+*v.ClosedIssues) ret = append(ret, githubMilestone{ - Repo: rName, + Repo: repoName(rName), Name: *v.Title, URL: *v.HTMLURL, IsOpen: *v.State == "open", @@ -173,6 +133,7 @@ func getMilestones(client *gogithub.Client, config *githubConfig) ([]githubMiles DueDate: dd, UpdatedAt: up, Progress: uint(progress), + IsMilestone: true, }) } } @@ -209,19 +170,14 @@ func refreshMilestones(gr *githubRender, config *githubConfig, client *gogithub. } func renderMilestones(payload *githubRender, c *githubConfig) error { - fmt.Println("DEBUG renderMilestones list", payload.List) hadRepo := make(map[string]bool) for _, orb := range payload.List { - fmt.Println("DEBUG branch", orb) rName := orb.Owner + "/" + orb.Repo if !hadRepo[rName] { - fmt.Println("DEBUG found repo", rName) issuesOpen, issuesClosed := 0, 0 for _, iss := range payload.Issues { - fmt.Println("DEBUG issue", iss) - if iss.Repo == rName { - fmt.Println("DEBUG Found issue", iss) + if iss.Repo == repoName(rName) { if iss.Milestone == noMilestone { if iss.IsOpen { issuesOpen++ @@ -231,9 +187,12 @@ func renderMilestones(payload *githubRender, c *githubConfig) error { } } } - payload.Milestones = append(payload.Milestones, githubMilestone{ - Repo: rName, Name: noMilestone, OpenIssues: issuesOpen, ClosedIssues: issuesClosed, - }) + if issuesClosed+issuesOpen > 0 { + payload.Milestones = append(payload.Milestones, githubMilestone{ + Repo: rName, Name: noMilestone, IsOpen: true, + OpenIssues: issuesOpen, ClosedIssues: issuesClosed, + }) + } hadRepo[rName] = true } diff --git a/core/section/github/milestones_template.go b/core/section/github/milestones_template.go new file mode 100644 index 00000000..a654134a --- /dev/null +++ b/core/section/github/milestones_template.go @@ -0,0 +1,64 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package github + +const ( + rawMSsvg = `` + openMSsvg = ` + + + ` + rawMSsvg + ` + + +` + closedMSsvg = ` + + + ` + rawMSsvg + ` + + +` + milestonesTemplate = ` + +` +) diff --git a/core/section/github/model.go b/core/section/github/model.go index 0764756b..a8871bd9 100644 --- a/core/section/github/model.go +++ b/core/section/github/model.go @@ -13,7 +13,8 @@ package github import ( "fmt" - "html/template" + "sort" + "strings" "time" "github.com/documize/community/core/log" @@ -30,7 +31,7 @@ type githubRender struct { BranchCommits []githubBranchCommits `json:"branchCommits"` CommitCount int `json:"commitCount"` Issues []githubIssue `json:"issues"` - SharedLabels []template.HTML `json:"sharedLabels"` + SharedLabels []githubSharedLabel `json:"sharedLabels"` OpenIssues int `json:"openIssues"` ClosedIssues int `json:"closedIssues"` Limit int `json:"limit"` @@ -79,6 +80,7 @@ type githubBranch struct { Included bool `json:"included"` URL string `json:"url"` Color string `json:"color,omitempty"` + Comma bool `json:"comma"` } type githubLabel struct { @@ -148,24 +150,51 @@ func (c *githubConfig) Clean() { c.Since = (*c.SincePtr).Format(issuesTimeFormat) // TEST DATA INSERTION DEBUG ONLY! - debugList := []string{"community", "enterprise", "test-data"} - c.Lists = make([]githubBranch, 0, len(debugList)) - for rid, repo := range debugList { - c.Lists = append(c.Lists, githubBranch{ - ID: fmt.Sprintf("%d", rid+1), - Owner: "documize", - Repo: repo, - Name: "master", - Included: true, - URL: "https://github.com/documize/" + repo + "/tree/master", - Color: "", - }) + debugList := map[string][]string{ + "community": []string{"master"}, + "enterprise": []string{"master"}, + "test-data": []string{"master"}, } + c.Lists = make([]githubBranch, 0, len(debugList)*3) + for repo, branches := range debugList { + render := make([]githubBranch, len(branches)) + for kc, vb := range branches { + render[kc] = githubBranch{ + Owner: "documize", + Repo: repo, + Name: vb, + ID: fmt.Sprintf("%s:%s:%s", "documize", repo, vb), + Included: true, + URL: "https://github.com/" + "documize" + "/" + repo + "/tree/" + vb, + } + } + c.Lists = append(c.Lists, render...) + } + c.Owner = "documize" c.ReportOrder = []string{tagSummaryData, tagMilestonesData, tagIssuesData /*, tagPullRequestData*/, tagCommitsData} c.BranchLines = 100 // overide js default of 30 with maximum allowable in one call + sort.Stable(branchesToSort(c.Lists)) // get the configured branches in a sensible order for printing + for i := range c.Lists { + if i != len(c.Lists)-1 { + c.Lists[i].Comma = true // put the commas in the right places + } + } + } type githubCallbackT struct { AccessToken string `json:"access_token"` } + +func repoName(branchName string) string { + bits := strings.Split(branchName, "/") + if len(bits) != 2 { + return branchName + "?repo" + } + pieces := strings.Split(bits[1], ":") + if len(pieces) == 0 { + return branchName + "?repo:?branch" + } + return pieces[0] +} diff --git a/core/section/github/summary.go b/core/section/github/summary.go index cc16ca8b..9ad50988 100644 --- a/core/section/github/summary.go +++ b/core/section/github/summary.go @@ -12,8 +12,6 @@ package github import ( - "sort" - gogithub "github.com/google/go-github/github" ) @@ -32,27 +30,7 @@ func (s branchesToSort) Less(i, j int) bool { } func init() { - reports[tagSummaryData] = report{refreshSummary, renderSummary, ` -
-

- Activity since {{.Config.Since}}{{.Config.DateMessage}} for repository branches [ - {{range $data := .Config.Lists}} - {{if $data.Included}} - - {{$data.Owner}}/{{$data.Repo}}:{{$data.Name}} - - {{end}} - {{end}} - ] -

-

- Shared Tags: - {{range $slabel := .SharedLabels}} - {{$slabel}} - {{end}} -

-
-`} + reports[tagSummaryData] = report{refreshSummary, renderSummary, summaryTemplate} } func refreshSummary(gr *githubRender, config *githubConfig, client *gogithub.Client) (err error) { @@ -60,6 +38,5 @@ func refreshSummary(gr *githubRender, config *githubConfig, client *gogithub.Cli } func renderSummary(payload *githubRender, c *githubConfig) error { - sort.Stable(branchesToSort(c.Lists)) // get the configured branches in a sensible order before printing return nil } diff --git a/core/section/github/summary_template.go b/core/section/github/summary_template.go new file mode 100644 index 00000000..6e2858a4 --- /dev/null +++ b/core/section/github/summary_template.go @@ -0,0 +1,33 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package github + +const summaryTemplate = ` +
+

+ Activity since {{.Config.Since}}{{.Config.DateMessage}} for {{.Config.Owner}} repositories: + {{range $data := .Config.Lists}} + {{if $data.Included}} + + {{$data.Repo}}{{if $data.Comma}},{{end}} + + {{end}} + {{end}} +

+

+ Common Labels:
+ {{range $slabel := .SharedLabels}} + {{$slabel.Name}} {{$slabel.Count}} {{$slabel.Repos}}
+ {{end}} +

+
+`