diff options
Diffstat (limited to 'cmd/generate/src_contribs.go')
-rw-r--r-- | cmd/generate/src_contribs.go | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/cmd/generate/src_contribs.go b/cmd/generate/src_contribs.go index eaff24b..b08e18d 100644 --- a/cmd/generate/src_contribs.go +++ b/cmd/generate/src_contribs.go @@ -1,10 +1,8 @@ package main import ( - "encoding/json" "fmt" - "io" - "net/http" + "net/url" "os" "regexp" "strings" @@ -20,21 +18,22 @@ type Contribution struct { Desc string `json:"desc"` SubmittedAt time.Time `json:"submitted-at"` + Status string `json:"status"` } func ReadContribs(filename string) ([]Contribution, error) { bs, err := os.ReadFile(filename) if err != nil { - return nil, err + return nil, fmt.Errorf("contribs: %q: %w", filename, err) } var ret []Contribution if err := yaml.UnmarshalStrict(bs, &ret); err != nil { - return nil, err + return nil, fmt.Errorf("contribs: %q: %w", filename, err) } for i := range ret { contrib := ret[i] if err := contrib.Fill(); err != nil { - return nil, err + return nil, fmt.Errorf("contribs: %q: %w", filename, err) } ret[i] = contrib } @@ -44,7 +43,13 @@ func ReadContribs(filename string) ([]Contribution, error) { func (c *Contribution) Fill() error { var err error if c.SubmittedAt.IsZero() { - c.SubmittedAt, err = c.getSubmittedAt() + c.SubmittedAt, err = c.fetchSubmittedAt() + if err != nil { + return err + } + } + if c.Status == "" { + c.Status, err = c.fetchStatus() if err != nil { return err } @@ -54,46 +59,88 @@ func (c *Contribution) Fill() error { var ( reGitHubPR = regexp.MustCompile(`^https://github.com/([^/?#]+)/([^/?#]+)/pull/([0-9]+)(?:\?[^#]*)?(?:#.*)?$`) + reGitLabMR = regexp.MustCompile(`^https://([^/]+)/([^?#]+)/-/merge_requests/([0-9]+)(?:\?[^#]*)?(?:#.*)?$`) rePiperMailDate = regexp.MustCompile(`^\s*<I>([^<]+)</I>\s*$`) ) -func (c Contribution) getSubmittedAt() (time.Time, error) { +func (c Contribution) fetchStatus() (string, error) { if m := reGitHubPR.FindStringSubmatch(c.URLs[0]); m != nil { user := m[1] repo := m[2] prnum := m[3] - resp, err := http.Get("https://api.github.com/repos/" + user + "/" + repo + "/pulls/" + prnum) - if err != nil { - return time.Time{}, err + + urlStr := "https://api.github.com/repos/" + user + "/" + repo + "/pulls/" + prnum + + var obj struct { + State string `json:"state"` } - if resp.StatusCode != http.StatusOK { - return time.Time{}, fmt.Errorf("unexpected HTTP status: %v", resp.Status) + if err := httpGetJSON(urlStr, &obj); err != nil { + return "", err } - jsonBytes, err := io.ReadAll(resp.Body) - if err != nil { - return time.Time{}, err + return obj.State, nil + } + if m := reGitLabMR.FindStringSubmatch(c.URLs[0]); m != nil { + 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 string `json:"state"` } + if err := httpGetJSON(urlStr, &obj); err != nil { + return "", err + } + return obj.State, nil + } + if len(c.URLs) > 1 { + for _, u := range c.URLs[1:] { + if strings.Contains(u, "/commit/") { + return "merged", nil + } + } + } + return "", fmt.Errorf("idk how to get status for %q", c.URLs[0]) +} + +func (c Contribution) fetchSubmittedAt() (time.Time, error) { + if m := reGitHubPR.FindStringSubmatch(c.URLs[0]); m != nil { + user := m[1] + repo := m[2] + prnum := m[3] + + urlStr := "https://api.github.com/repos/" + user + "/" + repo + "/pulls/" + prnum + var obj struct { CreatedAt time.Time `json:"created_at"` } - if err := json.Unmarshal(jsonBytes, &obj); err != nil { + if err := httpGetJSON(urlStr, &obj); err != nil { return time.Time{}, err } return obj.CreatedAt, nil } - if strings.Contains(c.URLs[0], "/pipermail/") { - resp, err := http.Get(c.URLs[0]) - if err != nil { - return time.Time{}, err + if m := reGitLabMR.FindStringSubmatch(c.URLs[0]); m != nil { + 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 resp.StatusCode != http.StatusOK { - return time.Time{}, fmt.Errorf("unexpected HTTP status: %v", resp.Status) + if err := httpGetJSON(urlStr, &obj); err != nil { + return time.Time{}, err } - htmlBytes, err := io.ReadAll(resp.Body) + return obj.CreatedAt, nil + } + if strings.Contains(c.URLs[0], "/pipermail/") { + htmlStr, err := httpGet(c.URLs[0]) if err != nil { return time.Time{}, err } - for _, line := range strings.Split(string(htmlBytes), "\n") { + for _, line := range strings.Split(htmlStr, "\n") { if m := rePiperMailDate.FindStringSubmatch(line); m != nil { return time.Parse(time.UnixDate, m[1]) } |