+43
-139
appview/state/pull.go
+43
-139
appview/state/pull.go
···
634
634
return
635
635
}
636
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)
637
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
646
638
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.")
639
+
log.Println("failed to compare", err)
640
+
s.pages.Notice(w, "pull", err.Error())
658
641
return
659
642
}
660
643
···
730
713
// hiddenRef: hidden/feature-1/main (on repo-fork)
731
714
// targetBranch: main (on repo-1)
732
715
// sourceBranch: feature-1 (on repo-fork)
733
-
diffResp, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
716
+
diffTreeResponse, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
734
717
if err != nil {
735
718
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.")
719
+
s.pages.Notice(w, "pull", err.Error())
754
720
return
755
721
}
756
722
···
1052
1018
1053
1019
patch := r.FormValue("patch")
1054
1020
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
1021
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1022
+
s.pages.Notice(w, "resubmit-error", err.Error())
1068
1023
}
1069
1024
1070
1025
tx, err := s.db.BeginTx(r.Context(), nil)
···
1127
1082
pull, ok := r.Context().Value("pull").(*db.Pull)
1128
1083
if !ok {
1129
1084
log.Println("failed to get pull")
1130
-
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
1085
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
1131
1086
return
1132
1087
}
1133
1088
···
1152
1107
ksClient, err := NewUnsignedClient(f.Knot, s.config.Dev)
1153
1108
if err != nil {
1154
1109
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.")
1110
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1156
1111
return
1157
1112
}
1158
1113
1159
-
compareResp, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
1114
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
1160
1115
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.")
1116
+
log.Printf("compare request failed: %s", err)
1117
+
s.pages.Notice(w, "resubmit-error", err.Error())
1187
1118
return
1188
1119
}
1189
1120
1190
1121
sourceRev := diffTreeResponse.DiffTree.Rev2
1191
1122
patch := diffTreeResponse.DiffTree.Patch
1192
1123
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
1124
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1125
+
s.pages.Notice(w, "resubmit-error", err.Error())
1206
1126
}
1207
1127
1208
1128
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
···
1274
1194
pull, ok := r.Context().Value("pull").(*db.Pull)
1275
1195
if !ok {
1276
1196
log.Println("failed to get pull")
1277
-
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
1197
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
1278
1198
return
1279
1199
}
1280
1200
···
1293
1213
forkRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
1294
1214
if err != nil {
1295
1215
log.Println("failed to get source repo", err)
1296
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1216
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1297
1217
return
1298
1218
}
1299
1219
···
1301
1221
ksClient, err := NewUnsignedClient(forkRepo.Knot, s.config.Dev)
1302
1222
if err != nil {
1303
1223
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.")
1224
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1305
1225
return
1306
1226
}
1307
1227
1308
1228
secret, err := db.GetRegistrationKey(s.db, forkRepo.Knot)
1309
1229
if err != nil {
1310
1230
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.")
1231
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1312
1232
return
1313
1233
}
1234
+
1314
1235
// update the hidden tracking branch to latest
1315
1236
signedClient, err := NewSignedClient(forkRepo.Knot, secret, s.config.Dev)
1316
1237
if err != nil {
1317
1238
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.")
1239
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1319
1240
return
1320
1241
}
1242
+
1321
1243
resp, err := signedClient.NewHiddenRef(forkRepo.Did, forkRepo.Name, pull.PullSource.Branch, pull.TargetBranch)
1322
1244
if err != nil || resp.StatusCode != http.StatusNoContent {
1323
1245
log.Printf("failed to update tracking branch: %s", err)
1324
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1246
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1325
1247
return
1326
1248
}
1327
1249
1328
1250
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)
1251
+
diffTreeResponse, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch)
1330
1252
if err != nil {
1331
1253
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.")
1254
+
s.pages.Notice(w, "resubmit-error", err.Error())
1357
1255
return
1358
1256
}
1359
1257
1360
1258
sourceRev := diffTreeResponse.DiffTree.Rev2
1361
1259
patch := diffTreeResponse.DiffTree.Patch
1362
1260
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
1261
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1262
+
s.pages.Notice(w, "resubmit-error", err.Error())
1376
1263
}
1377
1264
1378
1265
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
···
1438
1325
1439
1326
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1440
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
1441
1345
}
1442
1346
1443
1347
func (s *State) MergePull(w http.ResponseWriter, r *http.Request) {
+31
-3
appview/state/signer.go
+31
-3
appview/state/signer.go
···
7
7
"encoding/hex"
8
8
"encoding/json"
9
9
"fmt"
10
+
"io"
11
+
"log"
10
12
"net/http"
11
13
"net/url"
12
14
"time"
···
376
378
return &capabilities, nil
377
379
}
378
380
379
-
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*http.Response, error) {
381
+
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoDiffTreeResponse, error) {
380
382
const (
381
383
Method = "GET"
382
384
)
···
385
387
386
388
req, err := us.newRequest(Method, endpoint, nil)
387
389
if err != nil {
388
-
return nil, err
390
+
return nil, fmt.Errorf("Failed to create request.")
389
391
}
390
392
391
-
return us.client.Do(req)
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
392
420
}