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

appview: fix and refactor resubmit endpoint

- ksClient returns strong types in its API
- ResubmitPull is broken down into 3 flows similar to NewPull

there is quite a bit of duplication going on here; but i imagine this is solved by introducing the xrpc layer down the line.

Changed files
+396 -206
appview
db
pages
templates
fragments
repo
state
+13 -3
appview/db/pulls.go
···
return len(p.Submissions) - 1
}
-
func (p *Pull) IsSameRepoBranch() bool {
+
func (p *Pull) IsPatchBased() bool {
+
return p.PullSource == nil
+
}
+
+
func (p *Pull) IsBranchBased() bool {
if p.PullSource != nil {
if p.PullSource.RepoAt != nil {
return p.PullSource.RepoAt == &p.RepoAt
···
return false
}
-
func (p *Pull) IsPatch() bool {
-
return p.PullSource == nil
+
func (p *Pull) IsForkBased() bool {
+
if p.PullSource != nil {
+
if p.PullSource.RepoAt != nil {
+
// make sure repos are different
+
return p.PullSource.RepoAt != &p.RepoAt
+
}
+
}
+
return false
}
func (s PullSubmission) AsNiceDiff(targetBranch string) types.NiceDiff {
+2 -2
appview/pages/templates/fragments/pullActions.html
···
{{ $isConflicted := and .MergeCheck (or .MergeCheck.Error .MergeCheck.IsConflicted) }}
{{ $isPullAuthor := and .LoggedInUser (eq .LoggedInUser.Did .Pull.OwnerDid) }}
{{ $isLastRound := eq $roundNumber $lastIdx }}
-
{{ $isSameRepoBranch := .Pull.IsSameRepoBranch }}
+
{{ $isSameRepoBranch := .Pull.IsBranchBased }}
{{ $isUpToDate := .ResubmitCheck.No }}
<div class="relative w-fit">
<div id="actions-{{$roundNumber}}" class="flex flex-wrap gap-2">
···
{{ $disabled = "disabled" }}
{{ end }}
<button id="resubmitBtn"
-
{{ if not .Pull.IsPatch }}
+
{{ if not .Pull.IsPatchBased }}
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit"
{{ else }}
hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit"
+3 -3
appview/pages/templates/repo/pulls/pull.html
···
<a href="/{{ .RepoInfo.FullName }}/tree/{{ .Pull.TargetBranch }}" class="no-underline hover:underline">{{ .Pull.TargetBranch }}</a>
</span>
</span>
-
{{ if not .Pull.IsPatch }}
+
{{ if not .Pull.IsPatchBased }}
<span>from
-
{{ if not .Pull.IsSameRepoBranch }}
+
{{ if not .Pull.IsBranchBased }}
<a href="/{{ $owner }}/{{ .PullSourceRepo.Name }}" class="no-underline hover:underline">{{ $owner }}/{{ .PullSourceRepo.Name }}</a>
{{ end }}
{{ $fullRepo := .RepoInfo.FullName }}
-
{{ if not .Pull.IsSameRepoBranch }}
+
{{ if not .Pull.IsBranchBased }}
{{ $fullRepo = printf "%s/%s" $owner .PullSourceRepo.Name }}
{{ end }}
<span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-1/2 inline-flex items-center">
+2 -2
appview/pages/templates/repo/pulls/pulls.html
···
{{ .TargetBranch }}
</span>
</span>
-
{{ if not .IsPatch }}
+
{{ if not .IsPatchBased }}
<span>from
-
{{ if not .IsSameRepoBranch }}
+
{{ if not .IsBranchBased }}
<a href="/{{ $owner }}/{{ .PullSource.Repo.Name }}" class="no-underline hover:underline">{{ $owner }}/{{ .PullSource.Repo.Name }}</a>
{{ end }}
+344 -192
appview/state/pull.go
···
return
}
-
resp, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
-
switch resp.StatusCode {
-
case 404:
-
case 400:
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
-
return
-
}
-
-
respBody, err := io.ReadAll(resp.Body)
+
diffTreeResponse, err := ksClient.Compare(f.OwnerDid(), f.RepoName, targetBranch, sourceBranch)
if err != nil {
-
log.Println("failed to compare across branches")
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
defer resp.Body.Close()
-
-
var diffTreeResponse types.RepoDiffTreeResponse
-
err = json.Unmarshal(respBody, &diffTreeResponse)
-
if err != nil {
-
log.Println("failed to unmarshal diff tree response", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
+
log.Println("failed to compare", err)
+
s.pages.Notice(w, "pull", err.Error())
return
}
···
// hiddenRef: hidden/feature-1/main (on repo-fork)
// targetBranch: main (on repo-1)
// sourceBranch: feature-1 (on repo-fork)
-
diffResp, err := us.Compare(user.Did, fork.Name, hiddenRef, sourceBranch)
+
diffTreeResponse, 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", "Failed to create pull request. Try again later.")
-
return
-
}
-
-
respBody, err := io.ReadAll(diffResp.Body)
-
if err != nil {
-
log.Println("failed to read response body", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
-
defer resp.Body.Close()
-
-
var diffTreeResponse types.RepoDiffTreeResponse
-
err = json.Unmarshal(respBody, &diffTreeResponse)
-
if err != nil {
-
log.Println("failed to unmarshal diff tree response", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
+
s.pages.Notice(w, "pull", err.Error())
return
}
···
})
return
case http.MethodPost:
-
patch := r.FormValue("patch")
-
var sourceRev string
-
var recordPullSource *tangled.RepoPull_Source
-
-
var ownerDid, repoName, knotName string
-
var isSameRepo bool = pull.IsSameRepoBranch()
-
sourceBranch := pull.PullSource.Branch
-
targetBranch := pull.TargetBranch
-
recordPullSource = &tangled.RepoPull_Source{
-
Branch: sourceBranch,
+
if pull.IsPatchBased() {
+
s.resubmitPatch(w, r)
+
return
+
} else if pull.IsBranchBased() {
+
s.resubmitBranch(w, r)
+
return
+
} else if pull.IsForkBased() {
+
s.resubmitFork(w, r)
+
return
}
+
}
+
}
-
isPushAllowed := f.RepoInfo(s, user).Roles.IsPushAllowed()
-
if isSameRepo && isPushAllowed {
-
ownerDid = f.OwnerDid()
-
repoName = f.RepoName
-
knotName = f.Knot
-
} else if !isSameRepo {
-
sourceRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
-
if err != nil {
-
log.Println("failed to get source repo", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
ownerDid = sourceRepo.Did
-
repoName = sourceRepo.Name
-
knotName = sourceRepo.Knot
-
}
+
func (s *State) resubmitPatch(w http.ResponseWriter, r *http.Request) {
+
user := s.auth.GetUser(r)
-
if sourceBranch != "" && knotName != "" {
-
// extract patch by performing compare
-
ksClient, err := NewUnsignedClient(knotName, s.config.Dev)
-
if err != nil {
-
log.Printf("failed to create client for %s: %s", knotName, err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
if !ok {
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
+
return
+
}
-
if !isSameRepo {
-
secret, err := db.GetRegistrationKey(s.db, knotName)
-
if err != nil {
-
log.Printf("failed to get registration key for %s: %s", knotName, err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
// update the hidden tracking branch to latest
-
signedClient, err := NewSignedClient(knotName, secret, s.config.Dev)
-
if err != nil {
-
log.Printf("failed to create signed client for %s: %s", knotName, err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
resp, err := signedClient.NewHiddenRef(ownerDid, repoName, sourceBranch, targetBranch)
-
if err != nil || resp.StatusCode != http.StatusNoContent {
-
log.Printf("failed to update tracking branch: %s", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
}
+
f, err := fullyResolvedRepo(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
+
return
+
}
-
var compareResp *http.Response
-
if !isSameRepo {
-
hiddenRef := url.QueryEscape(fmt.Sprintf("hidden/%s/%s", sourceBranch, targetBranch))
-
compareResp, err = ksClient.Compare(ownerDid, repoName, hiddenRef, sourceBranch)
-
} else {
-
compareResp, err = ksClient.Compare(ownerDid, repoName, targetBranch, sourceBranch)
-
}
-
if err != nil {
-
log.Printf("failed to compare branches: %s", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
defer compareResp.Body.Close()
+
if user.Did != pull.OwnerDid {
+
log.Println("unauthorized user")
+
w.WriteHeader(http.StatusUnauthorized)
+
return
+
}
-
switch compareResp.StatusCode {
-
case 404:
-
case 400:
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
-
return
-
}
+
patch := r.FormValue("patch")
-
respBody, err := io.ReadAll(compareResp.Body)
-
if err != nil {
-
log.Println("failed to compare across branches")
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
-
defer compareResp.Body.Close()
+
if err = validateResubmittedPatch(pull, patch); err != nil {
+
s.pages.Notice(w, "resubmit-error", err.Error())
+
}
-
var diffTreeResponse types.RepoDiffTreeResponse
-
err = json.Unmarshal(respBody, &diffTreeResponse)
-
if err != nil {
-
log.Println("failed to unmarshal diff tree response", err)
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
-
return
-
}
+
tx, err := s.db.BeginTx(r.Context(), nil)
+
if err != nil {
+
log.Println("failed to start tx")
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
defer tx.Rollback()
-
sourceRev = diffTreeResponse.DiffTree.Rev2
-
patch = diffTreeResponse.DiffTree.Patch
-
}
+
err = db.ResubmitPull(tx, pull, patch, "")
+
if err != nil {
+
log.Println("failed to resubmit pull request", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull request. Try again later.")
+
return
+
}
+
client, _ := s.auth.AuthorizedClient(r)
-
if patch == "" {
-
s.pages.Notice(w, "resubmit-error", "Patch is empty.")
-
return
-
}
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
+
if err != nil {
+
// failed to get record
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
+
return
+
}
-
if patch == pull.LatestPatch() {
-
s.pages.Notice(w, "resubmit-error", "Patch is identical to previous submission.")
-
return
-
}
+
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
+
Collection: tangled.RepoPullNSID,
+
Repo: user.Did,
+
Rkey: pull.Rkey,
+
SwapRecord: ex.Cid,
+
Record: &lexutil.LexiconTypeDecoder{
+
Val: &tangled.RepoPull{
+
Title: pull.Title,
+
PullId: int64(pull.PullId),
+
TargetRepo: string(f.RepoAt),
+
TargetBranch: pull.TargetBranch,
+
Patch: patch, // new patch
+
},
+
},
+
})
+
if err != nil {
+
log.Println("failed to update record", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
+
return
+
}
-
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
-
s.pages.Notice(w, "resubmit-error", "This branch has not changed since the last submission.")
-
return
-
}
+
if err = tx.Commit(); err != nil {
+
log.Println("failed to commit transaction", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
+
return
+
}
-
if !isPatchValid(patch) {
-
s.pages.Notice(w, "resubmit-error", "Invalid patch format. Please provide a valid diff.")
-
return
-
}
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
+
return
+
}
-
tx, err := s.db.BeginTx(r.Context(), nil)
-
if err != nil {
-
log.Println("failed to start tx")
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
-
return
-
}
-
defer tx.Rollback()
+
func (s *State) resubmitBranch(w http.ResponseWriter, r *http.Request) {
+
user := s.auth.GetUser(r)
-
err = db.ResubmitPull(tx, pull, patch, sourceRev)
-
if err != nil {
-
log.Println("failed to create pull request", err)
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
-
return
-
}
-
client, _ := s.auth.AuthorizedClient(r)
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
if !ok {
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
+
return
+
}
-
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
-
if err != nil {
-
// failed to get record
-
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
-
return
-
}
+
f, err := fullyResolvedRepo(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
+
return
+
}
-
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
-
Collection: tangled.RepoPullNSID,
-
Repo: user.Did,
-
Rkey: pull.Rkey,
-
SwapRecord: ex.Cid,
-
Record: &lexutil.LexiconTypeDecoder{
-
Val: &tangled.RepoPull{
-
Title: pull.Title,
-
PullId: int64(pull.PullId),
-
TargetRepo: string(f.RepoAt),
-
TargetBranch: pull.TargetBranch,
-
Patch: patch, // new patch
-
Source: recordPullSource,
-
},
+
if user.Did != pull.OwnerDid {
+
log.Println("unauthorized user")
+
w.WriteHeader(http.StatusUnauthorized)
+
return
+
}
+
+
if !f.RepoInfo(s, user).Roles.IsPushAllowed() {
+
log.Println("unauthorized user")
+
w.WriteHeader(http.StatusUnauthorized)
+
return
+
}
+
+
ksClient, err := NewUnsignedClient(f.Knot, s.config.Dev)
+
if err != nil {
+
log.Printf("failed to create client for %s: %s", f.Knot, err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
+
diffTreeResponse, 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
+
+
if err = validateResubmittedPatch(pull, patch); err != nil {
+
s.pages.Notice(w, "resubmit-error", err.Error())
+
}
+
+
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
+
s.pages.Notice(w, "resubmit-error", "This branch has not changed since the last submission.")
+
return
+
}
+
+
tx, err := s.db.BeginTx(r.Context(), nil)
+
if err != nil {
+
log.Println("failed to start tx")
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
defer tx.Rollback()
+
+
err = db.ResubmitPull(tx, pull, patch, sourceRev)
+
if err != nil {
+
log.Println("failed to create pull request", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
client, _ := s.auth.AuthorizedClient(r)
+
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
+
if err != nil {
+
// failed to get record
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
+
return
+
}
+
+
recordPullSource := &tangled.RepoPull_Source{
+
Branch: pull.PullSource.Branch,
+
}
+
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
+
Collection: tangled.RepoPullNSID,
+
Repo: user.Did,
+
Rkey: pull.Rkey,
+
SwapRecord: ex.Cid,
+
Record: &lexutil.LexiconTypeDecoder{
+
Val: &tangled.RepoPull{
+
Title: pull.Title,
+
PullId: int64(pull.PullId),
+
TargetRepo: string(f.RepoAt),
+
TargetBranch: pull.TargetBranch,
+
Patch: patch, // new patch
+
Source: recordPullSource,
},
-
})
-
if err != nil {
-
log.Println("failed to update record", err)
-
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
-
return
-
}
+
},
+
})
+
if err != nil {
+
log.Println("failed to update record", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
+
return
+
}
+
+
if err = tx.Commit(); err != nil {
+
log.Println("failed to commit transaction", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
+
return
+
}
+
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
+
return
+
}
+
+
func (s *State) resubmitFork(w http.ResponseWriter, r *http.Request) {
+
user := s.auth.GetUser(r)
-
if err = tx.Commit(); err != nil {
-
log.Println("failed to commit transaction", err)
-
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
-
return
-
}
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
if !ok {
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "resubmit-error", "Failed to edit patch. Try again later.")
+
return
+
}
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
+
f, err := fullyResolvedRepo(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
return
+
+
if user.Did != pull.OwnerDid {
+
log.Println("unauthorized user")
+
w.WriteHeader(http.StatusUnauthorized)
+
return
+
}
+
+
forkRepo, err := db.GetRepoByAtUri(s.db, pull.PullSource.RepoAt.String())
+
if err != nil {
+
log.Println("failed to get source repo", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
+
// extract patch by performing compare
+
ksClient, err := NewUnsignedClient(forkRepo.Knot, s.config.Dev)
+
if err != nil {
+
log.Printf("failed to create client for %s: %s", forkRepo.Knot, err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
+
secret, err := db.GetRegistrationKey(s.db, forkRepo.Knot)
+
if err != nil {
+
log.Printf("failed to get registration key for %s: %s", forkRepo.Knot, err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
+
// update the hidden tracking branch to latest
+
signedClient, err := NewSignedClient(forkRepo.Knot, secret, s.config.Dev)
+
if err != nil {
+
log.Printf("failed to create signed client for %s: %s", forkRepo.Knot, err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
+
resp, err := signedClient.NewHiddenRef(forkRepo.Did, forkRepo.Name, pull.PullSource.Branch, pull.TargetBranch)
+
if err != nil || resp.StatusCode != http.StatusNoContent {
+
log.Printf("failed to update tracking branch: %s", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
+
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)
+
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
+
+
if err = validateResubmittedPatch(pull, patch); err != nil {
+
s.pages.Notice(w, "resubmit-error", err.Error())
+
}
+
+
if sourceRev == pull.Submissions[pull.LastRoundNumber()].SourceRev {
+
s.pages.Notice(w, "resubmit-error", "This branch has not changed since the last submission.")
+
return
+
}
+
+
tx, err := s.db.BeginTx(r.Context(), nil)
+
if err != nil {
+
log.Println("failed to start tx")
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
defer tx.Rollback()
+
+
err = db.ResubmitPull(tx, pull, patch, sourceRev)
+
if err != nil {
+
log.Println("failed to create pull request", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
+
return
+
}
+
client, _ := s.auth.AuthorizedClient(r)
+
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
+
if err != nil {
+
// failed to get record
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
+
return
+
}
+
+
repoAt := pull.PullSource.RepoAt.String()
+
recordPullSource := &tangled.RepoPull_Source{
+
Branch: pull.PullSource.Branch,
+
Repo: &repoAt,
+
}
+
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
+
Collection: tangled.RepoPullNSID,
+
Repo: user.Did,
+
Rkey: pull.Rkey,
+
SwapRecord: ex.Cid,
+
Record: &lexutil.LexiconTypeDecoder{
+
Val: &tangled.RepoPull{
+
Title: pull.Title,
+
PullId: int64(pull.PullId),
+
TargetRepo: string(f.RepoAt),
+
TargetBranch: pull.TargetBranch,
+
Patch: patch, // new patch
+
Source: recordPullSource,
+
},
+
},
+
})
+
if err != nil {
+
log.Println("failed to update record", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to update pull request on the PDS. Try again later.")
+
return
+
}
+
+
if err = tx.Commit(); err != nil {
+
log.Println("failed to commit transaction", err)
+
s.pages.Notice(w, "resubmit-error", "Failed to resubmit pull.")
+
return
+
}
+
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
+
return
+
}
+
+
// validate a resubmission against a pull request
+
func validateResubmittedPatch(pull *db.Pull, patch string) error {
+
if patch == "" {
+
return fmt.Errorf("Patch is empty.")
+
}
+
+
if patch == pull.LatestPatch() {
+
return fmt.Errorf("Patch is identical to previous submission.")
+
}
+
+
if !isPatchValid(patch) {
+
return fmt.Errorf("Invalid patch format. Please provide a valid diff.")
+
}
+
+
return nil
func (s *State) MergePull(w http.ResponseWriter, r *http.Request) {
+31 -3
appview/state/signer.go
···
"encoding/hex"
"encoding/json"
"fmt"
+
"io"
+
"log"
"net/http"
"net/url"
"time"
···
return &capabilities, nil
}
-
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*http.Response, error) {
+
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoDiffTreeResponse, error) {
const (
Method = "GET"
)
···
req, err := us.newRequest(Method, endpoint, nil)
if err != nil {
-
return nil, err
+
return nil, fmt.Errorf("Failed to create request.")
}
-
return us.client.Do(req)
+
compareResp, err := us.client.Do(req)
+
if err != nil {
+
return nil, fmt.Errorf("Failed to create request.")
+
}
+
defer compareResp.Body.Close()
+
+
switch compareResp.StatusCode {
+
case 404:
+
case 400:
+
return nil, fmt.Errorf("Branch comparisons not supported on this knot.")
+
}
+
+
respBody, err := io.ReadAll(compareResp.Body)
+
if err != nil {
+
log.Println("failed to compare across branches")
+
return nil, fmt.Errorf("Failed to compare branches.")
+
}
+
defer compareResp.Body.Close()
+
+
var diffTreeResponse types.RepoDiffTreeResponse
+
err = json.Unmarshal(respBody, &diffTreeResponse)
+
if err != nil {
+
log.Println("failed to unmarshal diff tree response", err)
+
return nil, fmt.Errorf("Failed to compare branches.")
+
}
+
+
return &diffTreeResponse, nil
}
+1 -1
flake.nix
···
g = config.services.tangled-knotserver.gitUser;
in [
"d /var/lib/knotserver 0770 ${u} ${g} - -" # Create the directory first
-
"f+ /var/lib/knotserver/secret 0660 ${u} ${g} - KNOT_SERVER_SECRET=6995e040e80e2d593b5e5e9ca611a70140b9ef8044add0a28b48b1ee34aa3e85"
+
"f+ /var/lib/knotserver/secret 0660 ${u} ${g} - KNOT_SERVER_SECRET=5b42390da4c6659f34c9a545adebd8af82c4a19960d735f651e3d582623ba9f2"
];
services.tangled-knotserver = {
enable = true;