- commit
- c20af52
- parent
- 8b876e0
- author
- Eric Bower
- date
- 2024-05-05 12:58:02 -0400 EDT
changes
M
db.go
+3,
-3
1@@ -8,7 +8,7 @@ import (
2 _ "modernc.org/sqlite"
3 )
4
5-// PatchRequest is a database model for patches submitted to a Repo
6+// PatchRequest is a database model for patches submitted to a Repo.
7 type PatchRequest struct {
8 ID int64 `db:"id"`
9 Pubkey string `db:"pubkey"`
10@@ -19,7 +19,7 @@ type PatchRequest struct {
11 UpdatedAt time.Time `db:"updated_at"`
12 }
13
14-// Patch is a database model for a single entry in a patchset
15+// Patch is a database model for a single entry in a patchset.
16 // This usually corresponds to a git commit.
17 type Patch struct {
18 ID int64 `db:"id"`
19@@ -36,7 +36,7 @@ type Patch struct {
20 CreatedAt time.Time `db:"created_at"`
21 }
22
23-// Comment is a database model for a non-patch comment within a PatchRequest
24+// Comment is a database model for a non-patch comment within a PatchRequest.
25 type Comment struct {
26 ID int64 `db:"id"`
27 Pubkey string `db:"pubkey"`
M
mdw.go
+91,
-63
1@@ -55,7 +55,7 @@ func gitServiceCommands(sesh ssh.Session, be *Backend, cmd, repo string) error {
2
3 func try(sesh ssh.Session, err error) {
4 if err != nil {
5- wish.Fatal(sesh, err)
6+ wish.Fatalln(sesh, err)
7 }
8 }
9
10@@ -65,60 +65,67 @@ func flagSet(sesh ssh.Session, cmdName string) *flag.FlagSet {
11 return cmd
12 }
13
14+type GitPatchRequest interface {
15+ GetPatchesByPrID(prID int64) ([]*Patch, error)
16+ SubmitPatch(pubkey string, prID int64, patch io.Reader) (*Patch, error)
17+ SubmitPatchRequest(pubkey string, repoName string, patches io.Reader) (*PatchRequest, error)
18+}
19+
20 type PrCmd struct {
21- Session ssh.Session
22 Backend *Backend
23- Repo string
24- Pubkey string
25 }
26
27-func (pr *PrCmd) PrintPatches(prID int64) {
28+var _ GitPatchRequest = PrCmd{}
29+var _ GitPatchRequest = (*PrCmd)(nil)
30+
31+func (pr PrCmd) GetPatchesByPrID(prID int64) ([]*Patch, error) {
32 patches := []*Patch{}
33- pr.Backend.DB.Select(
34+ err := pr.Backend.DB.Select(
35 &patches,
36 "SELECT * FROM patches WHERE patch_request_id=?",
37 prID,
38 )
39- if len(patches) == 0 {
40- wish.Printf(pr.Session, "no patches found for Patch Request ID: %d\n", prID)
41- return
42- }
43-
44- if len(patches) == 1 {
45- wish.Println(pr.Session, patches[0].RawText)
46- return
47+ if err != nil {
48+ return patches, err
49 }
50-
51- for _, patch := range patches {
52- wish.Printf(pr.Session, "%s\n\n\n", patch.RawText)
53+ if len(patches) == 0 {
54+ return patches, fmt.Errorf("no patches found for Patch Request ID: %d", prID)
55 }
56+ return patches, nil
57 }
58
59-func (cmd *PrCmd) SubmitPatch(prID int64) {
60+func (cmd PrCmd) SubmitPatch(pubkey string, prID int64, patch io.Reader) (*Patch, error) {
61 pr := PatchRequest{}
62- cmd.Backend.DB.Get(&pr, "SELECT * FROM patch_requests WHERE id=?", prID)
63+ err := cmd.Backend.DB.Get(&pr, "SELECT * FROM patch_requests WHERE id=?", prID)
64+ if err != nil {
65+ return nil, err
66+ }
67 if pr.ID == 0 {
68- wish.Fatalln(cmd.Session, "patch request does not exist")
69- return
70+ return nil, fmt.Errorf("patch request (ID: %d) does not exist", prID)
71 }
72
73 review := false
74- if pr.Pubkey != cmd.Pubkey {
75+ if pr.Pubkey != pubkey {
76 review = true
77 }
78
79 // need to read io.Reader from session twice
80 var buf bytes.Buffer
81- tee := io.TeeReader(cmd.Session, &buf)
82+ tee := io.TeeReader(patch, &buf)
83
84 _, preamble, err := gitdiff.Parse(tee)
85- try(cmd.Session, err)
86+ if err != nil {
87+ return nil, err
88+ }
89 header, err := gitdiff.ParsePatchHeader(preamble)
90- try(cmd.Session, err)
91+ if err != nil {
92+ return nil, err
93+ }
94
95- _, err = cmd.Backend.DB.Exec(
96- "INSERT INTO patches (pubkey, patch_request_id, author_name, author_email, title, body, commit_sha, commit_date, review, raw_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
97- cmd.Pubkey,
98+ patchID := 0
99+ row := cmd.Backend.DB.QueryRow(
100+ "INSERT INTO patches (pubkey, patch_request_id, author_name, author_email, title, body, commit_sha, commit_date, review, raw_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",
101+ pubkey,
102 prID,
103 header.Author.Name,
104 header.Author.Email,
105@@ -129,50 +136,61 @@ func (cmd *PrCmd) SubmitPatch(prID int64) {
106 review,
107 buf.String(),
108 )
109- try(cmd.Session, err)
110+ err = row.Scan(&patchID)
111+ if err != nil {
112+ return nil, err
113+ }
114
115- wish.Printf(cmd.Session, "submitted review!\n")
116+ var patchRec Patch
117+ err = cmd.Backend.DB.Get(&patchRec, "SELECT * FROM patches WHERE id=?")
118+ return &patchRec, err
119 }
120
121-func (cmd *PrCmd) SubmitPatchRequest(repoName string) {
122+func (cmd PrCmd) SubmitPatchRequest(pubkey string, repoName string, patches io.Reader) (*PatchRequest, error) {
123 err := git.EnsureWithin(cmd.Backend.ReposDir(), cmd.Backend.RepoName(repoName))
124- try(cmd.Session, err)
125+ if err != nil {
126+ return nil, err
127+ }
128 _, err = os.Stat(filepath.Join(cmd.Backend.ReposDir(), cmd.Backend.RepoName(repoName)))
129 if os.IsNotExist(err) {
130- wish.Fatalln(cmd.Session, "repo does not exist")
131- return
132+ return nil, fmt.Errorf("repo does not exist: %s", repoName)
133 }
134
135 // need to read io.Reader from session twice
136 var buf bytes.Buffer
137- tee := io.TeeReader(cmd.Session, &buf)
138+ tee := io.TeeReader(patches, &buf)
139
140 _, preamble, err := gitdiff.Parse(tee)
141- try(cmd.Session, err)
142+ if err != nil {
143+ return nil, err
144+ }
145 header, err := gitdiff.ParsePatchHeader(preamble)
146- try(cmd.Session, err)
147+ if err != nil {
148+ return nil, err
149+ }
150 prName := header.Title
151 prDesc := header.Body
152
153 var prID int64
154 row := cmd.Backend.DB.QueryRow(
155 "INSERT INTO patch_requests (pubkey, repo_id, name, text, updated_at) VALUES(?, ?, ?, ?, ?) RETURNING id",
156- cmd.Pubkey,
157+ pubkey,
158 repoName,
159 prName,
160 prDesc,
161 time.Now(),
162 )
163- row.Scan(&prID)
164+ err = row.Scan(&prID)
165+ if err != nil {
166+ return nil, err
167+ }
168 if prID == 0 {
169- wish.Fatal(cmd.Session, "could not create patch request")
170- return
171+ return nil, fmt.Errorf("could not create patch request")
172 }
173- try(cmd.Session, err)
174
175 _, err = cmd.Backend.DB.Exec(
176 "INSERT INTO patches (pubkey, patch_request_id, author_name, author_email, title, body, commit_sha, commit_date, raw_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
177- cmd.Pubkey,
178+ pubkey,
179 prID,
180 header.Author.Name,
181 header.Author.Email,
182@@ -182,17 +200,16 @@ func (cmd *PrCmd) SubmitPatchRequest(repoName string) {
183 header.CommitterDate,
184 buf.String(),
185 )
186- try(cmd.Session, err)
187+ if err != nil {
188+ return nil, err
189+ }
190
191- wish.Printf(
192- cmd.Session,
193- "created patch request!\nID: %d\nTitle: %s\n",
194- prID,
195- prName,
196- )
197+ var pr PatchRequest
198+ err = cmd.Backend.DB.Get(&pr, "SELECT * FROM patch_requests WHERE id=?", prID)
199+ return &pr, err
200 }
201
202-func GitPatchRequestMiddleware(be *Backend) wish.Middleware {
203+func GitPatchRequestMiddleware(be *Backend, pr GitPatchRequest) wish.Middleware {
204 isNumRe := regexp.MustCompile(`^\d+$`)
205
206 return func(next ssh.Handler) ssh.Handler {
207@@ -209,9 +226,7 @@ func GitPatchRequestMiddleware(be *Backend) wish.Middleware {
208 wish.Println(sesh, "commands: [help, pr, ls, git-receive-pack, git-upload-pack]")
209 } else if cmd == "ls" {
210 entries, err := os.ReadDir(be.ReposDir())
211- if err != nil {
212- wish.Fatal(sesh, err)
213- }
214+ try(sesh, err)
215
216 for _, e := range entries {
217 if e.IsDir() {
218@@ -246,20 +261,33 @@ func GitPatchRequestMiddleware(be *Backend) wish.Middleware {
219 }
220 out := prCmd.Bool("stdout", false, "print patchset to stdout")
221
222- pr := &PrCmd{
223- Session: sesh,
224- Backend: be,
225- Pubkey: pubkey,
226- }
227+ if *out {
228+ patches, err := pr.GetPatchesByPrID(prID)
229+ try(sesh, err)
230
231- if *out == true {
232- pr.PrintPatches(prID)
233+ if len(patches) == 0 {
234+ wish.Println(sesh, patches[0].RawText)
235+ return
236+ }
237+
238+ for _, patch := range patches {
239+ wish.Printf(sesh, "%s\n\n\n", patch.RawText)
240+ }
241 } else if prID != 0 {
242- pr.SubmitPatch(prID)
243+ patch, err := pr.SubmitPatch(pubkey, prID, sesh)
244+ if err != nil {
245+ wish.Fatalln(sesh, err)
246+ return
247+ }
248+ wish.Printf(sesh, "Patch submitted! (ID:%d)\n", patch.ID)
249 } else if subCmd == "ls" {
250 wish.Println(sesh, "list all patch requests")
251 } else if repoName != "" {
252- pr.SubmitPatchRequest(repoName)
253+ request, err := pr.SubmitPatchRequest(pubkey, repoName, sesh)
254+ if err != nil {
255+ wish.Fatalln(sesh, err)
256+ }
257+ wish.Printf(sesh, "Patch Request submitted! (ID:%d)\n", request.ID)
258 }
259
260 return
M
ssh.go
+4,
-1
1@@ -40,6 +40,9 @@ func GitSshServer() {
2 Logger: logger,
3 Cfg: cfg,
4 }
5+ prCmd := &PrCmd{
6+ Backend: be,
7+ }
8
9 s, err := wish.NewServer(
10 wish.WithAddress(
11@@ -50,7 +53,7 @@ func GitSshServer() {
12 ),
13 wish.WithPublicKeyAuth(authHandler),
14 wish.WithMiddleware(
15- GitPatchRequestMiddleware(be),
16+ GitPatchRequestMiddleware(be, prCmd),
17 ),
18 )
19