package main import ( "fmt" "regexp" "strings" "time" ) var ( rePiperMailDate = regexp.MustCompile(`^\s*([^<]+)\s*$`) reGitHubCommit = regexp.MustCompile(`^https://github\.com/([^/?#]+)/([^/?#]+)/commit/([0-9a-f]+)(?:\?[^#]*)?(?:#.*)?$`) ) type PiperMail struct{} var _ Forge = PiperMail{} func (PiperMail) FetchStatus(urls []string) (string, error) { var gitURL string var gitCommits []string for _, u := range urls { if m := reGitHubCommit.FindStringSubmatch(u); m != nil { user := m[1] repo := m[2] hash := m[3] gitURL = "https://github.com/" + user + "/" + repo gitCommits = append(gitCommits, hash) } } if len(gitCommits) == 0 { return "", nil } ret := statusMerged tag, err := getGitTagThatContainsAll(gitURL, gitCommits...) if err != nil { return "", err } if tag != "" { ret = fmt.Sprintf(statusReleasedFmt, tag) } return ret, nil } func (PiperMail) FetchSubmittedAt(urls []string) (time.Time, error) { for _, u := range urls { if !strings.Contains(u, "/pipermail/") { continue } htmlStr, err := httpGet(u, nil) if err != nil { return time.Time{}, err } for _, line := range strings.Split(htmlStr, "\n") { if m := rePiperMailDate.FindStringSubmatch(line); m != nil { return time.Parse(time.UnixDate, m[1]) } } } return time.Time{}, nil } func (PiperMail) FetchLastUpdated(urls []string) (time.Time, User, error) { var ret time.Time for _, u := range urls { if m := reGitHubCommit.FindStringSubmatch(u); m != nil { user := m[1] repo := m[2] hash := m[3] urlStr := "https://api.github.com/repos/" + user + "/" + repo + "/commits/" + hash var obj struct { Commit struct { Author struct { Date time.Time `json:"date"` } `json:"author"` Committer struct { Date time.Time `json:"date"` } `json:"committer"` } `json:"commit"` } if err := httpGetJSON(urlStr, nil, &obj); err != nil { return time.Time{}, User{}, err } if obj.Commit.Author.Date.After(ret) { ret = obj.Commit.Author.Date } if obj.Commit.Committer.Date.After(ret) { ret = obj.Commit.Committer.Date } } } if ret.IsZero() { return time.Time{}, User{}, nil } return ret, User{}, nil }