forked from tangled.org/core
this repo has no description

appview: add support for format-patch

Changed files
+56 -49
appview
types
+15
appview/db/pulls.go
···
"github.com/bluekeyes/go-gitdiff/gitdiff"
"github.com/bluesky-social/indigo/atproto/syntax"
+
"tangled.sh/tangled.sh/core/patchutil"
"tangled.sh/tangled.sh/core/types"
)
···
nd.Stat.FilesChanged = len(diffs)
return nd
+
}
+
+
func (s PullSubmission) IsFormatPatch() bool {
+
return patchutil.IsFormatPatch(s.Patch)
+
}
+
+
func (s PullSubmission) AsFormatPatch() []patchutil.FormatPatch {
+
patches, err := patchutil.ExtractPatches(s.Patch)
+
if err != nil {
+
log.Println("error extracting patches from submission:", err)
+
return []patchutil.FormatPatch{}
+
}
+
+
return patches
}
func NewPull(tx *sql.Tx, pull *Pull) error {
+29 -41
appview/state/pull.go
···
"net/http"
"net/url"
"strconv"
-
"strings"
"time"
"github.com/go-chi/chi/v5"
···
"tangled.sh/tangled.sh/core/appview/auth"
"tangled.sh/tangled.sh/core/appview/db"
"tangled.sh/tangled.sh/core/appview/pages"
+
"tangled.sh/tangled.sh/core/patchutil"
"tangled.sh/tangled.sh/core/types"
comatproto "github.com/bluesky-social/indigo/api/atproto"
···
latestSubmission := pull.Submissions[pull.LastRoundNumber()]
if latestSubmission.SourceRev != result.Branch.Hash {
+
fmt.Println(latestSubmission.SourceRev, result.Branch.Hash)
return pages.ShouldResubmit
}
···
return
}
-
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
+
comparison, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
if err != nil {
log.Println("failed to compare", err)
s.pages.Notice(w, "pull", err.Error())
return
}
-
sourceRev := diffTreeResponse.DiffTree.Rev2
-
patch := diffTreeResponse.DiffTree.Patch
+
sourceRev := comparison.Rev2
+
patch := comparison.Patch
-
if !isPatchValid(patch) {
+
if !patchutil.IsPatchValid(patch) {
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
return
}
···
}
func (s *State) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *auth.User, title, body, targetBranch, patch string) {
-
if !isPatchValid(patch) {
+
if !patchutil.IsPatchValid(patch) {
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
return
}
···
// hiddenRef: hidden/feature-1/main (on repo-fork)
// targetBranch: main (on repo-1)
// sourceBranch: feature-1 (on repo-fork)
-
diffTreeResponse, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
+
comparison, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
if err != nil {
log.Println("failed to compare across branches", err)
s.pages.Notice(w, "pull", err.Error())
return
}
-
sourceRev := diffTreeResponse.DiffTree.Rev2
-
patch := diffTreeResponse.DiffTree.Patch
+
sourceRev := comparison.Rev2
+
patch := comparison.Patch
-
if !isPatchValid(patch) {
+
if patchutil.IsPatchValid(patch) {
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
return
}
···
}, &tangled.RepoPull_Source{Branch: sourceBranch, Repo: &fork.AtUri})
}
-
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) {
+
func (s *State) createPullRequest(
+
w http.ResponseWriter,
+
r *http.Request,
+
f *FullyResolvedRepo,
+
user *auth.User,
+
title, body, targetBranch string,
+
patch string,
+
sourceRev string,
+
pullSource *db.PullSource,
+
recordPullSource *tangled.RepoPull_Source,
+
) {
tx, err := s.db.BeginTx(r.Context(), nil)
if err != nil {
log.Println("failed to start tx")
···
return
-
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
+
comparison, err := ksClient.Compare(f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.PullSource.Branch)
if err != nil {
log.Printf("compare request failed: %s", err)
s.pages.Notice(w, "resubmit-error", err.Error())
return
-
sourceRev := diffTreeResponse.DiffTree.Rev2
-
patch := diffTreeResponse.DiffTree.Patch
+
sourceRev := comparison.Rev2
+
patch := comparison.Patch
if err = validateResubmittedPatch(pull, patch); err != nil {
s.pages.Notice(w, "resubmit-error", err.Error())
···
hiddenRef := url.QueryEscape(fmt.Sprintf("hidden/%s/%s", pull.PullSource.Branch, pull.TargetBranch))
-
diffTreeResponse, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch)
+
comparison, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch)
if err != nil {
log.Printf("failed to compare branches: %s", err)
s.pages.Notice(w, "resubmit-error", err.Error())
return
-
sourceRev := diffTreeResponse.DiffTree.Rev2
-
patch := diffTreeResponse.DiffTree.Patch
+
sourceRev := comparison.Rev2
+
patch := comparison.Patch
if err = validateResubmittedPatch(pull, patch); err != nil {
s.pages.Notice(w, "resubmit-error", err.Error())
···
return fmt.Errorf("Patch is identical to previous submission.")
-
if !isPatchValid(patch) {
+
if patchutil.IsPatchValid(patch) {
return fmt.Errorf("Invalid patch format. Please provide a valid diff.")
···
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
return
-
-
// Very basic validation to check if it looks like a diff/patch
-
// A valid patch usually starts with diff or --- lines
-
func isPatchValid(patch string) bool {
-
// Basic validation to check if it looks like a diff/patch
-
// A valid patch usually starts with diff or --- lines
-
if len(patch) == 0 {
-
return false
-
}
-
-
lines := strings.Split(patch, "\n")
-
if len(lines) < 2 {
-
return false
-
}
-
-
// Check for common patch format markers
-
firstLine := strings.TrimSpace(lines[0])
-
return strings.HasPrefix(firstLine, "diff ") ||
-
strings.HasPrefix(firstLine, "--- ") ||
-
strings.HasPrefix(firstLine, "Index: ") ||
-
strings.HasPrefix(firstLine, "+++ ") ||
-
strings.HasPrefix(firstLine, "@@ ")
-
}
+6 -6
appview/state/signer.go
···
return &capabilities, nil
}
-
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoDiffTreeResponse, error) {
+
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoFormatPatchResponse, error) {
const (
Method = "GET"
)
···
}
defer compareResp.Body.Close()
-
var diffTreeResponse types.RepoDiffTreeResponse
-
err = json.Unmarshal(respBody, &diffTreeResponse)
+
var formatPatchResponse types.RepoFormatPatchResponse
+
err = json.Unmarshal(respBody, &formatPatchResponse)
if err != nil {
-
log.Println("failed to unmarshal diff tree response", err)
-
return nil, fmt.Errorf("Failed to compare branches.")
+
log.Println("failed to unmarshal format-patch response", err)
+
return nil, fmt.Errorf("failed to compare branches.")
}
-
return &diffTreeResponse, nil
+
return &formatPatchResponse, nil
}
+6 -2
types/repo.go
···
import (
"github.com/go-git/go-git/v5/plumbing/object"
+
"tangled.sh/tangled.sh/core/patchutil"
)
type RepoIndexResponse struct {
···
Diff *NiceDiff `json:"diff,omitempty"`
}
-
type RepoDiffTreeResponse struct {
-
DiffTree *DiffTree `json:"difftree,omitempty"`
+
type RepoFormatPatchResponse struct {
+
Rev1 string `json:"rev1,omitempty"`
+
Rev2 string `json:"rev2,omitempty"`
+
FormatPatch []patchutil.FormatPatch `json:"format_patch,omitempty"`
+
Patch string `json:"patch,omitempty"`
}
type RepoTreeResponse struct {