Skip to content

Commit 4e39002

Browse files
committed
Add inline diff in repos/pulls/files api
Add the inline diff on a per file basis to be compatible with GitHub Example: ``` curl http://localhost:3000/api/v1/repos/cedstrom/test/pulls/1/files?token=[redacted] ``` ``` [ { "filename": ".gitignore", "status": "added", "additions": 2, "deletions": 0, "changes": 2, "html_url": "http://localhost:3000/cedstrom/test/src/commit/ce2c53223388eaaa026c25156b807e30acc05a56/.gitignore", "contents_url": "http://localhost:3000/api/v1/repos/cedstrom/test/contents/.gitignore?ref=ce2c53223388eaaa026c25156b807e30acc05a56", "raw_url": "http://localhost:3000/cedstrom/test/raw/commit/ce2c53223388eaaa026c25156b807e30acc05a56/.gitignore", "patch": "diff --git a/.gitignore b/.gitignore\n--- a/.gitignore\n+++ b/.gitignore\n@@ -0,1 +1,2 @@\n @@ -0,0 +1,2 @@\n++.env\n++.env.local\n\n" }, { "filename": "README.md", "status": "changed", "additions": 1, "deletions": 0, "changes": 1, "html_url": "http://localhost:3000/cedstrom/test/src/commit/ce2c53223388eaaa026c25156b807e30acc05a56/README.md", "contents_url": "http://localhost:3000/api/v1/repos/cedstrom/test/contents/README.md?ref=ce2c53223388eaaa026c25156b807e30acc05a56", "raw_url": "http://localhost:3000/cedstrom/test/raw/commit/ce2c53223388eaaa026c25156b807e30acc05a56/README.md", "patch": "diff --git a/README.md b/README.md\n--- a/README.md\n+++ b/README.md\n@@ -1,2 +1,3 @@\n @@ -1,2 +1,3 @@\n # test\n \n++This is my first PR.\n\n" } ] ```
1 parent 165a3ea commit 4e39002

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

modules/structs/pull.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,6 @@ type ChangedFile struct {
188188
ContentsURL string `json:"contents_url,omitempty"`
189189
// The raw URL to download the file
190190
RawURL string `json:"raw_url,omitempty"`
191+
// The patch text for the file changes
192+
Patch string `json:"patch,omitempty"`
191193
}

services/convert/convert.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit stri
812812
HTMLURL: fmt.Sprint(repo.HTMLURL(), "/src/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
813813
ContentsURL: fmt.Sprint(repo.APIURL(), "/contents/", util.PathEscapeSegments(f.GetDiffFileName()), "?ref=", commit),
814814
RawURL: fmt.Sprint(repo.HTMLURL(), "/raw/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
815+
Patch: gitdiff.RenderUnifiedDiff(f),
815816
}
816817

817818
return file

services/gitdiff/gitdiff.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,88 @@ func createDiffFile(line string) *DiffFile {
10581058
return curFile
10591059
}
10601060

1061+
func RenderUnifiedDiff(file *DiffFile) string {
1062+
var sb strings.Builder
1063+
1064+
oldPath := file.OldName
1065+
if oldPath == "" {
1066+
oldPath = file.Name
1067+
}
1068+
newPath := file.Name
1069+
1070+
// File header
1071+
fmt.Fprintf(&sb, "diff --git a/%s b/%s\n", oldPath, newPath)
1072+
fmt.Fprintf(&sb, "--- a/%s\n", oldPath)
1073+
fmt.Fprintf(&sb, "+++ b/%s\n", newPath)
1074+
1075+
if file.IsBin {
1076+
return ("Binary files differ\n\n")
1077+
}
1078+
1079+
for _, section := range file.Sections {
1080+
// Compute hunk header
1081+
leftStart, leftCount := hunkRange(section, true)
1082+
rightStart, rightCount := hunkRange(section, false)
1083+
fmt.Fprintf(&sb, "@@ -%d,%d +%d,%d @@\n", leftStart, leftCount, rightStart, rightCount)
1084+
1085+
for _, line := range section.Lines {
1086+
prefix := " "
1087+
switch line.Type {
1088+
case DiffLineAdd:
1089+
prefix = "+"
1090+
case DiffLineDel:
1091+
prefix = "-"
1092+
}
1093+
sb.WriteString(prefix + line.Content)
1094+
if !strings.HasSuffix(line.Content, "\n") {
1095+
sb.WriteString("\n")
1096+
}
1097+
}
1098+
}
1099+
sb.WriteString("\n")
1100+
1101+
return sb.String()
1102+
}
1103+
1104+
// hunkRange calculates the start and length for either old or new file in a section
1105+
func hunkRange(section *DiffSection, left bool) (start, count int) {
1106+
lines := section.Lines
1107+
if len(lines) == 0 {
1108+
return 0, 0
1109+
}
1110+
1111+
if left {
1112+
for _, l := range lines {
1113+
if l.LeftIdx > 0 {
1114+
start = l.LeftIdx
1115+
break
1116+
}
1117+
}
1118+
for _, l := range lines {
1119+
if l.LeftIdx > 0 {
1120+
count++
1121+
}
1122+
}
1123+
} else {
1124+
for _, l := range lines {
1125+
if l.RightIdx > 0 {
1126+
start = l.RightIdx
1127+
break
1128+
}
1129+
}
1130+
for _, l := range lines {
1131+
if l.RightIdx > 0 {
1132+
count++
1133+
}
1134+
}
1135+
}
1136+
1137+
if count == 0 {
1138+
count = 1
1139+
}
1140+
return start, count
1141+
}
1142+
10611143
func readFileName(rd *strings.Reader) (string, bool) {
10621144
ambiguity := false
10631145
var name string

templates/swagger/v1_json.tmpl

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)