From e7cafd507c97b082e0bc9562984262154fc840ef Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Thu, 13 Mar 2025 15:27:19 +0200 Subject: [PATCH] appview: implement patch updates in pulls --- appview/db/pulls.go | 5 + .../pages/templates/repo/issues/issue.html | 8 +- appview/pages/templates/repo/pulls/pull.html | 169 ++++++++++++++---- appview/state/repo.go | 50 ++++-- appview/state/router.go | 1 + input.css | 8 +- 6 files changed, 185 insertions(+), 56 deletions(-) diff --git a/appview/db/pulls.go b/appview/db/pulls.go index 6ab9e6d1..82d3a50b 100644 --- a/appview/db/pulls.go +++ b/appview/db/pulls.go @@ -254,3 +254,8 @@ func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) { return count, nil } + +func EditPatch(e Execer, repoAt syntax.ATURI, pullId int, patch string) error { + _, err := e.Exec(`update pulls set patch = ? where repo_at = ? and pull_id = ?`, patch, repoAt, pullId) + return err +} diff --git a/appview/pages/templates/repo/issues/issue.html b/appview/pages/templates/repo/issues/issue.html index 434559b3..6cbca117 100644 --- a/appview/pages/templates/repo/issues/issue.html +++ b/appview/pages/templates/repo/issues/issue.html @@ -1,14 +1,14 @@ {{ define "title" }} - {{ .Issue.Title }} · + {{ .Issue.Title }} · issue #{{ .Issue.IssueId }} · {{ .RepoInfo.FullName }} {{ end }} {{ define "repoContent" }} -
-

+

+

{{ .Issue.Title }} #{{ .Issue.IssueId }} -

+

{{ $bgColor := "bg-gray-800" }} diff --git a/appview/pages/templates/repo/pulls/pull.html b/appview/pages/templates/repo/pulls/pull.html index 3ea4d869..37e5f159 100644 --- a/appview/pages/templates/repo/pulls/pull.html +++ b/appview/pages/templates/repo/pulls/pull.html @@ -4,10 +4,14 @@ {{ end }} {{ define "repoContent" }} -

- {{ .Pull.Title }} - #{{ .Pull.PullId }} -

+ +
+

+ {{ .Pull.Title }} + #{{ .Pull.PullId }} +

+
+ {{ $bgColor := "bg-gray-800" }} {{ $icon := "ban" }} {{ if eq .State "open" }} @@ -49,48 +53,145 @@ {{ end }} -
+
patch -
+            
+
        {{- .Pull.Patch -}}
-        
+
+
+ + +
+ + + +
+
+ +
+
+
+
- -
- {{ if .MergeCheck }} -
-
- {{ if .MergeCheck.IsConflicted }} - - merge conflicts detected + + {{ if .MergeCheck }} +
+
- ready to merge + bg-green-50 border-green-200 + {{ end }}" + > +
+ {{ if .MergeCheck.IsConflicted }} + + merge conflicts detected + {{ else }} + + ready to merge + {{ end }} +
+ + {{ if .MergeCheck.IsConflicted }} +
+
    + {{ range .MergeCheck.Conflicts }} +
  • + + {{ slice .Filename 0 (sub (len .Filename) 2) }} +
  • + {{ end }} +
+
{{ end }}
- - {{ if .MergeCheck.IsConflicted }} -
-
    - {{ range .MergeCheck.Conflicts }} -
  • - - {{ slice .Filename 0 (sub (len .Filename) 2) }} -
  • - {{ end }} -
