+1
-1
.tangled/workflows/build.yml
+1
-1
.tangled/workflows/build.yml
+1
-1
.tangled/workflows/fmt.yml
+1
-1
.tangled/workflows/fmt.yml
+1
-1
.tangled/workflows/test.yml
+1
-1
.tangled/workflows/test.yml
-9
appview/db/db.go
-9
appview/db/db.go
···
1097
1097
})
1098
1098
conn.ExecContext(ctx, "pragma foreign_keys = on;")
1099
1099
1100
-
// knots may report the combined patch for a comparison, we can store that on the appview side
1101
-
// (but not on the pds record), because calculating the combined patch requires a git index
1102
-
runMigration(conn, logger, "add-combined-column-submissions", func(tx *sql.Tx) error {
1103
-
_, err := tx.Exec(`
1104
-
alter table pull_submissions add column combined text;
1105
-
`)
1106
-
return err
1107
-
})
1108
-
1109
1100
return &DB{
1110
1101
db,
1111
1102
logger,
+20
-21
appview/db/pulls.go
+20
-21
appview/db/pulls.go
···
90
90
pull.ID = int(id)
91
91
92
92
_, err = tx.Exec(`
93
-
insert into pull_submissions (pull_at, round_number, patch, combined, source_rev)
94
-
values (?, ?, ?, ?, ?)
95
-
`, pull.PullAt(), 0, pull.Submissions[0].Patch, pull.Submissions[0].Combined, pull.Submissions[0].SourceRev)
93
+
insert into pull_submissions (pull_at, round_number, patch, source_rev)
94
+
values (?, ?, ?, ?)
95
+
`, pull.PullAt(), 0, pull.Submissions[0].Patch, pull.Submissions[0].SourceRev)
96
96
return err
97
97
}
98
98
···
313
313
pull_at,
314
314
round_number,
315
315
patch,
316
-
combined,
317
316
created,
318
317
source_rev
319
318
from
···
333
332
334
333
for rows.Next() {
335
334
var submission models.PullSubmission
336
-
var submissionCreatedStr string
337
-
var submissionSourceRev, submissionCombined sql.NullString
335
+
var createdAt string
336
+
var sourceRev sql.NullString
338
337
err := rows.Scan(
339
338
&submission.ID,
340
339
&submission.PullAt,
341
340
&submission.RoundNumber,
342
341
&submission.Patch,
343
-
&submissionCombined,
344
-
&submissionCreatedStr,
345
-
&submissionSourceRev,
342
+
&createdAt,
343
+
&sourceRev,
346
344
)
347
345
if err != nil {
348
346
return nil, err
349
347
}
350
348
351
-
if t, err := time.Parse(time.RFC3339, submissionCreatedStr); err == nil {
352
-
submission.Created = t
349
+
createdTime, err := time.Parse(time.RFC3339, createdAt)
350
+
if err != nil {
351
+
return nil, err
353
352
}
353
+
submission.Created = createdTime
354
354
355
-
if submissionSourceRev.Valid {
356
-
submission.SourceRev = submissionSourceRev.String
357
-
}
358
-
359
-
if submissionCombined.Valid {
360
-
submission.Combined = submissionCombined.String
355
+
if sourceRev.Valid {
356
+
submission.SourceRev = sourceRev.String
361
357
}
362
358
363
359
submissionMap[submission.ID] = &submission
···
594
590
return err
595
591
}
596
592
597
-
func ResubmitPull(e Execer, pullAt syntax.ATURI, newRoundNumber int, newPatch string, combinedPatch string, newSourceRev string) error {
593
+
func ResubmitPull(e Execer, pull *models.Pull) error {
594
+
newPatch := pull.LatestPatch()
595
+
newSourceRev := pull.LatestSha()
596
+
newRoundNumber := len(pull.Submissions)
598
597
_, err := e.Exec(`
599
-
insert into pull_submissions (pull_at, round_number, patch, combined, source_rev)
600
-
values (?, ?, ?, ?, ?)
601
-
`, pullAt, newRoundNumber, newPatch, combinedPatch, newSourceRev)
598
+
insert into pull_submissions (pull_at, round_number, patch, source_rev)
599
+
values (?, ?, ?, ?)
600
+
`, pull.PullAt(), newRoundNumber, newPatch, newSourceRev)
602
601
603
602
return err
604
603
}
+4
-4
appview/dns/cloudflare.go
+4
-4
appview/dns/cloudflare.go
···
30
30
return &Cloudflare{api: api, zone: c.Cloudflare.ZoneId}, nil
31
31
}
32
32
33
-
func (cf *Cloudflare) CreateDNSRecord(ctx context.Context, record Record) (string, error) {
34
-
result, err := cf.api.CreateDNSRecord(ctx, cloudflare.ZoneIdentifier(cf.zone), cloudflare.CreateDNSRecordParams{
33
+
func (cf *Cloudflare) CreateDNSRecord(ctx context.Context, record Record) error {
34
+
_, err := cf.api.CreateDNSRecord(ctx, cloudflare.ZoneIdentifier(cf.zone), cloudflare.CreateDNSRecordParams{
35
35
Type: record.Type,
36
36
Name: record.Name,
37
37
Content: record.Content,
···
39
39
Proxied: &record.Proxied,
40
40
})
41
41
if err != nil {
42
-
return "", fmt.Errorf("failed to create DNS record: %w", err)
42
+
return fmt.Errorf("failed to create DNS record: %w", err)
43
43
}
44
-
return result.ID, nil
44
+
return nil
45
45
}
46
46
47
47
func (cf *Cloudflare) DeleteDNSRecord(ctx context.Context, recordID string) error {
+8
-19
appview/models/pull.go
+8
-19
appview/models/pull.go
···
125
125
// content
126
126
RoundNumber int
127
127
Patch string
128
-
Combined string
129
128
Comments []PullComment
130
129
SourceRev string // include the rev that was used to create this submission: only for branch/fork PRs
131
130
···
151
150
Created time.Time
152
151
}
153
152
154
-
func (p *Pull) LastRoundNumber() int {
155
-
return len(p.Submissions) - 1
156
-
}
157
-
158
-
func (p *Pull) LatestSubmission() *PullSubmission {
159
-
return p.Submissions[p.LastRoundNumber()]
160
-
}
161
-
162
153
func (p *Pull) LatestPatch() string {
163
-
return p.LatestSubmission().Patch
154
+
latestSubmission := p.Submissions[p.LastRoundNumber()]
155
+
return latestSubmission.Patch
164
156
}
165
157
166
158
func (p *Pull) LatestSha() string {
167
-
return p.LatestSubmission().SourceRev
159
+
latestSubmission := p.Submissions[p.LastRoundNumber()]
160
+
return latestSubmission.SourceRev
168
161
}
169
162
170
163
func (p *Pull) PullAt() syntax.ATURI {
171
164
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", p.OwnerDid, tangled.RepoPullNSID, p.Rkey))
165
+
}
166
+
167
+
func (p *Pull) LastRoundNumber() int {
168
+
return len(p.Submissions) - 1
172
169
}
173
170
174
171
func (p *Pull) IsPatchBased() bool {
···
255
252
}
256
253
257
254
return participants
258
-
}
259
-
260
-
func (s PullSubmission) CombinedPatch() string {
261
-
if s.Combined == "" {
262
-
return s.Patch
263
-
}
264
-
265
-
return s.Combined
266
255
}
267
256
268
257
type Stack []*Pull
+46
-35
appview/pulls/pulls.go
+46
-35
appview/pulls/pulls.go
···
145
145
stack, _ := r.Context().Value("stack").(models.Stack)
146
146
abandonedPulls, _ := r.Context().Value("abandonedPulls").([]*models.Pull)
147
147
148
+
totalIdents := 1
149
+
for _, submission := range pull.Submissions {
150
+
totalIdents += len(submission.Comments)
151
+
}
152
+
153
+
identsToResolve := make([]string, totalIdents)
154
+
155
+
// populate idents
156
+
identsToResolve[0] = pull.OwnerDid
157
+
idx := 1
158
+
for _, submission := range pull.Submissions {
159
+
for _, comment := range submission.Comments {
160
+
identsToResolve[idx] = comment.OwnerDid
161
+
idx += 1
162
+
}
163
+
}
164
+
148
165
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
149
166
branchDeleteStatus := s.branchDeleteStatus(r, f, pull)
150
167
resubmitResult := pages.Unknown
···
442
459
return
443
460
}
444
461
445
-
patch := pull.Submissions[roundIdInt].CombinedPatch()
462
+
patch := pull.Submissions[roundIdInt].Patch
446
463
diff := patchutil.AsNiceDiff(patch, pull.TargetBranch)
447
464
448
465
s.pages.RepoPullPatchPage(w, pages.RepoPullPatchParams{
···
493
510
return
494
511
}
495
512
496
-
currentPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt].CombinedPatch())
513
+
currentPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt].Patch)
497
514
if err != nil {
498
515
log.Println("failed to interdiff; current patch malformed")
499
516
s.pages.Notice(w, fmt.Sprintf("interdiff-error-%d", roundIdInt), "Failed to calculate interdiff; current patch is invalid.")
500
517
return
501
518
}
502
519
503
-
previousPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt-1].CombinedPatch())
520
+
previousPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt-1].Patch)
504
521
if err != nil {
505
522
log.Println("failed to interdiff; previous patch malformed")
506
523
s.pages.Notice(w, fmt.Sprintf("interdiff-error-%d", roundIdInt), "Failed to calculate interdiff; previous patch is invalid.")
···
702
719
703
720
createdAt := time.Now().Format(time.RFC3339)
704
721
722
+
pullAt, err := db.GetPullAt(s.db, f.RepoAt(), pull.PullId)
723
+
if err != nil {
724
+
log.Println("failed to get pull at", err)
725
+
s.pages.Notice(w, "pull-comment", "Failed to create comment.")
726
+
return
727
+
}
728
+
705
729
client, err := s.oauth.AuthorizedClient(r)
706
730
if err != nil {
707
731
log.Println("failed to get authorized client", err)
···
714
738
Rkey: tid.TID(),
715
739
Record: &lexutil.LexiconTypeDecoder{
716
740
Val: &tangled.RepoPullComment{
717
-
Pull: pull.PullAt().String(),
741
+
Pull: string(pullAt),
718
742
Body: body,
719
743
CreatedAt: createdAt,
720
744
},
···
962
986
}
963
987
964
988
sourceRev := comparison.Rev2
965
-
patch := comparison.FormatPatchRaw
966
-
combined := comparison.CombinedPatchRaw
989
+
patch := comparison.Patch
967
990
968
991
if !patchutil.IsPatchValid(patch) {
969
992
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
···
978
1001
Sha: comparison.Rev2,
979
1002
}
980
1003
981
-
s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, combined, sourceRev, pullSource, recordPullSource, isStacked)
1004
+
s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, sourceRev, pullSource, recordPullSource, isStacked)
982
1005
}
983
1006
984
1007
func (s *Pulls) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, f *reporesolver.ResolvedRepo, user *oauth.User, title, body, targetBranch, patch string, isStacked bool) {
···
987
1010
return
988
1011
}
989
1012
990
-
s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, "", "", nil, nil, isStacked)
1013
+
s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, "", nil, nil, isStacked)
991
1014
}
992
1015
993
1016
func (s *Pulls) handleForkBasedPull(w http.ResponseWriter, r *http.Request, f *reporesolver.ResolvedRepo, user *oauth.User, forkRepo string, title, body, targetBranch, sourceBranch string, isStacked bool) {
···
1070
1093
}
1071
1094
1072
1095
sourceRev := comparison.Rev2
1073
-
patch := comparison.FormatPatchRaw
1074
-
combined := comparison.CombinedPatchRaw
1096
+
patch := comparison.Patch
1075
1097
1076
1098
if !patchutil.IsPatchValid(patch) {
1077
1099
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
···
1091
1113
Sha: sourceRev,
1092
1114
}
1093
1115
1094
-
s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, combined, sourceRev, pullSource, recordPullSource, isStacked)
1116
+
s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, sourceRev, pullSource, recordPullSource, isStacked)
1095
1117
}
1096
1118
1097
1119
func (s *Pulls) createPullRequest(
···
1101
1123
user *oauth.User,
1102
1124
title, body, targetBranch string,
1103
1125
patch string,
1104
-
combined string,
1105
1126
sourceRev string,
1106
1127
pullSource *models.PullSource,
1107
1128
recordPullSource *tangled.RepoPull_Source,
···
1161
1182
rkey := tid.TID()
1162
1183
initialSubmission := models.PullSubmission{
1163
1184
Patch: patch,
1164
-
Combined: combined,
1165
1185
SourceRev: sourceRev,
1166
1186
}
1167
1187
pull := &models.Pull{
···
1591
1611
1592
1612
patch := r.FormValue("patch")
1593
1613
1594
-
s.resubmitPullHelper(w, r, f, user, pull, patch, "", "")
1614
+
s.resubmitPullHelper(w, r, f, user, pull, patch, "")
1595
1615
}
1596
1616
1597
1617
func (s *Pulls) resubmitBranch(w http.ResponseWriter, r *http.Request) {
···
1652
1672
}
1653
1673
1654
1674
sourceRev := comparison.Rev2
1655
-
patch := comparison.FormatPatchRaw
1656
-
combined := comparison.CombinedPatchRaw
1675
+
patch := comparison.Patch
1657
1676
1658
-
s.resubmitPullHelper(w, r, f, user, pull, patch, combined, sourceRev)
1677
+
s.resubmitPullHelper(w, r, f, user, pull, patch, sourceRev)
1659
1678
}
1660
1679
1661
1680
func (s *Pulls) resubmitFork(w http.ResponseWriter, r *http.Request) {
···
1748
1767
comparison := forkComparison
1749
1768
1750
1769
sourceRev := comparison.Rev2
1751
-
patch := comparison.FormatPatchRaw
1752
-
combined := comparison.CombinedPatchRaw
1770
+
patch := comparison.Patch
1753
1771
1754
-
s.resubmitPullHelper(w, r, f, user, pull, patch, combined, sourceRev)
1772
+
s.resubmitPullHelper(w, r, f, user, pull, patch, sourceRev)
1755
1773
}
1756
1774
1757
1775
// validate a resubmission against a pull request
···
1778
1796
user *oauth.User,
1779
1797
pull *models.Pull,
1780
1798
patch string,
1781
-
combined string,
1782
1799
sourceRev string,
1783
1800
) {
1784
1801
if pull.IsStacked() {
···
1808
1825
}
1809
1826
defer tx.Rollback()
1810
1827
1811
-
pullAt := pull.PullAt()
1812
-
newRoundNumber := len(pull.Submissions)
1813
-
newPatch := patch
1814
-
newSourceRev := sourceRev
1815
-
combinedPatch := combined
1816
-
err = db.ResubmitPull(tx, pullAt, newRoundNumber, newPatch, combinedPatch, newSourceRev)
1828
+
pull.Submissions = append(pull.Submissions, &models.PullSubmission{
1829
+
Patch: patch,
1830
+
SourceRev: sourceRev,
1831
+
})
1832
+
err = db.ResubmitPull(tx, pull)
1817
1833
if err != nil {
1818
1834
log.Println("failed to create pull request", err)
1819
1835
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
···
2004
2020
continue
2005
2021
}
2006
2022
2007
-
// resubmit the new pull
2008
-
pullAt := op.PullAt()
2009
-
newRoundNumber := len(op.Submissions)
2010
-
newPatch := np.LatestPatch()
2011
-
combinedPatch := np.LatestSubmission().Combined
2012
-
newSourceRev := np.LatestSha()
2013
-
err := db.ResubmitPull(tx, pullAt, newRoundNumber, newPatch, combinedPatch, newSourceRev)
2023
+
// resubmit the old pull
2024
+
err := db.ResubmitPull(tx, np)
2025
+
2014
2026
if err != nil {
2015
2027
log.Println("failed to update pull", err, op.PullId)
2016
2028
s.pages.Notice(w, "pull-resubmit-error", "Failed to resubmit pull request. Try again later.")
···
2358
2370
initialSubmission := models.PullSubmission{
2359
2371
Patch: fp.Raw,
2360
2372
SourceRev: fp.SHA,
2361
-
Combined: fp.Raw,
2362
2373
}
2363
2374
pull := models.Pull{
2364
2375
Title: title,
+1
-6
appview/repo/repo.go
+1
-6
appview/repo/repo.go
···
2565
2565
return
2566
2566
}
2567
2567
2568
-
var diff types.NiceDiff
2569
-
if formatPatch.CombinedPatchRaw != "" {
2570
-
diff = patchutil.AsNiceDiff(formatPatch.CombinedPatchRaw, base)
2571
-
} else {
2572
-
diff = patchutil.AsNiceDiff(formatPatch.FormatPatchRaw, base)
2573
-
}
2568
+
diff := patchutil.AsNiceDiff(formatPatch.Patch, base)
2574
2569
2575
2570
repoinfo := f.RepoInfo(user)
2576
2571
-18
appview/signup/requests.go
-18
appview/signup/requests.go
···
102
102
103
103
return result.DID, nil
104
104
}
105
-
106
-
func (s *Signup) deleteAccountRequest(did string) error {
107
-
body := map[string]string{
108
-
"did": did,
109
-
}
110
-
111
-
resp, err := s.makePdsRequest("POST", "com.atproto.admin.deleteAccount", body, true)
112
-
if err != nil {
113
-
return err
114
-
}
115
-
defer resp.Body.Close()
116
-
117
-
if resp.StatusCode != http.StatusOK {
118
-
return s.handlePdsError(resp, "delete account")
119
-
}
120
-
121
-
return nil
122
-
}
+36
-93
appview/signup/signup.go
+36
-93
appview/signup/signup.go
···
2
2
3
3
import (
4
4
"bufio"
5
-
"context"
6
5
"encoding/json"
7
6
"errors"
8
7
"fmt"
···
217
216
return
218
217
}
219
218
219
+
did, err := s.createAccountRequest(username, password, email, code)
220
+
if err != nil {
221
+
s.l.Error("failed to create account", "error", err)
222
+
s.pages.Notice(w, "signup-error", err.Error())
223
+
return
224
+
}
225
+
220
226
if s.cf == nil {
221
227
s.l.Error("cloudflare client is nil", "error", "Cloudflare integration is not enabled in configuration")
222
228
s.pages.Notice(w, "signup-error", "Account signup is currently disabled. DNS record creation is not available. Please contact support.")
223
229
return
224
230
}
225
231
226
-
// Execute signup transactionally with rollback capability
227
-
err = s.executeSignupTransaction(r.Context(), username, password, email, code, w)
232
+
err = s.cf.CreateDNSRecord(r.Context(), dns.Record{
233
+
Type: "TXT",
234
+
Name: "_atproto." + username,
235
+
Content: fmt.Sprintf(`"did=%s"`, did),
236
+
TTL: 6400,
237
+
Proxied: false,
238
+
})
228
239
if err != nil {
229
-
// Error already logged and notice already sent
240
+
s.l.Error("failed to create DNS record", "error", err)
241
+
s.pages.Notice(w, "signup-error", "Failed to create DNS record for your handle. Please contact support.")
230
242
return
231
243
}
232
-
}
233
-
}
234
-
235
-
// executeSignupTransaction performs the signup process transactionally with rollback
236
-
func (s *Signup) executeSignupTransaction(ctx context.Context, username, password, email, code string, w http.ResponseWriter) error {
237
-
var recordID string
238
-
var did string
239
-
var emailAdded bool
240
-
241
-
success := false
242
-
defer func() {
243
-
if !success {
244
-
s.l.Info("rolling back signup transaction", "username", username, "did", did)
245
244
246
-
// Rollback DNS record
247
-
if recordID != "" {
248
-
if err := s.cf.DeleteDNSRecord(ctx, recordID); err != nil {
249
-
s.l.Error("failed to rollback DNS record", "error", err, "recordID", recordID)
250
-
} else {
251
-
s.l.Info("successfully rolled back DNS record", "recordID", recordID)
252
-
}
253
-
}
254
-
255
-
// Rollback PDS account
256
-
if did != "" {
257
-
if err := s.deleteAccountRequest(did); err != nil {
258
-
s.l.Error("failed to rollback PDS account", "error", err, "did", did)
259
-
} else {
260
-
s.l.Info("successfully rolled back PDS account", "did", did)
261
-
}
262
-
}
263
-
264
-
// Rollback email from database
265
-
if emailAdded {
266
-
if err := db.DeleteEmail(s.db, did, email); err != nil {
267
-
s.l.Error("failed to rollback email from database", "error", err, "email", email)
268
-
} else {
269
-
s.l.Info("successfully rolled back email from database", "email", email)
270
-
}
271
-
}
245
+
err = db.AddEmail(s.db, models.Email{
246
+
Did: did,
247
+
Address: email,
248
+
Verified: true,
249
+
Primary: true,
250
+
})
251
+
if err != nil {
252
+
s.l.Error("failed to add email", "error", err)
253
+
s.pages.Notice(w, "signup-error", "Failed to complete sign up. Try again later.")
254
+
return
272
255
}
273
-
}()
274
256
275
-
// step 1: create account in PDS
276
-
did, err := s.createAccountRequest(username, password, email, code)
277
-
if err != nil {
278
-
s.l.Error("failed to create account", "error", err)
279
-
s.pages.Notice(w, "signup-error", err.Error())
280
-
return err
281
-
}
282
-
283
-
// step 2: create DNS record with actual DID
284
-
recordID, err = s.cf.CreateDNSRecord(ctx, dns.Record{
285
-
Type: "TXT",
286
-
Name: "_atproto." + username,
287
-
Content: fmt.Sprintf(`"did=%s"`, did),
288
-
TTL: 6400,
289
-
Proxied: false,
290
-
})
291
-
if err != nil {
292
-
s.l.Error("failed to create DNS record", "error", err)
293
-
s.pages.Notice(w, "signup-error", "Failed to create DNS record for your handle. Please contact support.")
294
-
return err
295
-
}
257
+
s.pages.Notice(w, "signup-msg", fmt.Sprintf(`Account created successfully. You can now
258
+
<a class="underline text-black dark:text-white" href="/login">login</a>
259
+
with <code>%s.tngl.sh</code>.`, username))
296
260
297
-
// step 3: add email to database
298
-
err = db.AddEmail(s.db, models.Email{
299
-
Did: did,
300
-
Address: email,
301
-
Verified: true,
302
-
Primary: true,
303
-
})
304
-
if err != nil {
305
-
s.l.Error("failed to add email", "error", err)
306
-
s.pages.Notice(w, "signup-error", "Failed to complete sign up. Try again later.")
307
-
return err
261
+
go func() {
262
+
err := db.DeleteInflightSignup(s.db, email)
263
+
if err != nil {
264
+
s.l.Error("failed to delete inflight signup", "error", err)
265
+
}
266
+
}()
267
+
return
308
268
}
309
-
emailAdded = true
310
-
311
-
// if we get here, we've successfully created the account and added the email
312
-
success = true
313
-
314
-
s.pages.Notice(w, "signup-msg", fmt.Sprintf(`Account created successfully. You can now
315
-
<a class="underline text-black dark:text-white" href="/login">login</a>
316
-
with <code>%s.tngl.sh</code>.`, username))
317
-
318
-
// clean up inflight signup asynchronously
319
-
go func() {
320
-
if err := db.DeleteInflightSignup(s.db, email); err != nil {
321
-
s.l.Error("failed to delete inflight signup", "error", err)
322
-
}
323
-
}()
324
-
325
-
return nil
326
269
}
327
270
328
271
type turnstileResponse struct {
+4
-20
knotserver/xrpc/repo_compare.go
+4
-20
knotserver/xrpc/repo_compare.go
···
4
4
"fmt"
5
5
"net/http"
6
6
7
-
"github.com/bluekeyes/go-gitdiff/gitdiff"
8
7
"tangled.org/core/knotserver/git"
9
8
"tangled.org/core/types"
10
9
xrpcerr "tangled.org/core/xrpc/errors"
···
72
71
return
73
72
}
74
73
75
-
var combinedPatch []*gitdiff.File
76
-
var combinedPatchRaw string
77
-
// we need the combined patch
78
-
if len(formatPatch) >= 2 {
79
-
diffTree, err := gr.DiffTree(commit1, commit2)
80
-
if err != nil {
81
-
x.Logger.Error("error comparing revisions", "msg", err.Error())
82
-
} else {
83
-
combinedPatch = diffTree.Diff
84
-
combinedPatchRaw = diffTree.Patch
85
-
}
86
-
}
87
-
88
74
response := types.RepoFormatPatchResponse{
89
-
Rev1: commit1.Hash.String(),
90
-
Rev2: commit2.Hash.String(),
91
-
FormatPatch: formatPatch,
92
-
FormatPatchRaw: rawPatch,
93
-
CombinedPatch: combinedPatch,
94
-
CombinedPatchRaw: combinedPatchRaw,
75
+
Rev1: commit1.Hash.String(),
76
+
Rev2: commit2.Hash.String(),
77
+
FormatPatch: formatPatch,
78
+
Patch: rawPatch,
95
79
}
96
80
97
81
writeJson(w, response)
+5
-7
types/repo.go
+5
-7
types/repo.go
···
1
1
package types
2
2
3
3
import (
4
-
"github.com/bluekeyes/go-gitdiff/gitdiff"
5
4
"github.com/go-git/go-git/v5/plumbing/object"
6
5
)
7
6
···
34
33
}
35
34
36
35
type RepoFormatPatchResponse struct {
37
-
Rev1 string `json:"rev1,omitempty"`
38
-
Rev2 string `json:"rev2,omitempty"`
39
-
FormatPatch []FormatPatch `json:"format_patch,omitempty"`
40
-
FormatPatchRaw string `json:"patch,omitempty"`
41
-
CombinedPatch []*gitdiff.File `json:"combined_patch,omitempty"`
42
-
CombinedPatchRaw string `json:"combined_patch_raw,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"` // deprecated
40
+
Patch string `json:"patch,omitempty"`
43
41
}
44
42
45
43
type RepoTreeResponse struct {