maintner: deduplicate issue references in parseGithubRefs

When parsing commit messages for references to GitHub issues,
parseGithubRefs used to add entries to GerritCL.GitHubIssueRefs
slice whenever there was a reference, even if that reference has
already appeared before.

The GitHubIssueRef type only contains minimal information about
a reference: the repository and the issue number. As a result,
there is very little to gain from tracking multiple references
separately. Most users of the API would likely prefer a list
of unique issue references than the raw list. So, change it to
return unique issue references only, and document that.

If in the future there is a need to track issue references
at a more granular level, where it matters whether there was
one or multiple references, the API can be revisited then.

Fixes golang/go#26113.

Change-Id: Ib51372736bcf49e3eae4cf111d0258733c742e61
Reviewed-on: https://go-review.googlesource.com/128119
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Dmitri Shuralyov 2018-08-06 20:16:54 -04:00
Родитель dcbfa19f24
Коммит e7a2a012f3
3 изменённых файлов: 20 добавлений и 2 удалений

Просмотреть файл

@ -298,6 +298,7 @@ type GerritCL struct {
Private bool
// GitHubIssueRefs are parsed references to GitHub issues.
// Multiple references to the same issue are deduplicated.
GitHubIssueRefs []GitHubIssueRef
// Messages contains all of the messages for this CL, in sorted order.

Просмотреть файл

@ -2155,6 +2155,8 @@ func makeGithubResponse(res *http.Response) *github.Response {
var rxReferences = regexp.MustCompile(`(?:\b([\w\-]+)/([\w\-]+))?\#(\d+)\b`)
// parseGithubRefs parses references to GitHub issues from commit message commitMsg.
// Multiple references to the same issue are deduplicated.
func (c *Corpus) parseGithubRefs(gerritProj string, commitMsg string) []GitHubIssueRef {
// Use of rxReferences by itself caused this function to take 20% of the CPU time.
// TODO(bradfitz): stop using regexps here.
@ -2203,12 +2205,25 @@ func (c *Corpus) parseGithubRefs(gerritProj string, commitMsg string) []GitHubIs
continue
}
}
gr := github.getOrCreateRepo(owner, repo)
refs = append(refs, GitHubIssueRef{gr, int32(num)})
ref := GitHubIssueRef{github.getOrCreateRepo(owner, repo), int32(num)}
if contains(refs, ref) {
continue
}
refs = append(refs, ref)
}
return refs
}
// contains reports whether refs contains the reference ref.
func contains(refs []GitHubIssueRef, ref GitHubIssueRef) bool {
for _, r := range refs {
if r == ref {
return true
}
}
return false
}
type limitTransport struct {
limiter *rate.Limiter
base http.RoundTripper

Просмотреть файл

@ -573,6 +573,8 @@ func TestParseGithubRefs(t *testing.T) {
{"go.googlesource.com/go", "Fixes golang/go#1234", []string{"golang/go#1234"}},
{"go.googlesource.com/go", "Fixes golang/go#1234\n", []string{"golang/go#1234"}},
{"go.googlesource.com/go", "Fixes golang/go#1234.", []string{"golang/go#1234"}},
{"go.googlesource.com/go", "Mention issue #1234 a second time.\n\nFixes #1234.", []string{"golang/go#1234"}},
{"go.googlesource.com/go", "Mention issue #1234 a second time.\n\nFixes #1234.\nUpdates #1235.", []string{"golang/go#1234", "golang/go#1235"}},
{"go.googlesource.com/net", "Fixes golang/go#1234.", []string{"golang/go#1234"}},
{"go.googlesource.com/net", "Fixes #1234", nil},
}