Monorepo for Tangled tangled.org

appview: add support for format-patch

authored by anirudh.fi and committed by oppi.li f0f962e3 77809623

Changed files
+56 -49
appview
types
+15
appview/db/pulls.go
··· 10 10 11 11 "github.com/bluekeyes/go-gitdiff/gitdiff" 12 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 + "tangled.sh/tangled.sh/core/patchutil" 13 14 "tangled.sh/tangled.sh/core/types" 14 15 ) 15 16 ··· 188 189 nd.Stat.FilesChanged = len(diffs) 189 190 190 191 return nd 192 + } 193 + 194 + func (s PullSubmission) IsFormatPatch() bool { 195 + return patchutil.IsFormatPatch(s.Patch) 196 + } 197 + 198 + func (s PullSubmission) AsFormatPatch() []patchutil.FormatPatch { 199 + patches, err := patchutil.ExtractPatches(s.Patch) 200 + if err != nil { 201 + log.Println("error extracting patches from submission:", err) 202 + return []patchutil.FormatPatch{} 203 + } 204 + 205 + return patches 191 206 } 192 207 193 208 func NewPull(tx *sql.Tx, pull *Pull) error {
+29 -41
appview/state/pull.go
··· 10 10 "net/http" 11 11 "net/url" 12 12 "strconv" 13 - "strings" 14 13 "time" 15 14 16 15 "github.com/go-chi/chi/v5" ··· 18 17 "tangled.sh/tangled.sh/core/appview/auth" 19 18 "tangled.sh/tangled.sh/core/appview/db" 20 19 "tangled.sh/tangled.sh/core/appview/pages" 20 + "tangled.sh/tangled.sh/core/patchutil" 21 21 "tangled.sh/tangled.sh/core/types" 22 22 23 23 comatproto "github.com/bluesky-social/indigo/api/atproto" ··· 254 254 255 255 latestSubmission := pull.Submissions[pull.LastRoundNumber()] 256 256 if latestSubmission.SourceRev != result.Branch.Hash { 257 + fmt.Println(latestSubmission.SourceRev, result.Branch.Hash) 257 258 return pages.ShouldResubmit 258 259 } 259 260 ··· 635 636 return 636 637 } 637 638 638 - diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch) 639 + comparison, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch) 639 640 if err != nil { 640 641 log.Println("failed to compare", err) 641 642 s.pages.Notice(w, "pull", err.Error()) 642 643 return 643 644 } 644 645 645 - sourceRev := diffTreeResponse.DiffTree.Rev2 646 - patch := diffTreeResponse.DiffTree.Patch 646 + sourceRev := comparison.Rev2 647 + patch := comparison.Patch 647 648 648 - if !isPatchValid(patch) { 649 + if !patchutil.IsPatchValid(patch) { 649 650 s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.") 650 651 return 651 652 } ··· 654 655 } 655 656 656 657 func (s *State) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *auth.User, title, body, targetBranch, patch string) { 657 - if !isPatchValid(patch) { 658 + if !patchutil.IsPatchValid(patch) { 658 659 s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.") 659 660 return 660 661 } ··· 714 715 // hiddenRef: hidden/feature-1/main (on repo-fork) 715 716 // targetBranch: main (on repo-1) 716 717 // sourceBranch: feature-1 (on repo-fork) 717 - diffTreeResponse, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch) 718 + comparison, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch) 718 719 if err != nil { 719 720 log.Println("failed to compare across branches", err) 720 721 s.pages.Notice(w, "pull", err.Error()) 721 722 return 722 723 } 723 724 724 - sourceRev := diffTreeResponse.DiffTree.Rev2 725 - patch := diffTreeResponse.DiffTree.Patch 725 + sourceRev := comparison.Rev2 726 + patch := comparison.Patch 726 727 727 - if !isPatchValid(patch) { 728 + if patchutil.IsPatchValid(patch) { 728 729 s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.") 729 730 return 730 731 } ··· 742 743 }, &tangled.RepoPull_Source{Branch: sourceBranch, Repo: &fork.AtUri}) 743 744 } 744 745 745 - func (s *State) createPullRequest(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *auth.User, title, body, targetBranch, patch, sourceRev string, pullSource *db.PullSource, recordPullSource *tangled.RepoPull_Source) { 746 + func (s *State) createPullRequest( 747 + w http.ResponseWriter, 748 + r *http.Request, 749 + f *FullyResolvedRepo, 750 + user *auth.User, 751 + title, body, targetBranch string, 752 + patch string, 753 + sourceRev string, 754 + pullSource *db.PullSource, 755 + recordPullSource *tangled.RepoPull_Source, 756 + ) { 746 757 tx, err := s.db.BeginTx(r.Context(), nil) 747 758 if err != nil { 748 759 log.Println("failed to start tx") ··· 1112 1123 return 1113 1124 } 1114 1125 1115 - diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch) 1126 + comparison, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch) 1116 1127 if err != nil { 1117 1128 log.Printf("compare request failed: %s", err) 1118 1129 s.pages.Notice(w, "resubmit-error", err.Error()) 1119 1130 return 1120 1131 } 1121 1132 1122 - sourceRev := diffTreeResponse.DiffTree.Rev2 1123 - patch := diffTreeResponse.DiffTree.Patch 1133 + sourceRev := comparison.Rev2 1134 + patch := comparison.Patch 1124 1135 1125 1136 if err = validateResubmittedPatch(pull, patch); err != nil { 1126 1137 s.pages.Notice(w, "resubmit-error", err.Error()) ··· 1249 1260 } 1250 1261 1251 1262 hiddenRef := url.QueryEscape(fmt.Sprintf("hidden/%s/%s", pull.PullSource.Branch, pull.TargetBranch)) 1252 - diffTreeResponse, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch) 1263 + comparison, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch) 1253 1264 if err != nil { 1254 1265 log.Printf("failed to compare branches: %s", err) 1255 1266 s.pages.Notice(w, "resubmit-error", err.Error()) 1256 1267 return 1257 1268 } 1258 1269 1259 - sourceRev := diffTreeResponse.DiffTree.Rev2 1260 - patch := diffTreeResponse.DiffTree.Patch 1270 + sourceRev := comparison.Rev2 1271 + patch := comparison.Patch 1261 1272 1262 1273 if err = validateResubmittedPatch(pull, patch); err != nil { 1263 1274 s.pages.Notice(w, "resubmit-error", err.Error()) ··· 1338 1349 return fmt.Errorf("Patch is identical to previous submission.") 1339 1350 } 1340 1351 1341 - if !isPatchValid(patch) { 1352 + if patchutil.IsPatchValid(patch) { 1342 1353 return fmt.Errorf("Invalid patch format. Please provide a valid diff.") 1343 1354 } 1344 1355 ··· 1516 1527 s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId)) 1517 1528 return 1518 1529 } 1519 - 1520 - // Very basic validation to check if it looks like a diff/patch 1521 - // A valid patch usually starts with diff or --- lines 1522 - func isPatchValid(patch string) bool { 1523 - // Basic validation to check if it looks like a diff/patch 1524 - // A valid patch usually starts with diff or --- lines 1525 - if len(patch) == 0 { 1526 - return false 1527 - } 1528 - 1529 - lines := strings.Split(patch, "\n") 1530 - if len(lines) < 2 { 1531 - return false 1532 - } 1533 - 1534 - // Check for common patch format markers 1535 - firstLine := strings.TrimSpace(lines[0]) 1536 - return strings.HasPrefix(firstLine, "diff ") || 1537 - strings.HasPrefix(firstLine, "--- ") || 1538 - strings.HasPrefix(firstLine, "Index: ") || 1539 - strings.HasPrefix(firstLine, "+++ ") || 1540 - strings.HasPrefix(firstLine, "@@ ") 1541 - }
+6 -6
appview/state/signer.go
··· 378 378 return &capabilities, nil 379 379 } 380 380 381 - func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoDiffTreeResponse, error) { 381 + func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoFormatPatchResponse, error) { 382 382 const ( 383 383 Method = "GET" 384 384 ) ··· 409 409 } 410 410 defer compareResp.Body.Close() 411 411 412 - var diffTreeResponse types.RepoDiffTreeResponse 413 - err = json.Unmarshal(respBody, &diffTreeResponse) 412 + var formatPatchResponse types.RepoFormatPatchResponse 413 + err = json.Unmarshal(respBody, &formatPatchResponse) 414 414 if err != nil { 415 - log.Println("failed to unmarshal diff tree response", err) 416 - return nil, fmt.Errorf("Failed to compare branches.") 415 + log.Println("failed to unmarshal format-patch response", err) 416 + return nil, fmt.Errorf("failed to compare branches.") 417 417 } 418 418 419 - return &diffTreeResponse, nil 419 + return &formatPatchResponse, nil 420 420 }
+6 -2
types/repo.go
··· 2 2 3 3 import ( 4 4 "github.com/go-git/go-git/v5/plumbing/object" 5 + "tangled.sh/tangled.sh/core/patchutil" 5 6 ) 6 7 7 8 type RepoIndexResponse struct { ··· 32 33 Diff *NiceDiff `json:"diff,omitempty"` 33 34 } 34 35 35 - type RepoDiffTreeResponse struct { 36 - DiffTree *DiffTree `json:"difftree,omitempty"` 36 + type RepoFormatPatchResponse struct { 37 + Rev1 string `json:"rev1,omitempty"` 38 + Rev2 string `json:"rev2,omitempty"` 39 + FormatPatch []patchutil.FormatPatch `json:"format_patch,omitempty"` 40 + Patch string `json:"patch,omitempty"` 37 41 } 38 42 39 43 type RepoTreeResponse struct {