forked from forgejo/forgejo
Fix a couple of CommentAsPatch issues. (#14804)
* CutDiffAroundLine makes the incorrect assumption that `---` and `+++` always represent part of the header of a diff. This PR adds a flag to its parsing to prevent this problem and adds a streaming parsing technique to CutDiffAroundLine using an io.pipe instead of just sending data to an unbounded buffer. Fix #14711 Signed-off-by: Andrew Thornton <art27@cantab.net> * Handle unquoted comment patch files When making comment patches unfortunately the patch does not always quote the filename This makes the diff --git header ambiguous again. This PR finally adds handling for ambiguity in to parse patch Fix #14812 Signed-off-by: Andrew Thornton <art27@cantab.net> * Add in testing for no error There is no way currently for CutDiffAroundLine in this test to cause an error however, it should still be tested. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
904a26c57c
commit
3d8b5ad5f3
6 changed files with 270 additions and 41 deletions
|
@ -125,30 +125,39 @@ var hunkRegex = regexp.MustCompile(`^@@ -(?P<beginOld>[0-9]+)(,(?P<endOld>[0-9]+
|
|||
|
||||
const cmdDiffHead = "diff --git "
|
||||
|
||||
func isHeader(lof string) bool {
|
||||
return strings.HasPrefix(lof, cmdDiffHead) || strings.HasPrefix(lof, "---") || strings.HasPrefix(lof, "+++")
|
||||
func isHeader(lof string, inHunk bool) bool {
|
||||
return strings.HasPrefix(lof, cmdDiffHead) || (!inHunk && (strings.HasPrefix(lof, "---") || strings.HasPrefix(lof, "+++")))
|
||||
}
|
||||
|
||||
// CutDiffAroundLine cuts a diff of a file in way that only the given line + numberOfLine above it will be shown
|
||||
// it also recalculates hunks and adds the appropriate headers to the new diff.
|
||||
// Warning: Only one-file diffs are allowed.
|
||||
func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLine int) string {
|
||||
func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLine int) (string, error) {
|
||||
if line == 0 || numbersOfLine == 0 {
|
||||
// no line or num of lines => no diff
|
||||
return ""
|
||||
return "", nil
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(originalDiff)
|
||||
hunk := make([]string, 0)
|
||||
|
||||
// begin is the start of the hunk containing searched line
|
||||
// end is the end of the hunk ...
|
||||
// currentLine is the line number on the side of the searched line (differentiated by old)
|
||||
// otherLine is the line number on the opposite side of the searched line (differentiated by old)
|
||||
var begin, end, currentLine, otherLine int64
|
||||
var headerLines int
|
||||
|
||||
inHunk := false
|
||||
|
||||
for scanner.Scan() {
|
||||
lof := scanner.Text()
|
||||
// Add header to enable parsing
|
||||
if isHeader(lof) {
|
||||
|
||||
if isHeader(lof, inHunk) {
|
||||
if strings.HasPrefix(lof, cmdDiffHead) {
|
||||
inHunk = false
|
||||
}
|
||||
hunk = append(hunk, lof)
|
||||
headerLines++
|
||||
}
|
||||
|
@ -157,6 +166,7 @@ func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLi
|
|||
}
|
||||
// Detect "hunk" with contains commented lof
|
||||
if strings.HasPrefix(lof, "@@") {
|
||||
inHunk = true
|
||||
// Already got our hunk. End of hunk detected!
|
||||
if len(hunk) > headerLines {
|
||||
break
|
||||
|
@ -213,15 +223,19 @@ func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLi
|
|||
}
|
||||
}
|
||||
}
|
||||
err := scanner.Err()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// No hunk found
|
||||
if currentLine == 0 {
|
||||
return ""
|
||||
return "", nil
|
||||
}
|
||||
// headerLines + hunkLine (1) = totalNonCodeLines
|
||||
if len(hunk)-headerLines-1 <= numbersOfLine {
|
||||
// No need to cut the hunk => return existing hunk
|
||||
return strings.Join(hunk, "\n")
|
||||
return strings.Join(hunk, "\n"), nil
|
||||
}
|
||||
var oldBegin, oldNumOfLines, newBegin, newNumOfLines int64
|
||||
if old {
|
||||
|
@ -256,5 +270,5 @@ func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLi
|
|||
// construct the new hunk header
|
||||
newHunk[headerLines] = fmt.Sprintf("@@ -%d,%d +%d,%d @@",
|
||||
oldBegin, oldNumOfLines, newBegin, newNumOfLines)
|
||||
return strings.Join(newHunk, "\n")
|
||||
return strings.Join(newHunk, "\n"), nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue