Skip to content

Commit dfd5174

Browse files
committed
Extract function and make testable
Signed-off-by: Andrew Thornton <[email protected]>
1 parent bd25bd6 commit dfd5174

File tree

2 files changed

+89
-64
lines changed

2 files changed

+89
-64
lines changed

modules/references/references.go

Lines changed: 68 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -235,77 +235,81 @@ func findAllIssueReferencesMarkdown(content string) []*rawReference {
235235
return findAllIssueReferencesBytes(bcontent, links)
236236
}
237237

238-
// FindAllIssueReferences returns a list of unvalidated references found in a string.
239-
func FindAllIssueReferences(content string) []IssueReference {
240-
// Need to convert fully qualified html references to local system to #/! short codes
241-
contentBytes := []byte(content)
242-
if re := getGiteaIssuePullPattern(); re != nil {
243-
// We will iterate through the content, rewrite and simplify full references.
244-
//
245-
// We want to transform something like:
246-
//
247-
// 0 1 2 3 4 5 6
248-
// 012345678901234567890123456789012345678901234567890123456789012345789
249-
// this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo
250-
// https://ourgitea.com/git/owner/repo/pulls/123456789
251-
//
252-
// Into something like:
253-
//
254-
// this is a #123456789, foo
255-
// !123456789
256-
257-
pos := 0
258-
for {
259-
// re looks for something like: (\s|^|\(|\[)https://ourgitea.com/git/(owner/repo)/(issues)/(123456789)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)
260-
match := re.FindSubmatchIndex(contentBytes[pos:])
261-
if match == nil {
262-
break
263-
}
264-
// match is a bunch of indices into the content from pos onwards so if our content is:
238+
func convertFullHTMLReferencesToShortRefs(re *regexp.Regexp, contentBytes *[]byte) {
239+
// We will iterate through the content, rewrite and simplify full references.
240+
//
241+
// We want to transform something like:
242+
//
243+
// 0 1 2 3 4 5 6
244+
// 012345678901234567890123456789012345678901234567890123456789012345789
245+
// this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo
246+
// https://ourgitea.com/git/owner/repo/pulls/123456789
247+
//
248+
// Into something like:
249+
//
250+
// this is a #123456789, foo
251+
// !123456789
265252

266-
// To simplify things let's just add pos to all of the indices in match
267-
for i := range match {
268-
match[i] += pos
269-
}
253+
pos := 0
254+
for {
255+
// re looks for something like: (\s|^|\(|\[)https://ourgitea.com/git/(owner/repo)/(issues)/(123456789)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)
256+
match := re.FindSubmatchIndex((*contentBytes)[pos:])
257+
if match == nil {
258+
break
259+
}
260+
// match is a bunch of indices into the content from pos onwards so if our content is:
261+
262+
// To simplify things let's just add pos to all of the indices in match
263+
for i := range match {
264+
match[i] += pos
265+
}
270266

271-
// match[0]-match[1] is whole string
272-
// match[2]-match[3] is preamble
267+
// match[0]-match[1] is whole string
268+
// match[2]-match[3] is preamble
273269

274-
// move the position to the end of the preamble
275-
pos = match[3]
270+
// move the position to the end of the preamble
271+
pos = match[3]
276272

277-
// match[4]-match[5] is owner/repo
278-
// now copy the owner/repo to end of the preamble
279-
endPos := pos + match[5] - match[4]
280-
copy(contentBytes[pos:endPos], contentBytes[match[4]:match[5]])
273+
// match[4]-match[5] is owner/repo
274+
// now copy the owner/repo to end of the preamble
275+
endPos := pos + match[5] - match[4]
276+
copy((*contentBytes)[pos:endPos], (*contentBytes)[match[4]:match[5]])
281277

282-
// move the current position to the end of the newly copied owner/repo
283-
pos = endPos
278+
// move the current position to the end of the newly copied owner/repo
279+
pos = endPos
284280

285-
// Now set the issue/pull marker:
286-
//
287-
// match[6]-match[7] == 'issues'
288-
contentBytes[pos] = '#'
289-
if string(contentBytes[match[6]:match[7]]) == "pulls" {
290-
contentBytes[pos] = '!'
291-
}
292-
pos++
293-
294-
// Then add the issue/pull number
295-
//
296-
// match[8]-match[9] is the number
297-
endPos = pos + match[9] - match[8]
298-
copy(contentBytes[pos:endPos], contentBytes[match[8]:match[9]])
299-
300-
// Now copy what's left at the end of the string to the new end position
301-
copy(contentBytes[endPos:], contentBytes[match[9]:])
302-
// now we reset the length
303-
304-
// our new section has length endPos - match[3]
305-
// our old section has length match[9] - match[3]
306-
contentBytes = contentBytes[:len(contentBytes)-match[9]+endPos]
307-
pos = endPos
281+
// Now set the issue/pull marker:
282+
//
283+
// match[6]-match[7] == 'issues'
284+
(*contentBytes)[pos] = '#'
285+
if string((*contentBytes)[match[6]:match[7]]) == "pulls" {
286+
(*contentBytes)[pos] = '!'
308287
}
288+
pos++
289+
290+
// Then add the issue/pull number
291+
//
292+
// match[8]-match[9] is the number
293+
endPos = pos + match[9] - match[8]
294+
copy((*contentBytes)[pos:endPos], (*contentBytes)[match[8]:match[9]])
295+
296+
// Now copy what's left at the end of the string to the new end position
297+
copy((*contentBytes)[endPos:], (*contentBytes)[match[9]:])
298+
// now we reset the length
299+
300+
// our new section has length endPos - match[3]
301+
// our old section has length match[9] - match[3]
302+
(*contentBytes) = (*contentBytes)[:len((*contentBytes))-match[9]+endPos]
303+
pos = endPos
304+
}
305+
}
306+
307+
// FindAllIssueReferences returns a list of unvalidated references found in a string.
308+
func FindAllIssueReferences(content string) []IssueReference {
309+
// Need to convert fully qualified html references to local system to #/! short codes
310+
contentBytes := []byte(content)
311+
if re := getGiteaIssuePullPattern(); re != nil {
312+
convertFullHTMLReferencesToShortRefs(re, &contentBytes)
309313
} else {
310314
log.Debug("No GiteaIssuePullPattern pattern")
311315
}

modules/references/references_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package references
66

77
import (
8+
"regexp"
89
"testing"
910

1011
"code.gitea.io/gitea/modules/setting"
@@ -29,6 +30,26 @@ type testResult struct {
2930
TimeLog string
3031
}
3132

33+
func TestConvertFullHTMLReferencesToShortRefs(t *testing.T) {
34+
re := regexp.MustCompile(`(\s|^|\(|\[)` +
35+
regexp.QuoteMeta("https://ourgitea.com/git/") +
36+
`([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+)/` +
37+
`((?:issues)|(?:pulls))/([0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
38+
test := `this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo
39+
https://ourgitea.com/git/owner/repo/pulls/123456789
40+
And https://ourgitea.com/git/owner/repo/pulls/123
41+
`
42+
expect := `this is a owner/repo#123456789, foo
43+
owner/repo!123456789
44+
And owner/repo!123
45+
`
46+
47+
contentBytes := []byte(test)
48+
convertFullHTMLReferencesToShortRefs(re, &contentBytes)
49+
result := string(contentBytes)
50+
assert.EqualValues(t, expect, result)
51+
}
52+
3253
func TestFindAllIssueReferences(t *testing.T) {
3354

3455
fixtures := []testFixture{

0 commit comments

Comments
 (0)