diff options
Diffstat (limited to 'cmd/generate/forge_forgejo.go')
-rw-r--r-- | cmd/generate/forge_forgejo.go | 187 |
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 +} |