Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/pulls: rework pulls handlers to use xrpc calls

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.sh>

authored by

Anirudh Oppiliappan and committed by
oppiliappan
f89f104d f25a51e4

+233 -88
+233 -88
appview/pulls/pulls.go
··· 2 2 3 3 import ( 4 4 "database/sql" 5 + "encoding/json" 5 6 "errors" 6 7 "fmt" 7 8 "log" ··· 22 21 "tangled.sh/tangled.sh/core/appview/reporesolver" 23 22 "tangled.sh/tangled.sh/core/appview/xrpcclient" 24 23 "tangled.sh/tangled.sh/core/idresolver" 25 - "tangled.sh/tangled.sh/core/knotclient" 26 24 "tangled.sh/tangled.sh/core/patchutil" 27 25 "tangled.sh/tangled.sh/core/tid" 28 26 "tangled.sh/tangled.sh/core/types" ··· 99 99 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 100 100 resubmitResult := pages.Unknown 101 101 if user.Did == pull.OwnerDid { 102 - resubmitResult = s.resubmitCheck(f, pull, stack) 102 + resubmitResult = s.resubmitCheck(r, f, pull, stack) 103 103 } 104 104 105 105 s.pages.PullActionsFragment(w, pages.PullActionsParams{ ··· 154 154 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 155 155 resubmitResult := pages.Unknown 156 156 if user != nil && user.Did == pull.OwnerDid { 157 - resubmitResult = s.resubmitCheck(f, pull, stack) 157 + resubmitResult = s.resubmitCheck(r, f, pull, stack) 158 158 } 159 159 160 160 repoInfo := f.RepoInfo(user) ··· 282 282 return result 283 283 } 284 284 285 - func (s *Pulls) resubmitCheck(f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) pages.ResubmitResult { 285 + func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) pages.ResubmitResult { 286 286 if pull.State == db.PullMerged || pull.State == db.PullDeleted || pull.PullSource == nil { 287 287 return pages.Unknown 288 288 } ··· 307 307 repoName = f.Name 308 308 } 309 309 310 - us, err := knotclient.NewUnsignedClient(knot, s.config.Core.Dev) 311 - if err != nil { 312 - log.Printf("failed to setup client for %s; ignoring: %v", knot, err) 313 - return pages.Unknown 310 + scheme := "http" 311 + if !s.config.Core.Dev { 312 + scheme = "https" 313 + } 314 + host := fmt.Sprintf("%s://%s", scheme, knot) 315 + xrpcc := &indigoxrpc.Client{ 316 + Host: host, 314 317 } 315 318 316 - result, err := us.Branch(ownerDid, repoName, pull.PullSource.Branch) 319 + repo := fmt.Sprintf("%s/%s", ownerDid, repoName) 320 + branchResp, err := tangled.RepoBranch(r.Context(), xrpcc, pull.PullSource.Branch, repo) 317 321 if err != nil { 322 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 323 + log.Println("failed to call XRPC repo.branches", xrpcerr) 324 + return pages.Unknown 325 + } 318 326 log.Println("failed to reach knotserver", err) 319 327 return pages.Unknown 320 328 } 329 + 330 + targetBranch := branchResp 321 331 322 332 latestSourceRev := pull.Submissions[pull.LastRoundNumber()].SourceRev 323 333 ··· 336 326 latestSourceRev = top.Submissions[top.LastRoundNumber()].SourceRev 337 327 } 338 328 339 - if latestSourceRev != result.Branch.Hash { 329 + if latestSourceRev != targetBranch.Hash { 340 330 return pages.ShouldResubmit 341 331 } 342 332 ··· 688 678 689 679 switch r.Method { 690 680 case http.MethodGet: 691 - us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 681 + scheme := "http" 682 + if !s.config.Core.Dev { 683 + scheme = "https" 684 + } 685 + host := fmt.Sprintf("%s://%s", scheme, f.Knot) 686 + xrpcc := &indigoxrpc.Client{ 687 + Host: host, 688 + } 689 + 690 + repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 691 + xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 692 692 if err != nil { 693 - log.Printf("failed to create unsigned client for %s", f.Knot) 694 - s.pages.Error503(w) 693 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 694 + log.Println("failed to call XRPC repo.branches", xrpcerr) 695 + s.pages.Error503(w) 696 + return 697 + } 698 + log.Println("failed to fetch branches", err) 695 699 return 696 700 } 697 701 698 - result, err := us.Branches(f.OwnerDid(), f.Name) 699 - if err != nil { 700 - log.Println("failed to fetch branches", err) 702 + var result types.RepoBranchesResponse 703 + if err := json.Unmarshal(xrpcBytes, &result); err != nil { 704 + log.Println("failed to decode XRPC response", err) 705 + s.pages.Error503(w) 701 706 return 702 707 } 703 708 ··· 777 752 return 778 753 } 779 754 780 - us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 781 - if err != nil { 782 - log.Printf("failed to create unsigned client to %s: %v", f.Knot, err) 783 - s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.") 784 - return 755 + // us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 756 + // if err != nil { 757 + // log.Printf("failed to create unsigned client to %s: %v", f.Knot, err) 758 + // s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.") 759 + // return 760 + // } 761 + 762 + // TODO: make capabilities an xrpc call 763 + caps := struct { 764 + PullRequests struct { 765 + FormatPatch bool 766 + BranchSubmissions bool 767 + ForkSubmissions bool 768 + PatchSubmissions bool 769 + } 770 + }{ 771 + PullRequests: struct { 772 + FormatPatch bool 773 + BranchSubmissions bool 774 + ForkSubmissions bool 775 + PatchSubmissions bool 776 + }{ 777 + FormatPatch: true, 778 + BranchSubmissions: true, 779 + ForkSubmissions: true, 780 + PatchSubmissions: true, 781 + }, 785 782 } 786 783 787 - caps, err := us.Capabilities() 788 - if err != nil { 789 - log.Println("error fetching knot caps", f.Knot, err) 790 - s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.") 791 - return 792 - } 784 + // caps, err := us.Capabilities() 785 + // if err != nil { 786 + // log.Println("error fetching knot caps", f.Knot, err) 787 + // s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.") 788 + // return 789 + // } 793 790 794 791 if !caps.PullRequests.FormatPatch { 795 792 s.pages.Notice(w, "pull", "This knot doesn't support format-patch. Unfortunately, there is no fallback for now.") ··· 853 806 sourceBranch string, 854 807 isStacked bool, 855 808 ) { 856 - // Generate a patch using /compare 857 - ksClient, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 809 + scheme := "http" 810 + if !s.config.Core.Dev { 811 + scheme = "https" 812 + } 813 + host := fmt.Sprintf("%s://%s", scheme, f.Knot) 814 + xrpcc := &indigoxrpc.Client{ 815 + Host: host, 816 + } 817 + 818 + repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 819 + xrpcBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, targetBranch, sourceBranch) 858 820 if err != nil { 859 - log.Printf("failed to create signed client for %s: %s", f.Knot, err) 860 - s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 821 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 822 + log.Println("failed to call XRPC repo.compare", xrpcerr) 823 + s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 824 + return 825 + } 826 + log.Println("failed to compare", err) 827 + s.pages.Notice(w, "pull", err.Error()) 861 828 return 862 829 } 863 830 864 - comparison, err := ksClient.Compare(f.OwnerDid(), f.Name, targetBranch, sourceBranch) 865 - if err != nil { 866 - log.Println("failed to compare", err) 867 - s.pages.Notice(w, "pull", err.Error()) 831 + var comparison types.RepoFormatPatchResponse 832 + if err := json.Unmarshal(xrpcBytes, &comparison); err != nil { 833 + log.Println("failed to decode XRPC compare response", err) 834 + s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 868 835 return 869 836 } 870 837 ··· 930 869 oauth.WithLxm(tangled.RepoHiddenRefNSID), 931 870 oauth.WithDev(s.config.Core.Dev), 932 871 ) 933 - if err != nil { 934 - log.Printf("failed to connect to knot server: %v", err) 935 - s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 936 - return 937 - } 938 - 939 - us, err := knotclient.NewUnsignedClient(fork.Knot, s.config.Core.Dev) 940 - if err != nil { 941 - log.Println("failed to create unsigned client:", err) 942 - s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 943 - return 944 - } 945 872 946 873 resp, err := tangled.RepoHiddenRef( 947 874 r.Context(), ··· 960 911 // hiddenRef: hidden/feature-1/main (on repo-fork) 961 912 // targetBranch: main (on repo-1) 962 913 // sourceBranch: feature-1 (on repo-fork) 963 - comparison, err := us.Compare(fork.Did, fork.Name, hiddenRef, sourceBranch) 914 + forkScheme := "http" 915 + if !s.config.Core.Dev { 916 + forkScheme = "https" 917 + } 918 + forkHost := fmt.Sprintf("%s://%s", forkScheme, fork.Knot) 919 + forkXrpcc := &indigoxrpc.Client{ 920 + Host: forkHost, 921 + } 922 + 923 + forkRepoId := fmt.Sprintf("%s/%s", fork.Did, fork.Name) 924 + forkXrpcBytes, err := tangled.RepoCompare(r.Context(), forkXrpcc, forkRepoId, hiddenRef, sourceBranch) 964 925 if err != nil { 926 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 927 + log.Println("failed to call XRPC repo.compare for fork", xrpcerr) 928 + s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 929 + return 930 + } 965 931 log.Println("failed to compare across branches", err) 966 932 s.pages.Notice(w, "pull", err.Error()) 933 + return 934 + } 935 + 936 + var comparison types.RepoFormatPatchResponse 937 + if err := json.Unmarshal(forkXrpcBytes, &comparison); err != nil { 938 + log.Println("failed to decode XRPC compare response for fork", err) 939 + s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") 967 940 return 968 941 } 969 942 ··· 1282 1211 return 1283 1212 } 1284 1213 1285 - us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 1214 + scheme := "http" 1215 + if !s.config.Core.Dev { 1216 + scheme = "https" 1217 + } 1218 + host := fmt.Sprintf("%s://%s", scheme, f.Knot) 1219 + xrpcc := &indigoxrpc.Client{ 1220 + Host: host, 1221 + } 1222 + 1223 + repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 1224 + xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 1286 1225 if err != nil { 1287 - log.Printf("failed to create unsigned client for %s", f.Knot) 1288 - s.pages.Error503(w) 1226 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 1227 + log.Println("failed to call XRPC repo.branches", xrpcerr) 1228 + s.pages.Error503(w) 1229 + return 1230 + } 1231 + log.Println("failed to fetch branches", err) 1289 1232 return 1290 1233 } 1291 1234 1292 - result, err := us.Branches(f.OwnerDid(), f.Name) 1293 - if err != nil { 1294 - log.Println("failed to reach knotserver", err) 1235 + var result types.RepoBranchesResponse 1236 + if err := json.Unmarshal(xrpcBytes, &result); err != nil { 1237 + log.Println("failed to decode XRPC response", err) 1238 + s.pages.Error503(w) 1295 1239 return 1296 1240 } 1297 1241 ··· 1370 1284 return 1371 1285 } 1372 1286 1373 - sourceBranchesClient, err := knotclient.NewUnsignedClient(repo.Knot, s.config.Core.Dev) 1287 + sourceScheme := "http" 1288 + if !s.config.Core.Dev { 1289 + sourceScheme = "https" 1290 + } 1291 + sourceHost := fmt.Sprintf("%s://%s", sourceScheme, repo.Knot) 1292 + sourceXrpcc := &indigoxrpc.Client{ 1293 + Host: sourceHost, 1294 + } 1295 + 1296 + sourceRepo := fmt.Sprintf("%s/%s", forkOwnerDid, repo.Name) 1297 + sourceXrpcBytes, err := tangled.RepoBranches(r.Context(), sourceXrpcc, "", 0, sourceRepo) 1374 1298 if err != nil { 1375 - log.Printf("failed to create unsigned client for %s", repo.Knot) 1299 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 1300 + log.Println("failed to call XRPC repo.branches for source", xrpcerr) 1301 + s.pages.Error503(w) 1302 + return 1303 + } 1304 + log.Println("failed to fetch source branches", err) 1305 + return 1306 + } 1307 + 1308 + // Decode source branches 1309 + var sourceBranches types.RepoBranchesResponse 1310 + if err := json.Unmarshal(sourceXrpcBytes, &sourceBranches); err != nil { 1311 + log.Println("failed to decode source branches XRPC response", err) 1376 1312 s.pages.Error503(w) 1377 1313 return 1378 1314 } 1379 1315 1380 - sourceResult, err := sourceBranchesClient.Branches(forkOwnerDid, repo.Name) 1316 + targetScheme := "http" 1317 + if !s.config.Core.Dev { 1318 + targetScheme = "https" 1319 + } 1320 + targetHost := fmt.Sprintf("%s://%s", targetScheme, f.Knot) 1321 + targetXrpcc := &indigoxrpc.Client{ 1322 + Host: targetHost, 1323 + } 1324 + 1325 + targetRepo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 1326 + targetXrpcBytes, err := tangled.RepoBranches(r.Context(), targetXrpcc, "", 0, targetRepo) 1381 1327 if err != nil { 1382 - log.Println("failed to reach knotserver for source branches", err) 1328 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 1329 + log.Println("failed to call XRPC repo.branches for target", xrpcerr) 1330 + s.pages.Error503(w) 1331 + return 1332 + } 1333 + log.Println("failed to fetch target branches", err) 1383 1334 return 1384 1335 } 1385 1336 1386 - targetBranchesClient, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 1387 - if err != nil { 1388 - log.Printf("failed to create unsigned client for target knot %s", f.Knot) 1337 + // Decode target branches 1338 + var targetBranches types.RepoBranchesResponse 1339 + if err := json.Unmarshal(targetXrpcBytes, &targetBranches); err != nil { 1340 + log.Println("failed to decode target branches XRPC response", err) 1389 1341 s.pages.Error503(w) 1390 1342 return 1391 1343 } 1392 1344 1393 - targetResult, err := targetBranchesClient.Branches(f.OwnerDid(), f.Name) 1394 - if err != nil { 1395 - log.Println("failed to reach knotserver for target branches", err) 1396 - return 1397 - } 1398 - 1399 - sourceBranches := sourceResult.Branches 1400 - sort.Slice(sourceBranches, func(i int, j int) bool { 1401 - return sourceBranches[i].Commit.Committer.When.After(sourceBranches[j].Commit.Committer.When) 1345 + sort.Slice(sourceBranches.Branches, func(i int, j int) bool { 1346 + return sourceBranches.Branches[i].Commit.Committer.When.After(sourceBranches.Branches[j].Commit.Committer.When) 1402 1347 }) 1403 1348 1404 1349 s.pages.PullCompareForkBranchesFragment(w, pages.PullCompareForkBranchesParams{ 1405 1350 RepoInfo: f.RepoInfo(user), 1406 - SourceBranches: sourceBranches, 1407 - TargetBranches: targetResult.Branches, 1351 + SourceBranches: sourceBranches.Branches, 1352 + TargetBranches: targetBranches.Branches, 1408 1353 }) 1409 1354 } 1410 1355 ··· 1530 1413 return 1531 1414 } 1532 1415 1533 - ksClient, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 1416 + scheme := "http" 1417 + if !s.config.Core.Dev { 1418 + scheme = "https" 1419 + } 1420 + host := fmt.Sprintf("%s://%s", scheme, f.Knot) 1421 + xrpcc := &indigoxrpc.Client{ 1422 + Host: host, 1423 + } 1424 + 1425 + repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 1426 + xrpcBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, pull.TargetBranch, pull.PullSource.Branch) 1534 1427 if err != nil { 1535 - log.Printf("failed to create client for %s: %s", f.Knot, err) 1536 - s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 1428 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 1429 + log.Println("failed to call XRPC repo.compare", xrpcerr) 1430 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 1431 + return 1432 + } 1433 + log.Printf("compare request failed: %s", err) 1434 + s.pages.Notice(w, "resubmit-error", err.Error()) 1537 1435 return 1538 1436 } 1539 1437 1540 - comparison, err := ksClient.Compare(f.OwnerDid(), f.Name, pull.TargetBranch, pull.PullSource.Branch) 1541 - if err != nil { 1542 - log.Printf("compare request failed: %s", err) 1543 - s.pages.Notice(w, "resubmit-error", err.Error()) 1438 + var comparison types.RepoFormatPatchResponse 1439 + if err := json.Unmarshal(xrpcBytes, &comparison); err != nil { 1440 + log.Println("failed to decode XRPC compare response", err) 1441 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 1544 1442 return 1545 1443 } 1546 1444 ··· 1595 1463 } 1596 1464 1597 1465 // extract patch by performing compare 1598 - ksClient, err := knotclient.NewUnsignedClient(forkRepo.Knot, s.config.Core.Dev) 1466 + forkScheme := "http" 1467 + if !s.config.Core.Dev { 1468 + forkScheme = "https" 1469 + } 1470 + forkHost := fmt.Sprintf("%s://%s", forkScheme, forkRepo.Knot) 1471 + forkRepoId := fmt.Sprintf("%s/%s", forkRepo.Did, forkRepo.Name) 1472 + forkXrpcBytes, err := tangled.RepoCompare(r.Context(), &indigoxrpc.Client{Host: forkHost}, forkRepoId, pull.TargetBranch, pull.PullSource.Branch) 1599 1473 if err != nil { 1600 - log.Printf("failed to create client for %s: %s", forkRepo.Knot, err) 1474 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 1475 + log.Println("failed to call XRPC repo.compare for fork", xrpcerr) 1476 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 1477 + return 1478 + } 1479 + log.Printf("failed to compare branches: %s", err) 1480 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 1481 + return 1482 + } 1483 + 1484 + var forkComparison types.RepoFormatPatchResponse 1485 + if err := json.Unmarshal(forkXrpcBytes, &forkComparison); err != nil { 1486 + log.Println("failed to decode XRPC compare response for fork", err) 1601 1487 s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 1602 1488 return 1603 1489 } ··· 1651 1501 return 1652 1502 } 1653 1503 1654 - hiddenRef := fmt.Sprintf("hidden/%s/%s", pull.PullSource.Branch, pull.TargetBranch) 1655 - comparison, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch) 1656 - if err != nil { 1657 - log.Printf("failed to compare branches: %s", err) 1658 - s.pages.Notice(w, "resubmit-error", err.Error()) 1659 - return 1660 - } 1504 + // Use the fork comparison we already made 1505 + comparison := forkComparison 1661 1506 1662 1507 sourceRev := comparison.Rev2 1663 1508 patch := comparison.Patch