repos / git-pr

a self-hosted git collaboration server
git clone https://github.com/picosh/git-pr.git

commit
4ecc5a8
parent
cb5796b
author
Eric Bower
date
2024-06-04 23:19:21 -0400 EDT
style: sort by pr status
4 files changed,  +96, -16
M cli.go
M web.go
M cli.go
+41, -3
 1@@ -152,6 +152,16 @@ Here's how it works:
 2 						Usage:     "List all PRs",
 3 						Args:      true,
 4 						ArgsUsage: "[repoID]",
 5+						Flags: []cli.Flag{
 6+							&cli.BoolFlag{
 7+								Name:  "closed",
 8+								Usage: "only show closed PRs",
 9+							},
10+							&cli.BoolFlag{
11+								Name:  "accepted",
12+								Usage: "only show accepted PRs",
13+							},
14+						},
15 						Action: func(cCtx *cli.Context) error {
16 							repoID := cCtx.Args().First()
17 							var prs []*PatchRequest
18@@ -165,9 +175,24 @@ Here's how it works:
19 								return err
20 							}
21 
22+							onlyAccepted := cCtx.Bool("accepted")
23+							onlyClosed := cCtx.Bool("closed")
24+
25 							writer := NewTabWriter(sesh)
26 							fmt.Fprintln(writer, "ID\tRepoID\tName\tStatus\tDate")
27 							for _, req := range prs {
28+								if onlyAccepted && req.Status != "accepted" {
29+									continue
30+								}
31+
32+								if onlyClosed && req.Status != "closed" {
33+									continue
34+								}
35+
36+								if !onlyAccepted && !onlyClosed && req.Status != "open" {
37+									continue
38+								}
39+
40 								fmt.Fprintf(
41 									writer,
42 									"%d\t%s\t%s\t[%s]\t%s\n",
43@@ -360,8 +385,12 @@ Here's how it works:
44 								return err
45 							}
46 
47+							if patchReq.Status == "accepted" {
48+								return fmt.Errorf("PR has already been accepted")
49+							}
50+
51 							err = pr.UpdatePatchRequest(prID, pubkey, "accepted")
52-							if err != nil {
53+							if err == nil {
54 								wish.Printf(sesh, "Accepted PR %s (#%d)\n", patchReq.Name, patchReq.ID)
55 							}
56 							return err
57@@ -387,8 +416,13 @@ Here's how it works:
58 							if !isAdmin && !isContrib {
59 								return fmt.Errorf("you are not authorized to change PR status")
60 							}
61+
62+							if patchReq.Status == "closed" {
63+								return fmt.Errorf("PR has already been closed")
64+							}
65+
66 							err = pr.UpdatePatchRequest(prID, pubkey, "closed")
67-							if err != nil {
68+							if err == nil {
69 								wish.Printf(sesh, "Closed PR %s (#%d)\n", patchReq.Name, patchReq.ID)
70 							}
71 							return err
72@@ -415,8 +449,12 @@ Here's how it works:
73 								return fmt.Errorf("you are not authorized to change PR status")
74 							}
75 
76+							if patchReq.Status == "open" {
77+								return fmt.Errorf("PR is already open")
78+							}
79+
80 							err = pr.UpdatePatchRequest(prID, pubkey, "open")
81-							if err != nil {
82+							if err == nil {
83 								wish.Printf(sesh, "Reopened PR %s (#%d)\n", patchReq.Name, patchReq.ID)
84 							}
85 							return err
M tmpl/repo-detail.html
+35, -3
 1@@ -17,7 +17,9 @@
 2 	</div>
 3 </header>
 4 <main class="group">
 5-  {{range .Prs}}
 6+  <h3 class="text-lg">Open PRs</h3>
 7+
 8+  {{range .OpenPrs}}
 9   <article class="box">
10     <div><a href="{{.Url}}">{{.Text}}</a> <code>{{.Status}}</code></div>
11     <div class="text-sm">
12@@ -26,11 +28,41 @@
13       <code>{{.Pubkey}}</code>
14     </div>
15   </article>
16-  {{else}}
17+  {{end}}
18+
19+  {{if .AcceptedPrs}}
20+  <hr class="my w-full" />
21+
22+  <h3 class="text-lg">Accepted PRs</h3>
23+
24+  {{range .AcceptedPrs}}
25   <article class="box">
26-    <div>No patch requests for this repo.</div>
27+    <div><a href="{{.Url}}">{{.Text}}</a> <code>{{.Status}}</code></div>
28+    <div class="text-sm">
29+      <code>#{{.ID}}</code>
30+      <span>opened on <date>{{.Date}}</date> by </span>
31+      <code>{{.Pubkey}}</code>
32+    </div>
33   </article>
34   {{end}}
35+  {{end}}
36+
37+  {{if .ClosedPrs}}
38+  <hr class="my w-full" />
39+
40+  <h3 class="text-lg">Closed PRs</h3>
41+
42+  {{range .ClosedPrs}}
43+  <article class="box">
44+    <div><a href="{{.Url}}">{{.Text}}</a> <code>{{.Status}}</code></div>
45+    <div class="text-sm">
46+      <code>#{{.ID}}</code>
47+      <span>opened on <date>{{.Date}}</date> by </span>
48+      <code>{{.Pubkey}}</code>
49+    </div>
50+  </article>
51+  {{end}}
52+  {{end}}
53 </main>
54 
55 <hr />
M tmpl/repo-list.html
+0, -2
1@@ -26,8 +26,6 @@
2   </div>
3 </main>
4 
5-<hr />
6-
7 <footer>
8   <div><a href="/rss">rss</a></div>
9   <div class="text-sm">OR with fingerprint, url encoded: <code>/rss?pubkey=SHA256%3Axxx</code></div>
M web.go
+20, -8
 1@@ -136,9 +136,11 @@ type PrListData struct {
 2 }
 3 
 4 type RepoDetailData struct {
 5-	ID        string
 6-	CloneAddr string
 7-	Prs       []PrListData
 8+	ID          string
 9+	CloneAddr   string
10+	OpenPrs     []PrListData
11+	AcceptedPrs []PrListData
12+	ClosedPrs   []PrListData
13 }
14 
15 func repoHandler(w http.ResponseWriter, r *http.Request) {
16@@ -165,7 +167,9 @@ func repoHandler(w http.ResponseWriter, r *http.Request) {
17 		return
18 	}
19 
20-	prList := []PrListData{}
21+	openList := []PrListData{}
22+	acceptedList := []PrListData{}
23+	closedList := []PrListData{}
24 	for _, curpr := range prs {
25 		ls := PrListData{
26 			ID:     curpr.ID,
27@@ -177,15 +181,23 @@ func repoHandler(w http.ResponseWriter, r *http.Request) {
28 			Date:   curpr.CreatedAt.Format(time.RFC3339),
29 			Status: curpr.Status,
30 		}
31-		prList = append(prList, ls)
32+		if curpr.Status == "open" {
33+			openList = append(openList, ls)
34+		} else if curpr.Status == "accepted" {
35+			acceptedList = append(acceptedList, ls)
36+		} else {
37+			closedList = append(closedList, ls)
38+		}
39 	}
40 
41 	w.Header().Set("content-type", "text/html")
42 	tmpl := getTemplate("repo-detail.html")
43 	err = tmpl.Execute(w, RepoDetailData{
44-		ID:        repo.ID,
45-		CloneAddr: repo.CloneAddr,
46-		Prs:       prList,
47+		ID:          repo.ID,
48+		CloneAddr:   repo.CloneAddr,
49+		OpenPrs:     openList,
50+		AcceptedPrs: acceptedList,
51+		ClosedPrs:   closedList,
52 	})
53 	if err != nil {
54 		fmt.Println(err)