+43
-139
appview/state/pull.go
+43
-139
appview/state/pull.go
···
634
return
635
}
636
637
-
resp, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
638
-
switch resp.StatusCode {
639
-
case 404:
640
-
case 400:
641
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
642
-
return
643
-
}
644
-
645
-
respBody, err := io.ReadAll(resp.Body)
646
if err != nil {
647
-
log.Println("failed to compare across branches")
648
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
649
-
return
650
-
}
651
-
defer resp.Body.Close()
652
-
653
-
var diffTreeResponse types.RepoDiffTreeResponse
654
-
err = json.Unmarshal(respBody, &diffTreeResponse)
655
-
if err != nil {
656
-
log.Println("failed to unmarshal diff tree response", err)
657
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
658
return
659
}
660
···
730
// hiddenRef: hidden/feature-1/main (on repo-fork)
731
// targetBranch: main (on repo-1)
732
// sourceBranch: feature-1 (on repo-fork)
733
-
diffResp, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
734
if err != nil {
735
log.Println("failed to compare across branches", err)
736
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
737
-
return
738
-
}
739
-
740
-
respBody, err := io.ReadAll(diffResp.Body)
741
-
if err != nil {
742
-
log.Println("failed to read response body", err)
743
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
744
-
return
745
-
}
746
-
747
-
defer resp.Body.Close()
748
-
749
-
var diffTreeResponse types.RepoDiffTreeResponse
750
-
err = json.Unmarshal(respBody, &diffTreeResponse)
751
-
if err != nil {
752
-
log.Println("failed to unmarshal diff tree response", err)
753
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
754
return
755
}
756
···
1052
1053
patch := r.FormValue("patch")
1054
1055
-
if patch == "" {
1056
-
s.pages.Notice(w, "resubmit-error", "Patch is empty.")
1057
-
return
1058
-
}
1059
-
1060
-
if patch == pull.LatestPatch() {
1061
-
s.pages.Notice(w, "resubmit-error", "Patch is identical to previous submission.")
1062
-
return
1063
-
}
1064
-
1065
-
if !isPatchValid(patch) {
1066
-
s.pages.Notice(w, "resubmit-error", "Invalid patch format. Please provide a valid diff.")
1067
-
return
1068
}
1069
1070
tx, err := s.db.BeginTx(r.Context(), nil)
···
1127
pull, ok := r.Context().Value("pull").(*db.Pull)
1128
if !ok {
1129
log.Println("failed to get pull")
1130
-
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
1131
return
1132
}
1133
···
1152
ksClient, err := NewUnsignedClient(f.Knot, s.config.Dev)
1153
if err != nil {
1154
log.Printf("failed to create client for %s: %s", f.Knot, err)
1155
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1156
return
1157
}
1158
1159
-
compareResp, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
1160
if err != nil {
1161
-
log.Printf("failed to compare branches: %s", err)
1162
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1163
-
return
1164
-
}
1165
-
defer compareResp.Body.Close()
1166
-
1167
-
switch compareResp.StatusCode {
1168
-
case 404:
1169
-
case 400:
1170
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
1171
-
return
1172
-
}
1173
-
1174
-
respBody, err := io.ReadAll(compareResp.Body)
1175
-
if err != nil {
1176
-
log.Println("failed to compare across branches")
1177
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1178
-
return
1179
-
}
1180
-
defer compareResp.Body.Close()
1181
-
1182
-
var diffTreeResponse types.RepoDiffTreeResponse
1183
-
err = json.Unmarshal(respBody, &diffTreeResponse)
1184
-
if err != nil {
1185
-
log.Println("failed to unmarshal diff tree response", err)
1186
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1187
return
1188
}
1189
1190
sourceRev := diffTreeResponse.DiffTree.Rev2
1191
patch := diffTreeResponse.DiffTree.Patch
1192
1193
-
if patch == "" {
1194
-
s.pages.Notice(w, "resubmit-error", "Patch is empty.")
1195
-
return
1196
-
}
1197
-
1198
-
if patch == pull.LatestPatch() {
1199
-
s.pages.Notice(w, "resubmit-error", "Patch is identical to previous submission.")
1200
-
return
1201
-
}
1202
-
1203
-
if !isPatchValid(patch) {
1204
-
s.pages.Notice(w, "resubmit-error", "Invalid patch format. Please provide a valid diff.")
1205
-
return
1206
}
1207
1208
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
···
1274
pull, ok := r.Context().Value("pull").(*db.Pull)
1275
if !ok {
1276
log.Println("failed to get pull")
1277
-
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
1278
return
1279
}
1280
···
1293
forkRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
1294
if err != nil {
1295
log.Println("failed to get source repo", err)
1296
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1297
return
1298
}
1299
···
1301
ksClient, err := NewUnsignedClient(forkRepo.Knot, s.config.Dev)
1302
if err != nil {
1303
log.Printf("failed to create client for %s: %s", forkRepo.Knot, err)
1304
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1305
return
1306
}
1307
1308
secret, err := db.GetRegistrationKey(s.db, forkRepo.Knot)
1309
if err != nil {
1310
log.Printf("failed to get registration key for %s: %s", forkRepo.Knot, err)
1311
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1312
return
1313
}
1314
// update the hidden tracking branch to latest
1315
signedClient, err := NewSignedClient(forkRepo.Knot, secret, s.config.Dev)
1316
if err != nil {
1317
log.Printf("failed to create signed client for %s: %s", forkRepo.Knot, err)
1318
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1319
return
1320
}
1321
resp, err := signedClient.NewHiddenRef(forkRepo.Did, forkRepo.Name, pull.PullSource.Branch, pull.TargetBranch)
1322
if err != nil || resp.StatusCode != http.StatusNoContent {
1323
log.Printf("failed to update tracking branch: %s", err)
1324
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1325
return
1326
}
1327
1328
hiddenRef := url.QueryEscape(fmt.Sprintf("hidden/%s/%s", pull.PullSource.Branch, pull.TargetBranch))
1329
-
compareResp, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch)
1330
if err != nil {
1331
log.Printf("failed to compare branches: %s", err)
1332
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1333
-
return
1334
-
}
1335
-
defer compareResp.Body.Close()
1336
-
1337
-
switch compareResp.StatusCode {
1338
-
case 404:
1339
-
case 400:
1340
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
1341
-
return
1342
-
}
1343
-
1344
-
respBody, err := io.ReadAll(compareResp.Body)
1345
-
if err != nil {
1346
-
log.Println("failed to compare across branches")
1347
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1348
-
return
1349
-
}
1350
-
defer compareResp.Body.Close()
1351
-
1352
-
var diffTreeResponse types.RepoDiffTreeResponse
1353
-
err = json.Unmarshal(respBody, &diffTreeResponse)
1354
-
if err != nil {
1355
-
log.Println("failed to unmarshal diff tree response", err)
1356
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1357
return
1358
}
1359
1360
sourceRev := diffTreeResponse.DiffTree.Rev2
1361
patch := diffTreeResponse.DiffTree.Patch
1362
1363
-
if patch == "" {
1364
-
s.pages.Notice(w, "resubmit-error", "Patch is empty.")
1365
-
return
1366
-
}
1367
-
1368
-
if patch == pull.LatestPatch() {
1369
-
s.pages.Notice(w, "resubmit-error", "Patch is identical to previous submission.")
1370
-
return
1371
-
}
1372
-
1373
-
if !isPatchValid(patch) {
1374
-
s.pages.Notice(w, "resubmit-error", "Invalid patch format. Please provide a valid diff.")
1375
-
return
1376
}
1377
1378
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
···
1438
1439
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1440
return
1441
}
1442
1443
func (s *State) MergePull(w http.ResponseWriter, r *http.Request) {
···
634
return
635
}
636
637
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
638
if err != nil {
639
+
log.Println("failed to compare", err)
640
+
s.pages.Notice(w, "pull", err.Error())
641
return
642
}
643
···
713
// hiddenRef: hidden/feature-1/main (on repo-fork)
714
// targetBranch: main (on repo-1)
715
// sourceBranch: feature-1 (on repo-fork)
716
+
diffTreeResponse, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
717
if err != nil {
718
log.Println("failed to compare across branches", err)
719
+
s.pages.Notice(w, "pull", err.Error())
720
return
721
}
722
···
1018
1019
patch := r.FormValue("patch")
1020
1021
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1022
+
s.pages.Notice(w, "resubmit-error", err.Error())
1023
}
1024
1025
tx, err := s.db.BeginTx(r.Context(), nil)
···
1082
pull, ok := r.Context().Value("pull").(*db.Pull)
1083
if !ok {
1084
log.Println("failed to get pull")
1085
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
1086
return
1087
}
1088
···
1107
ksClient, err := NewUnsignedClient(f.Knot, s.config.Dev)
1108
if err != nil {
1109
log.Printf("failed to create client for %s: %s", f.Knot, err)
1110
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1111
return
1112
}
1113
1114
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
1115
if err != nil {
1116
+
log.Printf("compare request failed: %s", err)
1117
+
s.pages.Notice(w, "resubmit-error", err.Error())
1118
return
1119
}
1120
1121
sourceRev := diffTreeResponse.DiffTree.Rev2
1122
patch := diffTreeResponse.DiffTree.Patch
1123
1124
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1125
+
s.pages.Notice(w, "resubmit-error", err.Error())
1126
}
1127
1128
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
···
1194
pull, ok := r.Context().Value("pull").(*db.Pull)
1195
if !ok {
1196
log.Println("failed to get pull")
1197
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
1198
return
1199
}
1200
···
1213
forkRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
1214
if err != nil {
1215
log.Println("failed to get source repo", err)
1216
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1217
return
1218
}
1219
···
1221
ksClient, err := NewUnsignedClient(forkRepo.Knot, s.config.Dev)
1222
if err != nil {
1223
log.Printf("failed to create client for %s: %s", forkRepo.Knot, err)
1224
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1225
return
1226
}
1227
1228
secret, err := db.GetRegistrationKey(s.db, forkRepo.Knot)
1229
if err != nil {
1230
log.Printf("failed to get registration key for %s: %s", forkRepo.Knot, err)
1231
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1232
return
1233
}
1234
+
1235
// update the hidden tracking branch to latest
1236
signedClient, err := NewSignedClient(forkRepo.Knot, secret, s.config.Dev)
1237
if err != nil {
1238
log.Printf("failed to create signed client for %s: %s", forkRepo.Knot, err)
1239
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1240
return
1241
}
1242
+
1243
resp, err := signedClient.NewHiddenRef(forkRepo.Did, forkRepo.Name, pull.PullSource.Branch, pull.TargetBranch)
1244
if err != nil || resp.StatusCode != http.StatusNoContent {
1245
log.Printf("failed to update tracking branch: %s", err)
1246
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1247
return
1248
}
1249
1250
hiddenRef := url.QueryEscape(fmt.Sprintf("hidden/%s/%s", pull.PullSource.Branch, pull.TargetBranch))
1251
+
diffTreeResponse, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch)
1252
if err != nil {
1253
log.Printf("failed to compare branches: %s", err)
1254
+
s.pages.Notice(w, "resubmit-error", err.Error())
1255
return
1256
}
1257
1258
sourceRev := diffTreeResponse.DiffTree.Rev2
1259
patch := diffTreeResponse.DiffTree.Patch
1260
1261
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1262
+
s.pages.Notice(w, "resubmit-error", err.Error())
1263
}
1264
1265
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
···
1325
1326
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1327
return
1328
+
}
1329
+
1330
+
// validate a resubmission against a pull request
1331
+
func validateResubmittedPatch(pull *db.Pull, patch string) error {
1332
+
if patch == "" {
1333
+
return fmt.Errorf("Patch is empty.")
1334
+
}
1335
+
1336
+
if patch == pull.LatestPatch() {
1337
+
return fmt.Errorf("Patch is identical to previous submission.")
1338
+
}
1339
+
1340
+
if !isPatchValid(patch) {
1341
+
return fmt.Errorf("Invalid patch format. Please provide a valid diff.")
1342
+
}
1343
+
1344
+
return nil
1345
}
1346
1347
func (s *State) MergePull(w http.ResponseWriter, r *http.Request) {
+31
-3
appview/state/signer.go
+31
-3
appview/state/signer.go
···
7
"encoding/hex"
8
"encoding/json"
9
"fmt"
10
"net/http"
11
"net/url"
12
"time"
···
376
return &capabilities, nil
377
}
378
379
-
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*http.Response, error) {
380
const (
381
Method = "GET"
382
)
···
385
386
req, err := us.newRequest(Method, endpoint, nil)
387
if err != nil {
388
-
return nil, err
389
}
390
391
-
return us.client.Do(req)
392
}
···
7
"encoding/hex"
8
"encoding/json"
9
"fmt"
10
+
"io"
11
+
"log"
12
"net/http"
13
"net/url"
14
"time"
···
378
return &capabilities, nil
379
}
380
381
+
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoDiffTreeResponse, error) {
382
const (
383
Method = "GET"
384
)
···
387
388
req, err := us.newRequest(Method, endpoint, nil)
389
if err != nil {
390
+
return nil, fmt.Errorf("Failed to create request.")
391
}
392
393
+
compareResp, err := us.client.Do(req)
394
+
if err != nil {
395
+
return nil, fmt.Errorf("Failed to create request.")
396
+
}
397
+
defer compareResp.Body.Close()
398
+
399
+
switch compareResp.StatusCode {
400
+
case 404:
401
+
case 400:
402
+
return nil, fmt.Errorf("Branch comparisons not supported on this knot.")
403
+
}
404
+
405
+
respBody, err := io.ReadAll(compareResp.Body)
406
+
if err != nil {
407
+
log.Println("failed to compare across branches")
408
+
return nil, fmt.Errorf("Failed to compare branches.")
409
+
}
410
+
defer compareResp.Body.Close()
411
+
412
+
var diffTreeResponse types.RepoDiffTreeResponse
413
+
err = json.Unmarshal(respBody, &diffTreeResponse)
414
+
if err != nil {
415
+
log.Println("failed to unmarshal diff tree response", err)
416
+
return nil, fmt.Errorf("Failed to compare branches.")
417
+
}
418
+
419
+
return &diffTreeResponse, nil
420
}