Skip to content

Commit 9757f20

Browse files
Merge branch 'master' into ui-edit/add-project-title
2 parents 579259c + 182b5a0 commit 9757f20

File tree

4 files changed

+129
-39
lines changed

4 files changed

+129
-39
lines changed

modules/git/blame.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type BlameReader struct {
2727
cmd *exec.Cmd
2828
pid int64
2929
output io.ReadCloser
30-
scanner *bufio.Scanner
30+
reader *bufio.Reader
3131
lastSha *string
3232
cancel context.CancelFunc
3333
}
@@ -38,36 +38,58 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
3838
func (r *BlameReader) NextPart() (*BlamePart, error) {
3939
var blamePart *BlamePart
4040

41-
scanner := r.scanner
41+
reader := r.reader
4242

4343
if r.lastSha != nil {
4444
blamePart = &BlamePart{*r.lastSha, make([]string, 0)}
4545
}
4646

47-
for scanner.Scan() {
48-
line := scanner.Text()
47+
var line []byte
48+
var isPrefix bool
49+
var err error
50+
51+
for err != io.EOF {
52+
line, isPrefix, err = reader.ReadLine()
53+
if err != nil && err != io.EOF {
54+
return blamePart, err
55+
}
4956

50-
// Skip empty lines
5157
if len(line) == 0 {
58+
// isPrefix will be false
5259
continue
5360
}
5461

55-
lines := shaLineRegex.FindStringSubmatch(line)
62+
lines := shaLineRegex.FindSubmatch(line)
5663
if lines != nil {
57-
sha1 := lines[1]
64+
sha1 := string(lines[1])
5865

5966
if blamePart == nil {
6067
blamePart = &BlamePart{sha1, make([]string, 0)}
6168
}
6269

6370
if blamePart.Sha != sha1 {
6471
r.lastSha = &sha1
72+
// need to munch to end of line...
73+
for isPrefix {
74+
_, isPrefix, err = reader.ReadLine()
75+
if err != nil && err != io.EOF {
76+
return blamePart, err
77+
}
78+
}
6579
return blamePart, nil
6680
}
6781
} else if line[0] == '\t' {
6882
code := line[1:]
6983

70-
blamePart.Lines = append(blamePart.Lines, code)
84+
blamePart.Lines = append(blamePart.Lines, string(code))
85+
}
86+
87+
// need to munch to end of line...
88+
for isPrefix {
89+
_, isPrefix, err = reader.ReadLine()
90+
if err != nil && err != io.EOF {
91+
return blamePart, err
92+
}
7193
}
7294
}
7395

@@ -121,13 +143,13 @@ func createBlameReader(ctx context.Context, dir string, command ...string) (*Bla
121143

122144
pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cancel)
123145

124-
scanner := bufio.NewScanner(stdout)
146+
reader := bufio.NewReader(stdout)
125147

126148
return &BlameReader{
127149
cmd,
128150
pid,
129151
stdout,
130-
scanner,
152+
reader,
131153
nil,
132154
cancel,
133155
}, nil

modules/references/references.go

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

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+
// this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo
244+
// https://ourgitea.com/git/owner/repo/pulls/123456789
245+
//
246+
// Into something like:
247+
//
248+
// this is a #123456789, foo
249+
// !123456789
250+
251+
pos := 0
252+
for {
253+
// re looks for something like: (\s|^|\(|\[)https://ourgitea.com/git/(owner/repo)/(issues)/(123456789)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)
254+
match := re.FindSubmatchIndex((*contentBytes)[pos:])
255+
if match == nil {
256+
break
257+
}
258+
// match is a bunch of indices into the content from pos onwards so
259+
// to simplify things let's just add pos to all of the indices in match
260+
for i := range match {
261+
match[i] += pos
262+
}
263+
264+
// match[0]-match[1] is whole string
265+
// match[2]-match[3] is preamble
266+
267+
// move the position to the end of the preamble
268+
pos = match[3]
269+
270+
// match[4]-match[5] is owner/repo
271+
// now copy the owner/repo to end of the preamble
272+
endPos := pos + match[5] - match[4]
273+
copy((*contentBytes)[pos:endPos], (*contentBytes)[match[4]:match[5]])
274+
275+
// move the current position to the end of the newly copied owner/repo
276+
pos = endPos
277+
278+
// Now set the issue/pull marker:
279+
//
280+
// match[6]-match[7] == 'issues'
281+
(*contentBytes)[pos] = '#'
282+
if string((*contentBytes)[match[6]:match[7]]) == "pulls" {
283+
(*contentBytes)[pos] = '!'
284+
}
285+
pos++
286+
287+
// Then add the issue/pull number
288+
//
289+
// match[8]-match[9] is the number
290+
endPos = pos + match[9] - match[8]
291+
copy((*contentBytes)[pos:endPos], (*contentBytes)[match[8]:match[9]])
292+
293+
// Now copy what's left at the end of the string to the new end position
294+
copy((*contentBytes)[endPos:], (*contentBytes)[match[9]:])
295+
// now we reset the length
296+
297+
// our new section has length endPos - match[3]
298+
// our old section has length match[9] - match[3]
299+
(*contentBytes) = (*contentBytes)[:len((*contentBytes))-match[9]+endPos]
300+
pos = endPos
301+
}
302+
}
303+
238304
// FindAllIssueReferences returns a list of unvalidated references found in a string.
239305
func FindAllIssueReferences(content string) []IssueReference {
240306
// Need to convert fully qualified html references to local system to #/! short codes
241307
contentBytes := []byte(content)
242308
if re := getGiteaIssuePullPattern(); re != nil {
243-
pos := 0
244-
for {
245-
match := re.FindSubmatchIndex(contentBytes[pos:])
246-
if match == nil {
247-
break
248-
}
249-
// match[0]-match[1] is whole string
250-
// match[2]-match[3] is preamble
251-
pos += match[3]
252-
// match[4]-match[5] is owner/repo
253-
endPos := pos + match[5] - match[4]
254-
copy(contentBytes[pos:endPos], contentBytes[match[4]:match[5]])
255-
pos = endPos
256-
// match[6]-match[7] == 'issues'
257-
contentBytes[pos] = '#'
258-
if string(contentBytes[match[6]:match[7]]) == "pulls" {
259-
contentBytes[pos] = '!'
260-
}
261-
pos++
262-
// match[8]-match[9] is the number
263-
endPos = pos + match[9] - match[8]
264-
copy(contentBytes[pos:endPos], contentBytes[match[8]:match[9]])
265-
copy(contentBytes[endPos:], contentBytes[match[9]:])
266-
// now we reset the length
267-
// our new section has length endPos - match[3]
268-
// our old section has length match[9] - match[3]
269-
contentBytes = contentBytes[:len(contentBytes)-match[9]+endPos]
270-
pos = endPos
271-
}
309+
convertFullHTMLReferencesToShortRefs(re, &contentBytes)
272310
} else {
273311
log.Debug("No GiteaIssuePullPattern pattern")
274312
}

modules/references/references_test.go

Lines changed: 28 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{
@@ -106,6 +127,13 @@ func TestFindAllIssueReferences(t *testing.T) {
106127
{202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""},
107128
},
108129
},
130+
{
131+
"This http://gitea.com:3000/user4/repo5/pulls/202 yes. http://gitea.com:3000/user4/repo5/pulls/203 no",
132+
[]testResult{
133+
{202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""},
134+
{203, "user4", "repo5", "203", true, XRefActionNone, nil, nil, ""},
135+
},
136+
},
109137
{
110138
"This http://GiTeA.COM:3000/user4/repo6/pulls/205 yes.",
111139
[]testResult{

web_src/less/_repository.less

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,9 @@
10001000
.comment-container {
10011001
border: 1px solid var(--color-secondary);
10021002
border-radius: var(--border-radius);
1003+
}
10031004

1005+
.content {
10041006
> .merge-section {
10051007
background-color: var(--color-box-body);
10061008

0 commit comments

Comments
 (0)