diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-05-19 02:29:46 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-05-19 02:29:46 -0600 |
commit | 632b189cfed31bf1a1f1edf0c1ae69f294ef4123 (patch) | |
tree | b375ecf1391247bcd4439b7880a69c86b042aa42 /cmd/generate/forge_gitlab.go | |
parent | 75d2ab4f4d2415b1ecead2361acddb1e6d6392dd (diff) |
cmd/generate: Factor forge_*.go files out of src_contribs.go
Diffstat (limited to 'cmd/generate/forge_gitlab.go')
-rw-r--r-- | cmd/generate/forge_gitlab.go | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/cmd/generate/forge_gitlab.go b/cmd/generate/forge_gitlab.go new file mode 100644 index 0000000..41814ec --- /dev/null +++ b/cmd/generate/forge_gitlab.go @@ -0,0 +1,160 @@ +package main + +import ( + "fmt" + "net/url" + "regexp" + "time" +) + +var reGitLabMR = regexp.MustCompile(`^https://([^/]+)/([^?#]+)/-/merge_requests/([0-9]+)(?:\?[^#]*)?(?:#.*)?$`) + +type GitLab struct{} + +var _ Forge = GitLab{} + +func (GitLab) FetchStatus(urls []string) (string, error) { + for _, u := range urls { + m := reGitLabMR.FindStringSubmatch(u) + if m == nil { + continue + } + authority := m[1] + projectID := m[2] + mrnum := m[3] + + urlStr := "https://" + authority + "/api/v4/projects/" + url.QueryEscape(projectID) + "/merge_requests/" + mrnum + + var obj struct { + // State values are "opened", "closed", "locked", and "merged". + State string `json:"state"` + MergeCommitSha string `json:"merge_commit_sha"` + SquashCommitSha string `json:"squash_commit_sha"` + } + if err := httpGetJSON(urlStr, nil, &obj); err != nil { + return "", err + } + + ret := obj.State + if ret == "opened" { + ret = statusOpen + } + + if ret == "merged" { + ret = statusMerged + var mergeCommit string + if obj.MergeCommitSha != "" { + mergeCommit = obj.MergeCommitSha + } + if obj.SquashCommitSha != "" { + mergeCommit = obj.SquashCommitSha + } + if mergeCommit != "" { + tag, err := getGitTagThatContainsAll("https://"+authority+"/"+projectID+".git", mergeCommit) + if err != nil { + return "", err + } + if tag != "" { + ret = fmt.Sprintf(statusReleasedFmt, tag) + } + } + } + + return ret, nil + } + return "", nil +} + +func (GitLab) FetchSubmittedAt(urls []string) (time.Time, error) { + for _, u := range urls { + m := reGitLabMR.FindStringSubmatch(u) + if m == nil { + continue + } + authority := m[1] + projectID := m[2] + mrnum := m[3] + + urlStr := "https://" + authority + "/api/v4/projects/" + url.QueryEscape(projectID) + "/merge_requests/" + mrnum + + 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 (GitLab) FetchLastUpdated(urls []string) (time.Time, User, error) { + for _, u := range urls { + m := reGitLabMR.FindStringSubmatch(u) + if m == nil { + continue + } + authority := m[1] + projectID := m[2] + mrnum := m[3] + + urlStr := "https://" + authority + "/api/v4/projects/" + url.QueryEscape(projectID) + "/merge_requests/" + mrnum + + var obj struct { + ID int `json:"id"` + + UpdatedAt time.Time `json:"updated_at"` + + CreatedAt time.Time `json:"created_at"` + CreatedBy struct { + Username string `json:"username"` + WebURL string `json:"web_url"` + } `json:"author"` + + MergedAt time.Time `json:"merged_at"` + MergedBy struct { + Username string `json:"username"` + WebURL string `json:"web_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.Username + retUser.URL = obj.CreatedBy.WebURL + } + if retUser == (User{}) && withinOneSecond(obj.MergedAt, retUpdatedAt) { + retUser.Name = obj.MergedBy.Username + retUser.URL = obj.MergedBy.WebURL + } + if retUser == (User{}) { + var notes struct { + Notes []struct { + UpdatedAt time.Time `json:"updated_at"` + Author struct { + Username string `json:"username"` + WebURL string `json:"web_url"` + } `json:"author"` + } `json:"notes"` + } + if err := httpGetJSON(fmt.Sprintf("https://%s/%s/noteable/merge_request/%d/notes", authority, projectID, obj.ID), map[string]string{"X-Last-Fetched-At": "0"}, ¬es); err != nil { + return time.Time{}, User{}, err + } + for _, note := range notes.Notes { + if withinOneSecond(note.UpdatedAt, retUpdatedAt) { + retUser.Name = note.Author.Username + retUser.URL = note.Author.WebURL + break + } + } + } + + return retUpdatedAt, retUser, nil + } + return time.Time{}, User{}, nil +} |