- commit
- 751f871
- parent
- d60f2ca
- author
- Eric Bower
- date
- 2024-05-02 00:45:15 -0400 EDT
nice
M
cfg.go
+4,
-2
1@@ -1,11 +1,13 @@
2 package git
3
4 type GitCfg struct {
5- DataPath string
6+ DataPath string
7+ AdminPubkeys []string
8 }
9
10 func NewGitCfg() *GitCfg {
11 return &GitCfg{
12- DataPath: "ssh_data",
13+ DataPath: "ssh_data",
14+ AdminPubkeys: []string{},
15 }
16 }
M
mdw.go
+92,
-47
1@@ -4,7 +4,9 @@ import (
2 "bytes"
3 "fmt"
4 "io"
5+ "os"
6 "path/filepath"
7+ "strconv"
8 "time"
9
10 "github.com/bluekeyes/go-gitdiff/gitdiff"
11@@ -66,63 +68,106 @@ func GitServerMiddleware(be *Backend) wish.Middleware {
12 err := gitServiceCommands(sesh, be, cmd, repoName)
13 try(sesh, err)
14 } else if cmd == "help" {
15- wish.Println(sesh, "commands: [help, git-receive-pack, git-upload-pack]")
16+ wish.Println(sesh, "commands: [help, pr, ls, git-receive-pack, git-upload-pack]")
17+ } else if cmd == "ls" {
18+ entries, err := os.ReadDir(be.ReposDir())
19+ if err != nil {
20+ wish.Fatal(sesh, err)
21+ }
22+
23+ for _, e := range entries {
24+ if e.IsDir() {
25+ wish.Println(sesh, utils.SanitizeRepo(e.Name()))
26+ }
27+ }
28 } else if cmd == "pr" {
29 if len(args) < 2 {
30 wish.Fatal(sesh, "must provide repo name")
31 return
32 }
33+
34 repoName := utils.SanitizeRepo(args[1])
35- err := git.EnsureWithin(be.ReposDir(), be.RepoName(repoName))
36- try(sesh, err)
37
38- // need to read io.Reader from session twice
39- var buf bytes.Buffer
40- tee := io.TeeReader(sesh, &buf)
41+ if len(args) > 2 {
42+ prID, err := strconv.ParseInt(args[2], 10, 64)
43+ try(sesh, err)
44
45- _, preamble, err := gitdiff.Parse(tee)
46- try(sesh, err)
47- header, err := gitdiff.ParsePatchHeader(preamble)
48- try(sesh, err)
49- prName := header.Title
50- prDesc := header.Body
51-
52- var prID int64
53- row := be.DB.QueryRow(
54- "INSERT INTO patch_requests (pubkey, repo_id, name, text, updated_at) VALUES(?, ?, ?, ?, ?) RETURNING id",
55- pubkey,
56- repoName,
57- prName,
58- prDesc,
59- time.Now(),
60- )
61- row.Scan(&prID)
62- if prID == 0 {
63- wish.Fatal(sesh, "could not create patch request")
64- return
65- }
66- try(sesh, err)
67+ patches := []*Patch{}
68+ be.DB.Select(
69+ &patches,
70+ "SELECT * FROM patches WHERE patch_request_id=?",
71+ prID,
72+ )
73+ if len(patches) == 0 {
74+ wish.Printf(sesh, "No patches found for Patch Request ID: %d\n", prID)
75+ return
76+ }
77
78- _, err = be.DB.Exec(
79- "INSERT INTO patches (pubkey, patch_request_id, author_name, author_email, title, body, commit_sha, commit_date, raw_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
80- pubkey,
81- prID,
82- header.Author.Name,
83- header.Author.Email,
84- header.Title,
85- header.Body,
86- header.SHA,
87- header.CommitterDate,
88- buf.String(),
89- )
90- try(sesh, err)
91+ if len(patches) == 1 {
92+ wish.Println(sesh, patches[0].RawText)
93+ return
94+ }
95+
96+ for _, patch := range patches {
97+ wish.Printf(sesh, "%s\n\n\n", patch.RawText)
98+ }
99+ } else {
100+ err := git.EnsureWithin(be.ReposDir(), be.RepoName(repoName))
101+ try(sesh, err)
102+ _, err = os.Stat(filepath.Join(be.ReposDir(), be.RepoName(repoName)))
103+ if os.IsNotExist(err) {
104+ wish.Fatalln(sesh, "repo does not exist")
105+ return
106+ }
107+
108+ // need to read io.Reader from session twice
109+ var buf bytes.Buffer
110+ tee := io.TeeReader(sesh, &buf)
111
112- wish.Printf(
113- sesh,
114- "Create Patch Request!\nID: %d\nTitle: %s\n",
115- prID,
116- prName,
117- )
118+ _, preamble, err := gitdiff.Parse(tee)
119+ try(sesh, err)
120+ header, err := gitdiff.ParsePatchHeader(preamble)
121+ try(sesh, err)
122+ prName := header.Title
123+ prDesc := header.Body
124+
125+ var prID int64
126+ row := be.DB.QueryRow(
127+ "INSERT INTO patch_requests (pubkey, repo_id, name, text, updated_at) VALUES(?, ?, ?, ?, ?) RETURNING id",
128+ pubkey,
129+ repoName,
130+ prName,
131+ prDesc,
132+ time.Now(),
133+ )
134+ row.Scan(&prID)
135+ if prID == 0 {
136+ wish.Fatal(sesh, "could not create patch request")
137+ return
138+ }
139+ try(sesh, err)
140+
141+ _, err = be.DB.Exec(
142+ "INSERT INTO patches (pubkey, patch_request_id, author_name, author_email, title, body, commit_sha, commit_date, raw_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
143+ pubkey,
144+ prID,
145+ header.Author.Name,
146+ header.Author.Email,
147+ header.Title,
148+ header.Body,
149+ header.SHA,
150+ header.CommitterDate,
151+ buf.String(),
152+ )
153+ try(sesh, err)
154+
155+ wish.Printf(
156+ sesh,
157+ "Create Patch Request!\nID: %d\nTitle: %s\n",
158+ prID,
159+ prName,
160+ )
161+ }
162
163 return
164 } else {
+10,
-29
1@@ -1,37 +1,16 @@
2 package git
3
4 import (
5- "database/sql"
6 "time"
7 )
8
9-// User is the entity repesenting a pubkey authenticated user
10-// A user and a single ssh key-pair are synonymous in this context
11-type User struct {
12- ID int64 `db:"id"`
13- Name string `db:"name"`
14- Pubkey string `db:"pubkey"`
15- CreatedAt time.Time `db:"created_at"`
16- UpdatedAt time.Time `db:"updated_at"`
17-}
18-
19-// Repo is a database model for a repository.
20-type Repo struct {
21- ID int64 `db:"id"`
22- Name string `db:"name"`
23- Description string `db:"description"`
24- Private bool `db:"private"`
25- UserID sql.NullInt64 `db:"user_id"`
26- CreatedAt time.Time `db:"created_at"`
27- UpdatedAt time.Time `db:"updated_at"`
28-}
29-
30 // PatchRequest is a database model for patches submitted to a Repo
31 type PatchRequest struct {
32 ID int64 `db:"id"`
33- UserID int64 `db:"user_id"`
34+ Pubkey string `db:"pubkey"`
35 RepoID int64 `db:"repo_id"`
36 Name string `db:"name"`
37+ Text string `db:"text"`
38 CreatedAt time.Time `db:"created_at"`
39 UpdatedAt time.Time `db:"updated_at"`
40 }
41@@ -40,13 +19,15 @@ type PatchRequest struct {
42 // This usually corresponds to a git commit.
43 type Patch struct {
44 ID int64 `db:"id"`
45- UserID int64 `db:"user_id"`
46+ Pubkey string `db:"pubkey"`
47 PatchRequestID int64 `db:"patch_request_id"`
48- FromName string `db:"from_name"`
49- FromEmail string `db:"from_email"`
50- Subject string `db:"subject"`
51- Text string `db:"text"`
52- Date time.Time `db:"date"`
53+ AuthorName string `db:"author_name"`
54+ AuthorEmail string `db:"author_email"`
55+ Title string `db:"title"`
56+ Body string `db:"body"`
57+ CommitSha string `db:"commit_sha"`
58+ CommitDate time.Time `db:"commit_date"`
59+ RawText string `db:"raw_text"`
60 CreatedAt time.Time `db:"created_at"`
61 }
62
M
ssh.go
+1,
-1
1@@ -34,7 +34,7 @@ func GitSshServer() {
2 cfg := NewGitCfg()
3 logger := slog.Default()
4 handler := NewUploadHandler(cfg, logger)
5- dbh, err := Open(":memory", logger)
6+ dbh, err := Open(":memory:", logger)
7 if err != nil {
8 panic(err)
9 }