···
637
-
resp, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
638
-
switch resp.StatusCode {
641
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
645
-
respBody, err := io.ReadAll(resp.Body)
637
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
647
-
log.Println("failed to compare across branches")
648
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
651
-
defer resp.Body.Close()
653
-
var diffTreeResponse types.RepoDiffTreeResponse
654
-
err = json.Unmarshal(respBody, &diffTreeResponse)
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())
···
// hiddenRef: hidden/feature-1/main (on repo-fork)
// targetBranch: main (on repo-1)
// 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)
log.Println("failed to compare across branches", err)
736
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
740
-
respBody, err := io.ReadAll(diffResp.Body)
742
-
log.Println("failed to read response body", err)
743
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
747
-
defer resp.Body.Close()
749
-
var diffTreeResponse types.RepoDiffTreeResponse
750
-
err = json.Unmarshal(respBody, &diffTreeResponse)
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())
···
1018
-
patch := r.FormValue("patch")
1019
-
var sourceRev string
1020
-
var recordPullSource *tangled.RepoPull_Source
1022
-
var ownerDid, repoName, knotName string
1023
-
var isSameRepo bool = pull.IsSameRepoBranch()
1024
-
sourceBranch := pull.PullSource.Branch
1025
-
targetBranch := pull.TargetBranch
1026
-
recordPullSource = &tangled.RepoPull_Source{
1027
-
Branch: sourceBranch,
984
+
if pull.IsPatchBased() {
985
+
s.resubmitPatch(w, r)
987
+
} else if pull.IsBranchBased() {
988
+
s.resubmitBranch(w, r)
990
+
} else if pull.IsForkBased() {
991
+
s.resubmitFork(w, r)
1030
-
isPushAllowed := f.RepoInfo(s, user).Roles.IsPushAllowed()
1031
-
if isSameRepo && isPushAllowed {
1032
-
ownerDid = f.OwnerDid()
1033
-
repoName = f.RepoName
1035
-
} else if !isSameRepo {
1036
-
sourceRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
1038
-
log.Println("failed to get source repo", err)
1039
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1042
-
ownerDid = sourceRepo.Did
1043
-
repoName = sourceRepo.Name
1044
-
knotName = sourceRepo.Knot
997
+
func (s *State) resubmitPatch(w http.ResponseWriter, r *http.Request) {
998
+
user := s.auth.GetUser(r)
1047
-
if sourceBranch != "" && knotName != "" {
1048
-
// extract patch by performing compare
1049
-
ksClient, err := NewUnsignedClient(knotName, s.config.Dev)
1051
-
log.Printf("failed to create client for %s: %s", knotName, err)
1052
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1000
+
pull, ok := r.Context().Value("pull").(*db.Pull)
1002
+
log.Println("failed to get pull")
1003
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
1057
-
secret, err := db.GetRegistrationKey(s.db, knotName)
1059
-
log.Printf("failed to get registration key for %s: %s", knotName, err)
1060
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1063
-
// update the hidden tracking branch to latest
1064
-
signedClient, err := NewSignedClient(knotName, secret, s.config.Dev)
1066
-
log.Printf("failed to create signed client for %s: %s", knotName, err)
1067
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1070
-
resp, err := signedClient.NewHiddenRef(ownerDid, repoName, sourceBranch, targetBranch)
1071
-
if err != nil || resp.StatusCode != http.StatusNoContent {
1072
-
log.Printf("failed to update tracking branch: %s", err)
1073
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1007
+
f, err := fullyResolvedRepo(r)
1009
+
log.Println("failed to get repo and knot", err)
1078
-
var compareResp *http.Response
1080
-
hiddenRef := url.QueryEscape(fmt.Sprintf("hidden/%s/%s", sourceBranch, targetBranch))
1081
-
compareResp, err = ksClient.Compare(ownerDid, repoName, hiddenRef, sourceBranch)
1083
-
compareResp, err = ksClient.Compare(ownerDid, repoName, targetBranch, sourceBranch)
1086
-
log.Printf("failed to compare branches: %s", err)
1087
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1090
-
defer compareResp.Body.Close()
1013
+
if user.Did != pull.OwnerDid {
1014
+
log.Println("unauthorized user")
1015
+
w.WriteHeader(http.StatusUnauthorized)
1092
-
switch compareResp.StatusCode {
1095
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
1019
+
patch := r.FormValue("patch")
1099
-
respBody, err := io.ReadAll(compareResp.Body)
1101
-
log.Println("failed to compare across branches")
1102
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1105
-
defer compareResp.Body.Close()
1021
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1022
+
s.pages.Notice(w, "resubmit-error", err.Error())
1107
-
var diffTreeResponse types.RepoDiffTreeResponse
1108
-
err = json.Unmarshal(respBody, &diffTreeResponse)
1110
-
log.Println("failed to unmarshal diff tree response", err)
1111
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
1025
+
tx, err := s.db.BeginTx(r.Context(), nil)
1027
+
log.Println("failed to start tx")
1028
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1031
+
defer tx.Rollback()
1115
-
sourceRev = diffTreeResponse.DiffTree.Rev2
1116
-
patch = diffTreeResponse.DiffTree.Patch
1033
+
err = db.ResubmitPull(tx, pull, patch, "")
1035
+
log.Println("failed to resubmit pull request", err)
1036
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull request. Try again later.")
1039
+
client, _ := s.auth.AuthorizedClient(r)
1120
-
s.pages.Notice(w, "resubmit-error", "Patch is empty.")
1041
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
1043
+
// failed to get record
1044
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
1124
-
if patch == pull.LatestPatch() {
1125
-
s.pages.Notice(w, "resubmit-error", "Patch is identical to previous submission.")
1048
+
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1049
+
Collection: tangled.RepoPullNSID,
1052
+
SwapRecord: ex.Cid,
1053
+
Record: &lexutil.LexiconTypeDecoder{
1054
+
Val: &tangled.RepoPull{
1055
+
Title: pull.Title,
1056
+
PullId: int64(pull.PullId),
1057
+
TargetRepo: string(f.RepoAt),
1058
+
TargetBranch: pull.TargetBranch,
1059
+
Patch: patch, // new patch
1064
+
log.Println("failed to update record", err)
1065
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
1129
-
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
1130
-
s.pages.Notice(w, "resubmit-error", "This branch has not changed since the last submission.")
1069
+
if err = tx.Commit(); err != nil {
1070
+
log.Println("failed to commit transaction", err)
1071
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
1134
-
if !isPatchValid(patch) {
1135
-
s.pages.Notice(w, "resubmit-error", "Invalid patch format. Please provide a valid diff.")
1075
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1139
-
tx, err := s.db.BeginTx(r.Context(), nil)
1141
-
log.Println("failed to start tx")
1142
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1145
-
defer tx.Rollback()
1079
+
func (s *State) resubmitBranch(w http.ResponseWriter, r *http.Request) {
1080
+
user := s.auth.GetUser(r)
1147
-
err = db.ResubmitPull(tx, pull, patch, sourceRev)
1149
-
log.Println("failed to create pull request", err)
1150
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1153
-
client, _ := s.auth.AuthorizedClient(r)
1082
+
pull, ok := r.Context().Value("pull").(*db.Pull)
1084
+
log.Println("failed to get pull")
1085
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
1155
-
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
1157
-
// failed to get record
1158
-
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
1089
+
f, err := fullyResolvedRepo(r)
1091
+
log.Println("failed to get repo and knot", err)
1162
-
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1163
-
Collection: tangled.RepoPullNSID,
1166
-
SwapRecord: ex.Cid,
1167
-
Record: &lexutil.LexiconTypeDecoder{
1168
-
Val: &tangled.RepoPull{
1169
-
Title: pull.Title,
1170
-
PullId: int64(pull.PullId),
1171
-
TargetRepo: string(f.RepoAt),
1172
-
TargetBranch: pull.TargetBranch,
1173
-
Patch: patch, // new patch
1174
-
Source: recordPullSource,
1095
+
if user.Did != pull.OwnerDid {
1096
+
log.Println("unauthorized user")
1097
+
w.WriteHeader(http.StatusUnauthorized)
1101
+
if !f.RepoInfo(s, user).Roles.IsPushAllowed() {
1102
+
log.Println("unauthorized user")
1103
+
w.WriteHeader(http.StatusUnauthorized)
1107
+
ksClient, err := NewUnsignedClient(f.Knot, s.config.Dev)
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.")
1114
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
1116
+
log.Printf("compare request failed: %s", err)
1117
+
s.pages.Notice(w, "resubmit-error", err.Error())
1121
+
sourceRev := diffTreeResponse.DiffTree.Rev2
1122
+
patch := diffTreeResponse.DiffTree.Patch
1124
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1125
+
s.pages.Notice(w, "resubmit-error", err.Error())
1128
+
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
1129
+
s.pages.Notice(w, "resubmit-error", "This branch has not changed since the last submission.")
1133
+
tx, err := s.db.BeginTx(r.Context(), nil)
1135
+
log.Println("failed to start tx")
1136
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1139
+
defer tx.Rollback()
1141
+
err = db.ResubmitPull(tx, pull, patch, sourceRev)
1143
+
log.Println("failed to create pull request", err)
1144
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1147
+
client, _ := s.auth.AuthorizedClient(r)
1149
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
1151
+
// failed to get record
1152
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
1156
+
recordPullSource := &tangled.RepoPull_Source{
1157
+
Branch: pull.PullSource.Branch,
1159
+
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1160
+
Collection: tangled.RepoPullNSID,
1163
+
SwapRecord: ex.Cid,
1164
+
Record: &lexutil.LexiconTypeDecoder{
1165
+
Val: &tangled.RepoPull{
1166
+
Title: pull.Title,
1167
+
PullId: int64(pull.PullId),
1168
+
TargetRepo: string(f.RepoAt),
1169
+
TargetBranch: pull.TargetBranch,
1170
+
Patch: patch, // new patch
1171
+
Source: recordPullSource,
1179
-
log.Println("failed to update record", err)
1180
-
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
1176
+
log.Println("failed to update record", err)
1177
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
1181
+
if err = tx.Commit(); err != nil {
1182
+
log.Println("failed to commit transaction", err)
1183
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
1187
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1191
+
func (s *State) resubmitFork(w http.ResponseWriter, r *http.Request) {
1192
+
user := s.auth.GetUser(r)
1184
-
if err = tx.Commit(); err != nil {
1185
-
log.Println("failed to commit transaction", err)
1186
-
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
1194
+
pull, ok := r.Context().Value("pull").(*db.Pull)
1196
+
log.Println("failed to get pull")
1197
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
1190
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1201
+
f, err := fullyResolvedRepo(r)
1203
+
log.Println("failed to get repo and knot", err)
1207
+
if user.Did != pull.OwnerDid {
1208
+
log.Println("unauthorized user")
1209
+
w.WriteHeader(http.StatusUnauthorized)
1213
+
forkRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
1215
+
log.Println("failed to get source repo", err)
1216
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1220
+
// extract patch by performing compare
1221
+
ksClient, err := NewUnsignedClient(forkRepo.Knot, s.config.Dev)
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.")
1228
+
secret, err := db.GetRegistrationKey(s.db, forkRepo.Knot)
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.")
1235
+
// update the hidden tracking branch to latest
1236
+
signedClient, err := NewSignedClient(forkRepo.Knot, secret, s.config.Dev)
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.")
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.")
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)
1253
+
log.Printf("failed to compare branches: %s", err)
1254
+
s.pages.Notice(w, "resubmit-error", err.Error())
1258
+
sourceRev := diffTreeResponse.DiffTree.Rev2
1259
+
patch := diffTreeResponse.DiffTree.Patch
1261
+
if err = validateResubmittedPatch(pull, patch); err != nil {
1262
+
s.pages.Notice(w, "resubmit-error", err.Error())
1265
+
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
1266
+
s.pages.Notice(w, "resubmit-error", "This branch has not changed since the last submission.")
1270
+
tx, err := s.db.BeginTx(r.Context(), nil)
1272
+
log.Println("failed to start tx")
1273
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1276
+
defer tx.Rollback()
1278
+
err = db.ResubmitPull(tx, pull, patch, sourceRev)
1280
+
log.Println("failed to create pull request", err)
1281
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1284
+
client, _ := s.auth.AuthorizedClient(r)
1286
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
1288
+
// failed to get record
1289
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
1293
+
repoAt := pull.PullSource.RepoAt.String()
1294
+
recordPullSource := &tangled.RepoPull_Source{
1295
+
Branch: pull.PullSource.Branch,
1298
+
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1299
+
Collection: tangled.RepoPullNSID,
1302
+
SwapRecord: ex.Cid,
1303
+
Record: &lexutil.LexiconTypeDecoder{
1304
+
Val: &tangled.RepoPull{
1305
+
Title: pull.Title,
1306
+
PullId: int64(pull.PullId),
1307
+
TargetRepo: string(f.RepoAt),
1308
+
TargetBranch: pull.TargetBranch,
1309
+
Patch: patch, // new patch
1310
+
Source: recordPullSource,
1315
+
log.Println("failed to update record", err)
1316
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
1320
+
if err = tx.Commit(); err != nil {
1321
+
log.Println("failed to commit transaction", err)
1322
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
1326
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1330
+
// validate a resubmission against a pull request
1331
+
func validateResubmittedPatch(pull *db.Pull, patch string) error {
1333
+
return fmt.Errorf("Patch is empty.")
1336
+
if patch == pull.LatestPatch() {
1337
+
return fmt.Errorf("Patch is identical to previous submission.")
1340
+
if !isPatchValid(patch) {
1341
+
return fmt.Errorf("Invalid patch format. Please provide a valid diff.")
func (s *State) MergePull(w http.ResponseWriter, r *http.Request) {