Skip to content

Commit

Permalink
Merge pull request #1 from karashiiro/feat/json-validation
Browse files Browse the repository at this point in the history
Implement JSON and title lints for plugin PRs
  • Loading branch information
karashiiro authored May 9, 2022
2 parents 3c20cf7 + 6caa637 commit 71f1906
Show file tree
Hide file tree
Showing 11 changed files with 547 additions and 93 deletions.
46 changes: 46 additions & 0 deletions cmd/view_test/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"fmt"
"net/http"
"text/template"
"time"

"github.com/karashiiro/operator/pkg/html"
"github.com/karashiiro/operator/pkg/reports"
)

func reportHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "text/html")

t, err := template.New("report.gohtml").Funcs(template.FuncMap{
"formatTime": func(t time.Time) string {
return t.Format(time.RFC822)
},
}).ParseFS(html.Files, "report.gohtml")
if err != nil {
w.Write([]byte(fmt.Sprintf("%v\n", err)))
return
}

reportTemplates, err := reports.GetPlogonReportTemplates()
if err != nil {
w.Write([]byte(fmt.Sprintf("%v\n", err)))
return
}

err = t.Execute(w, struct {
PlogonStates []*reports.ReportTemplate
}{
PlogonStates: reportTemplates,
})
if err != nil {
w.Write([]byte(fmt.Sprintf("%v\n", err)))
return
}
}

func main() {
http.HandleFunc("/report", reportHandler)
http.ListenAndServe(":9000", nil)
}
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sloonz/go-qprintable v0.0.0-20210417175225-715103f9e6eb // indirect
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
golang.org/x/text v0.3.6 // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/text v0.3.7 // indirect
)

require (
github.com/bluekeyes/go-gitdiff v0.6.1
github.com/google/go-cmp v0.5.8
github.com/google/go-github/v44 v44.0.1-0.20220502191311-417479672f91
github.com/google/go-querystring v1.1.0 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 // indirect
)
15 changes: 9 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/bluekeyes/go-gitdiff v0.6.1 h1:VPpQZanEVwFid0IoAIyiJLD+SMWM/AXZXYFc+3E9CS4=
github.com/bluekeyes/go-gitdiff v0.6.1/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/glennzw/go-imap v0.0.0-20200213170711-35ad56e460d4 h1:pQAqfr44gthAWySJTn3ND5+Ho3yJjlFeUIXaNBQCW/8=
Expand All @@ -8,6 +10,7 @@ github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZg
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v44 v44.0.1-0.20220502191311-417479672f91 h1:07IRiIaXrkBvpln6reaLXjWorQTQ2PvwiSNgW4YwJeA=
github.com/google/go-github/v44 v44.0.1-0.20220502191311-417479672f91/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
Expand All @@ -26,8 +29,6 @@ github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo=
github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
github.com/mxk/go-imap v0.0.0-20150429134902-531c36c3f12d h1:+DgqA2tuWi/8VU+gVgBAa7+WZrnFbPKhQWbKBB54cVs=
github.com/mxk/go-imap v0.0.0-20150429134902-531c36c3f12d/go.mod h1:xacC5qXZnL/ooiitVoe3BtI1OotFTqi5zICBs9J5Fyk=
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw=
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand All @@ -38,14 +39,16 @@ github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5g
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sloonz/go-qprintable v0.0.0-20210417175225-715103f9e6eb h1:T+USeSgAg9MysHPeOQ2W3KAuBQHVZzG0XMHyfHN88Yg=
github.com/sloonz/go-qprintable v0.0.0-20210417175225-715103f9e6eb/go.mod h1:WKd1iQMtoZdaS9rlKDPprxWJoan2hkQA9BcGt+oxezs=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8=
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
44 changes: 39 additions & 5 deletions pkg/html/report.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,54 @@
<th>Title</th>
<th>Submitter</th>
<th>Labels</th>
<th>Problems</th>
<th>Updated</th>
</tr>
</thead>
<tbody>
{{range .Plogons}}
{{range .PlogonStates}}
<tr>
<td><a href="{{.URL}}">{{.Title}}</a></td>
<td>{{.Submitter}}</td>
<td><a href="{{.Plogon.URL}}">{{.Plogon.Title}}</a></td>
<td>{{.Plogon.Submitter}}</td>
<td>
{{range .Labels}}
{{range .Plogon.Labels}}
<span style="color: #{{.Color}};">{{.Name}}&nbsp;</span>
{{end}}
</td>
<td>{{formatTime .Updated}}</td>
<td>
{{if ne .ValidationState.Err nil}}
<span style="color: #F00;">error: {{.ValidationState.Err}}</span>
{{else}}
{{$validation := .ValidationState.Result}}
<ul>
{{if not $validation.NameSet}}
<li><span>No name set</span></li>
{{end}}
{{if not $validation.InternalNameSet}}
<li><span>No internal name set</span></li>
{{end}}
{{if not $validation.DescriptionSet}}
<li><span>No description set</span></li>
{{end}}
{{if not $validation.AssemblyVersionSet}}
<li><span>No version set</span></li>
{{end}}
{{if not $validation.RepoURLSet}}
<li><span>No repo URL set</span></li>
{{end}}
{{if not $validation.PunchlineSet}}
<li><span>No punchline set</span></li>
{{end}}
{{if not $validation.MatchesZipped}}
<li><span>Unzipped and zipped metadata do not match</span></li>
{{end}}
{{if not $validation.TestingHasTaggedTitle | and $validation.Testing }}
<li><span>Testing plugin does not have tagged title</span></li>
{{end}}
</ul>
{{end}}
</td>
<td>{{formatTime .Plogon.Updated}}</td>
</tr>
{{end}}
</tbody>
Expand Down
42 changes: 0 additions & 42 deletions pkg/reports/pretty.go