-
- {{ end }}
- {{ end }} -
+ {{ end }} {{ end }} {{ define "repoAfter" }} @@ -134,6 +235,7 @@
{{ end }} + {{ if .LoggedInUser }} @@ -172,7 +274,6 @@ > {{ $action }} -
{{ end }} {{ end }} diff --git a/appview/state/repo.go b/appview/state/repo.go index 2ab7af32..3d7740fd 100644 --- a/appview/state/repo.go +++ b/appview/state/repo.go @@ -230,49 +230,72 @@ func (s *State) RepoDescription(w http.ResponseWriter, r *http.Request) { } } -// MergeCheck gets called async, every time the patch diff is updated in a pull. -func (s *State) MergeCheck(w http.ResponseWriter, r *http.Request) { +func (s *State) EditPatch(w http.ResponseWriter, r *http.Request) { user := s.auth.GetUser(r) f, err := fullyResolvedRepo(r) if err != nil { log.Println("failed to get repo and knot", err) - s.pages.Notice(w, "pull", "Failed to check mergeability. Try again later.") + s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.") + return + } + + prId := chi.URLParam(r, "pull") + prIdInt, err := strconv.Atoi(prId) + if err != nil { + http.Error(w, "bad pr id", http.StatusBadRequest) + log.Println("failed to parse pr id", err) return } patch := r.FormValue("patch") - targetBranch := r.FormValue("targetBranch") + if patch == "" { + s.pages.Notice(w, "pull-error", "Patch is required.") + return + } + + err = db.EditPatch(s.db, f.RepoAt, prIdInt, patch) + if err != nil { + log.Println("failed to update patch", err) + s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.") + return + } - if patch == "" || targetBranch == "" { - s.pages.Notice(w, "pull", "Patch and target branch are required.") + // Get target branch after patch update + pull, _, err := db.GetPullWithComments(s.db, f.RepoAt, prIdInt) + if err != nil { + log.Println("failed to get pull information", err) + s.pages.Notice(w, "pull-success", "Patch updated successfully.") return } + targetBranch := pull.TargetBranch + + // Perform merge check secret, err := db.GetRegistrationKey(s.db, f.Knot) if err != nil { log.Printf("no key found for domain %s: %s\n", f.Knot, err) - s.pages.Notice(w, "pull", "Failed to check mergeability. Try again later.") + s.pages.Notice(w, "pull-success", "Patch updated successfully, but couldn't check mergeability.") return } ksClient, err := NewSignedClient(f.Knot, secret, s.config.Dev) if err != nil { log.Printf("failed to create signed client for %s", f.Knot) - s.pages.Notice(w, "pull", "Failed to check mergeability. Try again later.") + s.pages.Notice(w, "pull-success", "Patch updated successfully, but couldn't check mergeability.") return } resp, err := ksClient.MergeCheck([]byte(patch), user.Did, f.RepoName, targetBranch) if err != nil { log.Println("failed to check mergeability", err) - s.pages.Notice(w, "pull", "Unable to check for mergeability. Try again later.") + s.pages.Notice(w, "pull-success", "Patch updated successfully, but couldn't check mergeability.") return } respBody, err := io.ReadAll(resp.Body) if err != nil { log.Println("failed to read knotserver response body") - s.pages.Notice(w, "pull", "Unable to check for mergeability. Try again later.") + s.pages.Notice(w, "pull-success", "Patch updated successfully, but couldn't check mergeability.") return } @@ -280,13 +303,12 @@ func (s *State) MergeCheck(w http.ResponseWriter, r *http.Request) { err = json.Unmarshal(respBody, &mergeCheckResponse) if err != nil { log.Println("failed to unmarshal merge check response", err) - s.pages.Notice(w, "pull", "Failed to check mergeability. Try again later.") + s.pages.Notice(w, "pull-success", "Patch updated successfully, but couldn't check mergeability.") return } - // TODO: this has to return a html fragment - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(mergeCheckResponse) + s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s/pulls/%d", f.OwnerHandle(), f.RepoName, prIdInt)) + return } func (s *State) NewPull(w http.ResponseWriter, r *http.Request) { diff --git a/appview/state/router.go b/appview/state/router.go index 20b9c511..76972781 100644 --- a/appview/state/router.go +++ b/appview/state/router.go @@ -64,6 +64,7 @@ func (s *State) UserRouter() http.Handler { r.Use(AuthMiddleware(s)) r.Get("/new", s.NewPull) r.Post("/new", s.NewPull) + r.Patch("/{pull}/patch", s.EditPatch) // r.Post("/{pull}/comment", s.PullComment) // r.Post("/{pull}/close", s.ClosePull) // r.Post("/{pull}/reopen", s.ReopenPull) diff --git a/input.css b/input.css index 9c21b476..0e32a9d0 100644 --- a/input.css +++ b/input.css @@ -105,9 +105,9 @@ @layer base { html { - letter-spacing: -0.01em; - word-spacing: -0.07em; - font-size: 14px; + letter-spacing: -0.01em; + word-spacing: -0.07em; + font-size: 14px; } a { @apply no-underline text-black hover:underline hover:text-gray-800; @@ -147,7 +147,7 @@ @apply py-1 text-red-400; } .success { - @apply py-1 text-black; + @apply py-1 text-green-400; } } } -- 2.51.2