summaryrefslogtreecommitdiff
path: root/cmd/generate/forge_forgejo.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/generate/forge_forgejo.go')
-rw-r--r--cmd/generate/forge_forgejo.go187
1 files changed, 187 insertions, 0 deletions
diff --git a/cmd/generate/forge_forgejo.go b/cmd/generate/forge_forgejo.go
new file mode 100644
index 0000000..7d7c8ae
--- /dev/null
+++ b/cmd/generate/forge_forgejo.go
@@ -0,0 +1,187 @@
+package main
+
+import (
+ "fmt"
+ "regexp"
+ "time"
+)
+
+var reForgejoPR = regexp.MustCompile(`^https://([^/]+)/([^/?#]+)/([^/?#]+)/pulls/([0-9]+)(?:\?[^#]*)?(?:#.*)?$`)
+
+type Forgejo struct {
+ Authority string
+}
+
+var _ Forge = Forgejo{}
+
+func (f Forgejo) FetchStatus(urls []string) (string, error) {
+ for _, u := range urls {
+ m := reForgejoPR.FindStringSubmatch(u)
+ if m == nil || m[1] != f.Authority {
+ continue
+ }
+ authority := m[1]
+ user := m[2]
+ repo := m[3]
+ prnum := m[4]
+
+ urlStr := "https://" + authority + "/api/v1/repos/" + user + "/" + repo + "/pulls/" + prnum
+
+ var obj struct {
+ // State values are "open" and "closed".
+ State string `json:"state"`
+ Merged bool `json:"merged"`
+ MergeCommitSha string `json:"merge_commit_sha"`
+ }
+ if err := httpGetJSON(urlStr, nil, &obj); err != nil {
+ return "", err
+ }
+ ret := obj.State
+ if obj.Merged {
+ ret = statusMerged
+ tag, err := getGitTagThatContainsAll("https://"+authority+"/"+user+"/"+repo, obj.MergeCommitSha)
+ if err != nil {
+ return "", err
+ }
+ if tag != "" {
+ ret = fmt.Sprintf(statusReleasedFmt, tag)
+ }
+ }
+
+ return ret, nil
+ }
+ return "", nil
+}
+
+func (f Forgejo) FetchSubmittedAt(urls []string) (time.Time, error) {
+ for _, u := range urls {
+ m := reForgejoPR.FindStringSubmatch(u)
+ fmt.Printf("u=%q m=%#v\n", u, m)
+ if m == nil || m[1] != f.Authority {
+ continue
+ }
+ authority := m[1]
+ user := m[2]
+ repo := m[3]
+ prnum := m[4]
+
+ urlStr := "https://" + authority + "/api/v1/repos/" + user + "/" + repo + "/pulls/" + prnum
+
+ var obj struct {
+ CreatedAt time.Time `json:"created_at"`
+ }
+ if err := httpGetJSON(urlStr, nil, &obj); err != nil {
+ return time.Time{}, err
+ }
+ return obj.CreatedAt, nil
+ }
+ return time.Time{}, nil
+}
+
+func (f Forgejo) FetchLastUpdated(urls []string) (time.Time, User, error) {
+ for _, u := range urls {
+ m := reForgejoPR.FindStringSubmatch(u)
+ if m == nil || m[1] != f.Authority {
+ continue
+ }
+ authority := m[1]
+ user := m[2]
+ repo := m[3]
+ prnum := m[4]
+
+ urlStr := "https://" + authority + "/api/v1/repos/" + user + "/" + repo + "/pulls/" + prnum
+
+ var obj struct {
+ UpdatedAt time.Time `json:"updated_at"`
+
+ CreatedAt time.Time `json:"created_at"`
+ CreatedBy struct {
+ Login string `json:"login"`
+ HTMLURL string `json:"html_url"`
+ } `json:"user"`
+
+ MergedAt time.Time `json:"merged_at"`
+ MergedBy struct {
+ Login string `json:"login"`
+ HTMLURL string `json:"html_url"`
+ } `json:"merged_by"`
+ }
+ if err := httpGetJSON(urlStr, nil, &obj); err != nil {
+ return time.Time{}, User{}, err
+ }
+
+ retUpdatedAt := obj.UpdatedAt
+ var retUser User
+
+ if retUser == (User{}) && withinOneSecond(obj.CreatedAt, retUpdatedAt) {
+ retUser.Name = obj.CreatedBy.Login
+ retUser.URL = obj.CreatedBy.HTMLURL
+ }
+ if retUser == (User{}) && withinOneSecond(obj.MergedAt, retUpdatedAt) {
+ retUser.Name = obj.MergedBy.Login
+ retUser.URL = obj.MergedBy.HTMLURL
+ }
+ if retUser == (User{}) {
+ // "normal" comments
+ var comments []struct {
+ UpdatedAt time.Time `json:"updated_at"`
+ User struct {
+ Login string `json:"login"`
+ HTMLURL string `json:"html_url"`
+ } `json:"user"`
+ }
+ if err := httpGetPaginatedJSON("https://api.github.com/repos/"+user+"/"+repo+"/issues/"+prnum+"/comments", nil, &comments, githubPagination); err != nil {
+ return time.Time{}, User{}, err
+ }
+ for _, comment := range comments {
+ if withinOneSecond(comment.UpdatedAt, retUpdatedAt) {
+ retUser.Name = comment.User.Login
+ retUser.URL = comment.User.HTMLURL
+ break
+ }
+ }
+ }
+ if retUser == (User{}) {
+ // comments on a specific part of the diff
+ var reviewComments []struct {
+ UpdatedAt time.Time `json:"updated_at"`
+ User struct {
+ Login string `json:"login"`
+ HTMLURL string `json:"html_url"`
+ } `json:"user"`
+ }
+ if err := httpGetPaginatedJSON("https://api.github.com/repos/"+user+"/"+repo+"/pulls/"+prnum+"/comments", nil, &reviewComments, githubPagination); err != nil {
+ return time.Time{}, User{}, err
+ }
+ for _, comment := range reviewComments {
+ if withinOneSecond(comment.UpdatedAt, retUpdatedAt) {
+ retUser.Name = comment.User.Login
+ retUser.URL = comment.User.HTMLURL
+ break
+ }
+ }
+ }
+ if retUser == (User{}) {
+ var events []struct {
+ CreatedAt time.Time `json:"created_at"`
+ Actor struct {
+ Login string `json:"login"`
+ HTMLURL string `json:"html_url"`
+ } `json:"actor"`
+ }
+ if err := httpGetJSON("https://api.github.com/repos/"+user+"/"+repo+"/issues/"+prnum+"/events", nil, &events); err != nil {
+ return time.Time{}, User{}, err
+ }
+ for _, event := range events {
+ if withinOneSecond(event.CreatedAt, retUpdatedAt) {
+ retUser.Name = event.Actor.Login
+ retUser.URL = event.Actor.HTMLURL
+ break
+ }
+ }
+ }
+
+ return retUpdatedAt, retUser, nil
+ }
+ return time.Time{}, User{}, nil
+}