This file was deleted.

103 changes: 68 additions & 35 deletions pkg/reports/reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,30 @@ package reports

import (
"bytes"
"context"
"hash/fnv"
"io"
"log"
"text/template"
"time"

"github.com/google/go-github/v44/github"
"github.com/jackc/pgx"
"github.com/karashiiro/operator/pkg/html"
"github.com/karashiiro/operator/pkg/outlook"
"github.com/karashiiro/operator/pkg/repos/plogons"
)

type ReportJob struct {
Pool *pgx.ConnPool
}

func (j *ReportJob) Execute() {
// Retrieve all open pull requests
client := github.NewClient(nil)
plogons, _, err := client.PullRequests.List(context.Background(), "goatcorp", "DalamudPlugins", &github.PullRequestListOptions{
State: "open",
})
// Process all open pull requests
reportTemplates, err := GetPlogonReportTemplates()
if err != nil {
log.Printf("Request error: %v\n", err)
log.Printf("Failed to retrieve plogons: %v\n", err)
return
}

// Make the plogons :dognosepretty:
plogonsPretty := make([]*Plogon, len(plogons))
for i, plogon := range plogons {
labels := make([]*PlogonLabel, len(plogon.Labels))
for j, label := range plogon.Labels {
labels[j] = &PlogonLabel{
Name: label.GetName(),
Color: label.GetColor(),
}
}

plogonsPretty[i] = &Plogon{
Title: plogon.GetTitle(),
URL: plogon.GetHTMLURL(),
Labels: labels,
Submitter: plogon.User.GetLogin(),
Updated: plogon.GetUpdatedAt(),
}
}

// Retrieve all of the active report readers
readerConn, err := j.Pool.Acquire()
if err != nil {
Expand Down Expand Up @@ -92,18 +71,18 @@ func (j *ReportJob) Execute() {
// Figure out the size of the array we need so we can allocate
// it all at once
sinceLastEmail := 0
for _, p := range plogonsPretty {
if ref.IsZero() || p.Updated.After(ref) {
for _, rt := range reportTemplates {
if ref.IsZero() || rt.Plogon.Updated.After(ref) {
sinceLastEmail++
}
}

// Filter the stuff
plogonsFiltered := make([]*Plogon, sinceLastEmail)
plogonsFiltered := make([]*ReportTemplate, sinceLastEmail)
plogonsFilteredIdx := 0
for _, p := range plogonsPretty {
if ref.IsZero() || p.Updated.After(ref) {
plogonsFiltered[plogonsFilteredIdx] = p
for _, rt := range reportTemplates {
if ref.IsZero() || rt.Plogon.Updated.After(ref) {
plogonsFiltered[plogonsFilteredIdx] = rt
plogonsFilteredIdx++
}
}
Expand All @@ -122,7 +101,7 @@ func (j *ReportJob) Execute() {

// Send the email
var readerMessage bytes.Buffer
err = BuildTemplate(&readerMessage, plogonsFiltered)
err = buildTemplate(&readerMessage, plogonsFiltered)
if err != nil {
log.Printf("Failed to build template: %v\n", err)
continue
Expand Down Expand Up @@ -158,6 +137,60 @@ func (j *ReportJob) Key() int {
return int(h.Sum32())
}

func GetPlogonReportTemplates() ([]*ReportTemplate, error) {
// Retrieve all open pull requests
plogonList, plogonPRs, err := plogons.GetPlogons()
if err != nil {
return nil, err
}

// Get the validation states of all open pull requests
plogonValidation := make([]*ReportPlogonValidationState, len(plogonList))
for i, pr := range plogonPRs {
log.Printf("Validating pull request #%d\n", pr.GetNumber())
res, err := plogons.ValidatePullRequest(pr)
plogonValidation[i] = &ReportPlogonValidationState{
Result: res,
Err: err,
}
}

// Zip the two slices so we can enumerate them together
plogonTemplates := make([]*ReportTemplate, len(plogonList))
for i, p := range plogonList {
plogonTemplates[i] = &ReportTemplate{
Plogon: p,
ValidationState: plogonValidation[i],
}
}

return plogonTemplates, nil
}

func buildTemplate(w io.Writer, reportTemplates []*ReportTemplate) error {
// Build the HTML template
t, err := template.New("report.gohtml").Funcs(template.FuncMap{
"formatTime": func(t time.Time) string {
return t.Format(time.RFC822)
},
}).ParseFS(html.Files, "report.gohtml")
if err != nil {
return err
}

// Execute the template
err = t.Execute(w, struct {
PlogonStates []*ReportTemplate
}{
PlogonStates: reportTemplates,
})
if err != nil {
return err
}

return nil
}

func getReadersToNotify(conn *pgx.Conn) (*pgx.Rows, error) {
return conn.Query(`
SELECT Reader.id, Reader.email, Reader.github, max(Report.sent_time)
Expand Down
13 changes: 13 additions & 0 deletions pkg/reports/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package reports

import "github.com/karashiiro/operator/pkg/repos/plogons"

type ReportPlogonValidationState struct {
Result *plogons.PlogonMetaValidationResult
Err error
}

type ReportTemplate struct {
Plogon *plogons.Plogon
ValidationState *ReportPlogonValidationState
}
Loading

0 comments on commit 71f1906

Please sign in to comment.