+2
-69
appview/db/pulls.go
+2
-69
appview/db/pulls.go
···
9
9
"strings"
10
10
"time"
11
11
12
-
"github.com/bluekeyes/go-gitdiff/gitdiff"
13
12
"github.com/bluesky-social/indigo/atproto/syntax"
14
13
"tangled.sh/tangled.sh/core/api/tangled"
15
14
"tangled.sh/tangled.sh/core/patchutil"
···
203
202
return p.StackId != ""
204
203
}
205
204
206
-
func (s PullSubmission) AsDiff(targetBranch string) ([]*gitdiff.File, error) {
207
-
patch := s.Patch
208
-
209
-
// if format-patch; then extract each patch
210
-
var diffs []*gitdiff.File
211
-
if patchutil.IsFormatPatch(patch) {
212
-
patches, err := patchutil.ExtractPatches(patch)
213
-
if err != nil {
214
-
return nil, err
215
-
}
216
-
var ps [][]*gitdiff.File
217
-
for _, p := range patches {
218
-
ps = append(ps, p.Files)
219
-
}
220
-
221
-
diffs = patchutil.CombineDiff(ps...)
222
-
} else {
223
-
d, _, err := gitdiff.Parse(strings.NewReader(patch))
224
-
if err != nil {
225
-
return nil, err
226
-
}
227
-
diffs = d
228
-
}
229
-
230
-
return diffs, nil
231
-
}
232
-
233
-
func (s PullSubmission) AsNiceDiff(targetBranch string) types.NiceDiff {
234
-
diffs, err := s.AsDiff(targetBranch)
235
-
if err != nil {
236
-
log.Println(err)
237
-
}
238
-
239
-
nd := types.NiceDiff{}
240
-
nd.Commit.Parent = targetBranch
241
-
242
-
for _, d := range diffs {
243
-
ndiff := types.Diff{}
244
-
ndiff.Name.New = d.NewName
245
-
ndiff.Name.Old = d.OldName
246
-
ndiff.IsBinary = d.IsBinary
247
-
ndiff.IsNew = d.IsNew
248
-
ndiff.IsDelete = d.IsDelete
249
-
ndiff.IsCopy = d.IsCopy
250
-
ndiff.IsRename = d.IsRename
251
-
252
-
for _, tf := range d.TextFragments {
253
-
ndiff.TextFragments = append(ndiff.TextFragments, *tf)
254
-
for _, l := range tf.Lines {
255
-
switch l.Op {
256
-
case gitdiff.OpAdd:
257
-
nd.Stat.Insertions += 1
258
-
case gitdiff.OpDelete:
259
-
nd.Stat.Deletions += 1
260
-
}
261
-
}
262
-
}
263
-
264
-
nd.Diff = append(nd.Diff, ndiff)
265
-
}
266
-
267
-
nd.Stat.FilesChanged = len(diffs)
268
-
269
-
return nd
270
-
}
271
-
272
205
func (s PullSubmission) IsFormatPatch() bool {
273
206
return patchutil.IsFormatPatch(s.Patch)
274
207
}
275
208
276
-
func (s PullSubmission) AsFormatPatch() []patchutil.FormatPatch {
209
+
func (s PullSubmission) AsFormatPatch() []types.FormatPatch {
277
210
patches, err := patchutil.ExtractPatches(s.Patch)
278
211
if err != nil {
279
212
log.Println("error extracting patches from submission:", err)
280
-
return []patchutil.FormatPatch{}
213
+
return []types.FormatPatch{}
281
214
}
282
215
283
216
return patches
+6
-5
appview/state/pull.go
+6
-5
appview/state/pull.go
···
305
305
}
306
306
}
307
307
308
-
diff := pull.Submissions[roundIdInt].AsNiceDiff(pull.TargetBranch)
308
+
patch := pull.Submissions[roundIdInt].Patch
309
+
diff := patchutil.AsNiceDiff(patch, pull.TargetBranch)
309
310
310
311
s.pages.RepoPullPatchPage(w, pages.RepoPullPatchParams{
311
312
LoggedInUser: user,
···
361
362
}
362
363
}
363
364
364
-
currentPatch, err := pull.Submissions[roundIdInt].AsDiff(pull.TargetBranch)
365
+
currentPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt].Patch)
365
366
if err != nil {
366
367
log.Println("failed to interdiff; current patch malformed")
367
368
s.pages.Notice(w, fmt.Sprintf("interdiff-error-%d", roundIdInt), "Failed to calculate interdiff; current patch is invalid.")
368
369
return
369
370
}
370
371
371
-
previousPatch, err := pull.Submissions[roundIdInt-1].AsDiff(pull.TargetBranch)
372
+
previousPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt-1].Patch)
372
373
if err != nil {
373
374
log.Println("failed to interdiff; previous patch malformed")
374
375
s.pages.Notice(w, fmt.Sprintf("interdiff-error-%d", roundIdInt), "Failed to calculate interdiff; previous patch is invalid.")
···
1143
1144
return
1144
1145
}
1145
1146
1146
-
branches := result.Branches
1147
+
branches := result.Branches
1147
1148
sort.Slice(branches, func(i int, j int) bool {
1148
1149
return branches[i].Commit.Committer.When.After(branches[j].Commit.Committer.When)
1149
1150
})
···
1233
1234
1234
1235
s.pages.PullCompareForkBranchesFragment(w, pages.PullCompareForkBranchesParams{
1235
1236
RepoInfo: f.RepoInfo(s, user),
1236
-
SourceBranches: sourceResult.Branches,
1237
+
SourceBranches: sourceBranches,
1237
1238
TargetBranches: targetResult.Branches,
1238
1239
})
1239
1240
}
+9
-5
appview/state/repo.go
+9
-5
appview/state/repo.go
···
2084
2084
return
2085
2085
}
2086
2086
2087
-
forks, err := db.GetForksByDid(s.db, user.Did)
2088
-
if err != nil {
2089
-
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2090
-
log.Println("failed to get forks", err)
2091
-
return
2087
+
var forks []db.Repo
2088
+
if user != nil {
2089
+
var err error
2090
+
forks, err = db.GetForksByDid(s.db, user.Did)
2091
+
if err != nil {
2092
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2093
+
log.Println("failed to get forks", err)
2094
+
return
2095
+
}
2092
2096
}
2093
2097
2094
2098
s.pages.RepoCompare(w, pages.RepoCompareParams{
+3
-3
knotserver/git/diff.go
+3
-3
knotserver/git/diff.go
···
127
127
128
128
// FormatPatch generates a git-format-patch output between two commits,
129
129
// and returns the raw format-patch series, a parsed FormatPatch and an error.
130
-
func (g *GitRepo) formatSinglePatch(base, commit2 plumbing.Hash, extraArgs ...string) (string, *patchutil.FormatPatch, error) {
130
+
func (g *GitRepo) formatSinglePatch(base, commit2 plumbing.Hash, extraArgs ...string) (string, *types.FormatPatch, error) {
131
131
var stdout bytes.Buffer
132
132
133
133
args := []string{
···
222
222
return commits, nil
223
223
}
224
224
225
-
func (g *GitRepo) FormatPatch(base, commit2 *object.Commit) (string, []patchutil.FormatPatch, error) {
225
+
func (g *GitRepo) FormatPatch(base, commit2 *object.Commit) (string, []types.FormatPatch, error) {
226
226
// get list of commits between commir2 and base
227
227
commits, err := g.commitsBetween(commit2, base)
228
228
if err != nil {
···
233
233
slices.Reverse(commits)
234
234
235
235
var allPatchesContent strings.Builder
236
-
var allPatches []patchutil.FormatPatch
236
+
var allPatches []types.FormatPatch
237
237
238
238
for _, commit := range commits {
239
239
changeId := ""
+69
-16
patchutil/patchutil.go
+69
-16
patchutil/patchutil.go
···
2
2
3
3
import (
4
4
"fmt"
5
+
"log"
5
6
"os"
6
7
"os/exec"
7
8
"regexp"
···
9
10
"strings"
10
11
11
12
"github.com/bluekeyes/go-gitdiff/gitdiff"
13
+
"tangled.sh/tangled.sh/core/types"
12
14
)
13
15
14
-
type FormatPatch struct {
15
-
Files []*gitdiff.File
16
-
*gitdiff.PatchHeader
17
-
Raw string
18
-
}
19
-
20
-
func (f FormatPatch) ChangeId() (string, error) {
21
-
if vals, ok := f.RawHeaders["Change-Id"]; ok && len(vals) == 1 {
22
-
return vals[0], nil
23
-
}
24
-
return "", fmt.Errorf("no change-id found")
25
-
}
26
-
27
-
func ExtractPatches(formatPatch string) ([]FormatPatch, error) {
16
+
func ExtractPatches(formatPatch string) ([]types.FormatPatch, error) {
28
17
patches := splitFormatPatch(formatPatch)
29
18
30
-
result := []FormatPatch{}
19
+
result := []types.FormatPatch{}
31
20
32
21
for _, patch := range patches {
33
22
files, headerStr, err := gitdiff.Parse(strings.NewReader(patch))
···
40
29
return nil, fmt.Errorf("failed to parse patch header: %w", err)
41
30
}
42
31
43
-
result = append(result, FormatPatch{
32
+
result = append(result, types.FormatPatch{
44
33
Files: files,
45
34
PatchHeader: header,
46
35
Raw: patch,
···
263
252
return strings.Compare(bestName(a), bestName(b))
264
253
})
265
254
}
255
+
256
+
func AsDiff(patch string) ([]*gitdiff.File, error) {
257
+
// if format-patch; then extract each patch
258
+
var diffs []*gitdiff.File
259
+
if IsFormatPatch(patch) {
260
+
patches, err := ExtractPatches(patch)
261
+
if err != nil {
262
+
return nil, err
263
+
}
264
+
var ps [][]*gitdiff.File
265
+
for _, p := range patches {
266
+
ps = append(ps, p.Files)
267
+
}
268
+
269
+
diffs = CombineDiff(ps...)
270
+
} else {
271
+
d, _, err := gitdiff.Parse(strings.NewReader(patch))
272
+
if err != nil {
273
+
return nil, err
274
+
}
275
+
diffs = d
276
+
}
277
+
278
+
return diffs, nil
279
+
}
280
+
281
+
func AsNiceDiff(patch, targetBranch string) types.NiceDiff {
282
+
diffs, err := AsDiff(patch)
283
+
if err != nil {
284
+
log.Println(err)
285
+
}
286
+
287
+
nd := types.NiceDiff{}
288
+
nd.Commit.Parent = targetBranch
289
+
290
+
for _, d := range diffs {
291
+
ndiff := types.Diff{}
292
+
ndiff.Name.New = d.NewName
293
+
ndiff.Name.Old = d.OldName
294
+
ndiff.IsBinary = d.IsBinary
295
+
ndiff.IsNew = d.IsNew
296
+
ndiff.IsDelete = d.IsDelete
297
+
ndiff.IsCopy = d.IsCopy
298
+
ndiff.IsRename = d.IsRename
299
+
300
+
for _, tf := range d.TextFragments {
301
+
ndiff.TextFragments = append(ndiff.TextFragments, *tf)
302
+
for _, l := range tf.Lines {
303
+
switch l.Op {
304
+
case gitdiff.OpAdd:
305
+
nd.Stat.Insertions += 1
306
+
case gitdiff.OpDelete:
307
+
nd.Stat.Deletions += 1
308
+
}
309
+
}
310
+
}
311
+
312
+
nd.Diff = append(nd.Diff, ndiff)
313
+
}
314
+
315
+
nd.Stat.FilesChanged = len(diffs)
316
+
317
+
return nd
318
+
}
+20
types/patch.go
+20
types/patch.go
···
1
+
package types
2
+
3
+
import (
4
+
"fmt"
5
+
6
+
"github.com/bluekeyes/go-gitdiff/gitdiff"
7
+
)
8
+
9
+
type FormatPatch struct {
10
+
Files []*gitdiff.File
11
+
*gitdiff.PatchHeader
12
+
Raw string
13
+
}
14
+
15
+
func (f FormatPatch) ChangeId() (string, error) {
16
+
if vals, ok := f.RawHeaders["Change-Id"]; ok && len(vals) == 1 {
17
+
return vals[0], nil
18
+
}
19
+
return "", fmt.Errorf("no change-id found")
20
+
}
+5
-6
types/repo.go
+5
-6
types/repo.go
···
2
2
3
3
import (
4
4
"github.com/go-git/go-git/v5/plumbing/object"
5
-
"tangled.sh/tangled.sh/core/patchutil"
6
5
)
7
6
8
7
type RepoIndexResponse struct {
···
34
33
}
35
34
36
35
type RepoFormatPatchResponse struct {
37
-
Rev1 string `json:"rev1,omitempty"`
38
-
Rev2 string `json:"rev2,omitempty"`
39
-
FormatPatch []patchutil.FormatPatch `json:"format_patch,omitempty"`
40
-
MergeBase string `json:"merge_base,omitempty"`
41
-
Patch string `json:"patch,omitempty"`
36
+
Rev1 string `json:"rev1,omitempty"`
37
+
Rev2 string `json:"rev2,omitempty"`
38
+
FormatPatch []FormatPatch `json:"format_patch,omitempty"`
39
+
MergeBase string `json:"merge_base,omitempty"`
40
+
Patch string `json:"patch,omitempty"`
42
41
}
43
42
44
43
type RepoTreeResponse struct {