-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
161 lines (139 loc) · 4.26 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"context"
"flag"
humanize "github.com/dustin/go-humanize"
"github.com/google/go-github/v32/github"
"golang.org/x/oauth2"
"html/template"
"log"
"math"
"os"
"sort"
"strings"
"time"
)
type RepoInfo struct {
Repository *github.Repository
URL string
IssueCount int
Name string
Description string
LastUpdated string
}
func now() string {
return time.Now().Format(time.RFC3339)
}
func main() {
// Define the UI
var token, outflag string
flag.StringVar(&token, "t", "", "GitHub Token")
flag.StringVar(&outflag, "o", "", "Path to the rendered template")
flag.Parse()
var out *os.File
var err error
if outflag == "" {
out = os.Stdout
} else {
out, err = os.Create(outflag)
if err != nil {
log.Fatalf("Could not open %v: %v", outflag, err)
}
}
// Setup GitHub client
ctx := context.Background()
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
opts := &github.SearchOptions{
Sort: "updated",
ListOptions: github.ListOptions{PerPage: 100, Page: 1},
}
// Search for issues labelled "Hacktoberfest" across Julia repos
var issues []*github.Issue
for {
res, resp, err := client.Search.Issues(ctx, "is:issue is:open language:julia label:hacktoberfest", opts)
if err != nil {
log.Fatalf("Could not execute search: %v", err)
} else if resp.StatusCode != 200 {
log.Fatalf("Search failed: %v - %v", resp.StatusCode, resp.Status)
}
log.Printf("Searching page %v/%v...", opts.Page, int(math.Ceil(float64(res.GetTotal())/float64(100))))
issues = append(issues, res.Issues...)
if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}
repos := make(map[string]int)
// Manually add some repos that can't be found due to not having Julia as main language (e.g. docs repos)
repos["https://github.com/FluxML/fluxml.github.io"]++
//additionalRepos := [...]string{
// "FluxML/fluxml.github.io",
//}
//for _, r := range additionalRepos {
// log.Printf("Manually search %v for Hacktoberfest issues...", r)
// searchString := fmt.Sprintf("is:issue is:open repo:%s label:hacktoberfest", r)
// res, resp, err := client.Search.Issues(ctx, searchString, opts)
// if err != nil {
// log.Fatalf("Could not execute search: %v", err)
// } else if resp.StatusCode != 200 {
// log.Fatalf("Search failed: %v - %v", resp.StatusCode, resp.Status)
// }
//
// fmt.Println(res.Issues)
//
// issues = append(issues, res.Issues...)
// if resp.NextPage == 0 {
// break
// }
// opts.Page = resp.NextPage
//}
for _, issue := range issues {
repos[issue.GetRepositoryURL()]++
}
// Create entries for the list of participating repos
var entries []RepoInfo
for repoURL, count := range repos {
// Get repo data from API
splitURL := strings.Split(repoURL, "/")
owner := splitURL[len(splitURL)-2]
repo := splitURL[len(splitURL)-1]
log.Printf("Fetching repo info for %v/%v...", owner, repo)
res, resp, err := client.Repositories.Get(ctx, owner, repo)
if err != nil {
log.Fatalf("Could not get repo: %v", err)
} else if resp.StatusCode != 200 {
log.Fatalf("Repo lookup failed: %v - %v", resp.StatusCode, resp.Status)
}
entries = append(entries, RepoInfo{
Repository: res,
URL: res.GetHTMLURL(),
IssueCount: count,
Name: res.GetFullName(),
Description: res.GetDescription(),
LastUpdated: humanize.Time(res.GetUpdatedAt().Time),
})
}
// Sort entries by time of last update
sort.SliceStable(entries, func(i, j int) bool { return entries[i].Repository.GetUpdatedAt().Time.After(entries[j].Repository.GetUpdatedAt().Time) })
// Remove repos that haven't had any activity in the last 6 months
filteredEntries := []RepoInfo{}
for _, r := range entries {
if r.Repository.GetUpdatedAt().After(time.Date(2021, 4, 1, 0, 0, 0, 0, time.UTC)) {
filteredEntries = append(filteredEntries, r)
}
}
// Render template
funcMap := template.FuncMap{"now": now}
log.Println("Parsing template...")
tpl, err := template.New("template.html").Funcs(funcMap).ParseFiles("template.html")
if err != nil {
log.Fatalf("Could not parse template: %v", err)
}
log.Println("Executing template...")
err = tpl.Execute(out, filteredEntries)
if err != nil {
log.Fatalf("Could not execute template: %v", err)
}
}