diff --git a/main.go b/main.go index 8cde844..fd99832 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,6 @@ /* -Copyright 2017, 2020 Vector Creations Ltd +Copyright 2017 Vector Creations Ltd +Copyright 2020 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -48,7 +49,10 @@ type config struct { // A GitHub personal access token, to create a GitHub issue for each report. GithubToken string `yaml:"github_token"` - GithubProjectMappings map[string]string `yaml:"github_project_mappings"` + // Mappings from app name (as submitted in the API) to github repo for issue reporting. + GithubProjectMappings map[string]string `yaml:"github_project_mappings"` + // Mappings from app name (as submitted in the API) to github repo as to which the issues pertain. + // Not needed if the issues are reported to the main repo as github will complete the ambiguous references correctly. AutocompleteProjectMappings map[string]string `yaml:"autocomplete_project_mappings"` SlackWebhookURL string `yaml:"slack_webhook_url"` diff --git a/submit.go b/submit.go index a31aecb..52825ac 100644 --- a/submit.go +++ b/submit.go @@ -1,5 +1,6 @@ /* -Copyright 2017, 2020 Vector Creations Ltd +Copyright 2017 Vector Creations Ltd +Copyright 2020 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -120,7 +121,12 @@ type submitResponse struct { } // regex to catch and substitute ambiguous issue references with explicit ones to the actual repo they are in -var ambiguousIssueRegex = regexp.MustCompile(`[\s,.](#\d+)`) +var ambiguousIssueRegex = regexp.MustCompile(`(^|[([{\s])(#\d+)([^\w]|$)`) + +func replaceAmbiguousIssueReferences(ownerRepo, text string) string { + t := ambiguousIssueRegex.ReplaceAllString(text, fmt.Sprintf("${1}%s$2$3", ownerRepo)) + return t +} func (s *submitServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { // if we attempt to return a response without reading the request body, @@ -168,7 +174,7 @@ func (s *submitServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { } if s.autocompleteProjectMappings[p.AppName] != "" { - p.UserText = ambiguousIssueRegex.ReplaceAllString(p.UserText, fmt.Sprintf("%s/$1", s.autocompleteProjectMappings[p.AppName])) + p.UserText = replaceAmbiguousIssueReferences(s.autocompleteProjectMappings[p.AppName], p.UserText) } resp, err := s.saveReport(req.Context(), *p, reportDir, listingURL) diff --git a/submit_test.go b/submit_test.go index f5cca86..499d1b8 100644 --- a/submit_test.go +++ b/submit_test.go @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2020 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -483,3 +484,20 @@ user_id: id } } } + +func TestAutocompleteIssueReferences(t *testing.T) { + tests := map[string]string{ + "Testing #123 Foobar": "Testing owner/repo#123 Foobar", // standard + "#123": "owner/repo#123", // first/last word + "test (#123) bar": "test (owner/repo#123) bar", // brackets + "Start #123. Now": "Start owner/repo#123. Now", // followed by punctuation + "#123foo": "#123foo", // ignore + } + + for text, expect := range tests { + got := replaceAmbiguousIssueReferences("owner/repo", text) + if expect != got { + t.Errorf("expected %s got %s", expect, got) + } + } +}