+15
-7
legit/db/init.go
+15
-7
legit/db/init.go
···
17
17
}
18
18
19
19
_, err = db.Exec(`
20
-
create table if not exists public_keys (
21
-
id integer primary key autoincrement,
22
-
did text not null,
23
-
name text not null,
24
-
key text not null,
25
-
unique(did, name, key))
26
-
`)
20
+
create table if not exists public_keys (
21
+
id integer primary key autoincrement,
22
+
did text not null,
23
+
name text not null,
24
+
key text not null,
25
+
unique(did, name, key)
26
+
);
27
+
create table if not exists repos (
28
+
id integer primary key autoincrement,
29
+
did text not null,
30
+
name text not null,
31
+
description text not null,
32
+
unique(did, name)
33
+
)
34
+
`)
27
35
if err != nil {
28
36
return nil, err
29
37
}
+25
legit/db/repo.go
+25
legit/db/repo.go
···
1
+
package db
2
+
3
+
func (d *DB) AddRepo(did string, name string, description string) error {
4
+
_, err := d.db.Exec("insert into repos (did, name, description) values (?, ?, ?)", did, name, description)
5
+
if err != nil {
6
+
return err
7
+
}
8
+
return nil
9
+
}
10
+
11
+
func (d *DB) RemoveRepo(did string) error {
12
+
_, err := d.db.Exec("delete from repos where did = ?", did)
13
+
if err != nil {
14
+
return err
15
+
}
16
+
return nil
17
+
}
18
+
19
+
func (d *DB) UpdateRepo(did string, name string, description string) error {
20
+
_, err := d.db.Exec("update repos set name = ?, description = ? where did = ?", name, description, did)
21
+
if err != nil {
22
+
return err
23
+
}
24
+
return nil
25
+
}
+33
legit/git/repo.go
+33
legit/git/repo.go
···
1
+
package git
2
+
3
+
import (
4
+
"errors"
5
+
"fmt"
6
+
"os"
7
+
"path/filepath"
8
+
9
+
gogit "github.com/go-git/go-git/v5"
10
+
"github.com/go-git/go-git/v5/config"
11
+
)
12
+
13
+
func InitBare(path string) error {
14
+
parent := filepath.Dir(path)
15
+
16
+
if err := os.MkdirAll(parent, 0755); errors.Is(err, os.ErrExist) {
17
+
return fmt.Errorf("error creating user directory: %w", err)
18
+
}
19
+
20
+
repository, err := gogit.PlainInit(path, true)
21
+
if err != nil {
22
+
return err
23
+
}
24
+
25
+
err = repository.CreateBranch(&config.Branch{
26
+
Name: "main",
27
+
})
28
+
if err != nil {
29
+
return fmt.Errorf("creating branch: %w", err)
30
+
}
31
+
32
+
return nil
33
+
}
+5
legit/routes/handler.go
+5
legit/routes/handler.go
···
51
51
r.Get("/login", h.Login)
52
52
r.Get("/static/{file}", h.ServeStatic)
53
53
54
+
r.Route("/repo", func(r chi.Router) {
55
+
r.Get("/new", h.NewRepo)
56
+
r.Put("/new", h.NewRepo)
57
+
})
58
+
54
59
r.Route("/settings", func(r chi.Router) {
55
60
r.Get("/keys", h.Keys)
56
61
r.Put("/keys", h.Keys)
+39
-4
legit/routes/routes.go
+39
-4
legit/routes/routes.go
···
2
2
3
3
import (
4
4
"compress/gzip"
5
+
"errors"
5
6
"fmt"
6
7
"html/template"
7
8
"log"
···
15
16
16
17
"github.com/dustin/go-humanize"
17
18
"github.com/go-chi/chi/v5"
19
+
"github.com/go-git/go-git/v5/plumbing"
18
20
"github.com/icyphox/bild/legit/config"
19
21
"github.com/icyphox/bild/legit/db"
20
22
"github.com/icyphox/bild/legit/git"
···
100
102
fmt.Println(path)
101
103
gr, err := git.Open(path, "")
102
104
if err != nil {
103
-
h.Write404(w)
104
-
return
105
+
if errors.Is(err, plumbing.ErrReferenceNotFound) {
106
+
h.t.ExecuteTemplate(w, "empty", nil)
107
+
return
108
+
} else {
109
+
h.Write404(w)
110
+
return
111
+
}
105
112
}
106
113
commits, err := gr.Commits()
107
114
if err != nil {
···
436
443
}
437
444
438
445
func (h *Handle) Keys(w http.ResponseWriter, r *http.Request) {
439
-
440
446
switch r.Method {
441
447
case http.MethodGet:
442
448
// TODO: fetch keys from db
···
457
463
458
464
// TODO: add did here
459
465
if err := h.db.AddPublicKey("did:ashtntnashtx", name, key); err != nil {
460
-
h.WriteOOBNotice(w, "keys", "Failed to add key")
466
+
h.WriteOOBNotice(w, "keys", "Failed to add key.")
461
467
log.Printf("adding public key: %s", err)
462
468
return
463
469
}
···
466
472
return
467
473
}
468
474
}
475
+
476
+
func (h *Handle) NewRepo(w http.ResponseWriter, r *http.Request) {
477
+
switch r.Method {
478
+
case http.MethodGet:
479
+
if err := h.t.ExecuteTemplate(w, "new", nil); err != nil {
480
+
log.Println(err)
481
+
return
482
+
}
483
+
case http.MethodPut:
484
+
name := r.FormValue("name")
485
+
description := r.FormValue("description")
486
+
487
+
// TODO: Get handle from session. We need this to construct the repository path.
488
+
err := git.InitBare(filepath.Join(h.c.Repo.ScanPath, "example.com", name))
489
+
if err != nil {
490
+
h.WriteOOBNotice(w, "repo", "Error creating repo. Try again later.")
491
+
return
492
+
}
493
+
494
+
err = h.db.AddRepo("did:ashtntnashtx", name, description)
495
+
if err != nil {
496
+
h.WriteOOBNotice(w, "repo", "Error creating repo. Try again later.")
497
+
return
498
+
}
499
+
500
+
w.Header().Set("HX-Redirect", fmt.Sprintf("/@example.com/%s", name))
501
+
w.WriteHeader(http.StatusOK)
502
+
}
503
+
}
+1
-1
legit/routes/util.go
+1
-1
legit/routes/util.go
+11
legit/templates/empty.html
+11
legit/templates/empty.html
+32
legit/templates/new.html
+32
legit/templates/new.html
···
1
+
{{ define "new" }}
2
+
<html>
3
+
{{ template "head" . }}
4
+
5
+
<body>
6
+
<main>
7
+
<h1>create a new repository</h1>
8
+
<form>
9
+
<p>
10
+
Give your Git repository a name and, optionally, a
11
+
description.
12
+
</p>
13
+
<div id="repo"></div>
14
+
<div>
15
+
<label for="name">Name</label>
16
+
<input type="text" id="name" name="name" placeholder="" />
17
+
<label for="description">Description</label>
18
+
<input
19
+
type="text"
20
+
id="description"
21
+
name="description"
22
+
placeholder=""
23
+
/>
24
+
</div>
25
+
<button hx-put="/repo/new" hx-swap="none" type="submit">
26
+
Submit
27
+
</button>
28
+
</form>
29
+
</main>
30
+
</body>
31
+
</html>
32
+
{{ end }}