routes, templates: tree and log views
Anirudh Oppiliappan x@icyphox.sh
Sun, 11 Dec 2022 21:17:04 +0530
6 files changed,
110 insertions(+),
37 deletions(-)
M
routes/handler.go
→
routes/handler.go
@@ -11,5 +11,6 @@ d := deps{c}
mux.HandleFunc("/:name", d.RepoIndex, "GET") mux.HandleFunc("/:name/tree/:ref/...", d.RepoTree, "GET") mux.HandleFunc("/:name/blob/:ref/...", d.FileContent, "GET") + mux.HandleFunc("/:name/log/:ref", d.Log, "GET") return mux }
M
routes/routes.go
→
routes/routes.go
@@ -1,13 +1,12 @@
package routes import ( + "html/template" "log" "net/http" "path/filepath" "github.com/alexedwards/flow" - gogit "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" "icyphox.sh/legit/config" "icyphox.sh/legit/git" )@@ -21,27 +20,25 @@ name := flow.Param(r.Context(), "name")
name = filepath.Clean(name) // TODO: remove .git path := filepath.Join(d.c.Git.ScanPath, name+".git") - repo, err := gogit.PlainOpen(path) + gr, err := git.Open(path, "") if err != nil { Write404(w, *d.c) return } - head, err := repo.Head() + files, err := gr.FileTree("") if err != nil { Write500(w, *d.c) log.Println(err) return } - files, err := git.FilesAtRef(repo, head.Hash(), "") - if err != nil { - Write500(w, *d.c) - log.Println(err) - return - } + data := make(map[string]any) + data["name"] = name + // TODO: make this configurable + data["ref"] = "master" - d.listFiles(files, w) + d.listFiles(files, data, w) return }@@ -53,27 +50,25 @@
name = filepath.Clean(name) // TODO: remove .git path := filepath.Join(d.c.Git.ScanPath, name+".git") - repo, err := gogit.PlainOpen(path) + gr, err := git.Open(path, ref) if err != nil { Write404(w, *d.c) return } - hash, err := repo.ResolveRevision(plumbing.Revision(ref)) + files, err := gr.FileTree(treePath) if err != nil { Write500(w, *d.c) log.Println(err) return } - files, err := git.FilesAtRef(repo, *hash, treePath) - if err != nil { - Write500(w, *d.c) - log.Println(err) - return - } + data := make(map[string]any) + data["name"] = name + data["ref"] = ref + data["parent"] = treePath - d.listFiles(files, w) + d.listFiles(files, data, w) return }@@ -85,20 +80,50 @@
name = filepath.Clean(name) // TODO: remove .git path := filepath.Join(d.c.Git.ScanPath, name+".git") - repo, err := gogit.PlainOpen(path) + gr, err := git.Open(path, ref) + if err != nil { + Write404(w, *d.c) + return + } + + contents, err := gr.FileContent(treePath) + data := make(map[string]any) + data["name"] = name + data["ref"] = ref + + d.showFile(contents, data, w) + return +} + +func (d *deps) Log(w http.ResponseWriter, r *http.Request) { + name := flow.Param(r.Context(), "name") + ref := flow.Param(r.Context(), "ref") + + path := filepath.Join(d.c.Git.ScanPath, name+".git") + gr, err := git.Open(path, ref) if err != nil { Write404(w, *d.c) return } - hash, err := repo.ResolveRevision(plumbing.Revision(ref)) + commits, err := gr.Commits() if err != nil { Write500(w, *d.c) log.Println(err) return } - contents, err := git.FileContentAtRef(repo, *hash, treePath) - d.showFile(contents, w) - return + tpath := filepath.Join(d.c.Template.Dir, "*") + t := template.Must(template.ParseGlob(tpath)) + + data := make(map[string]interface{}) + data["commits"] = commits + data["meta"] = d.c.Meta + data["name"] = name + data["ref"] = ref + + if err := t.ExecuteTemplate(w, "log", data); err != nil { + log.Println(err) + return + } }
M
routes/template.go
→
routes/template.go
@@ -24,31 +24,29 @@ t := template.Must(template.ParseFiles(tpath))
t.Execute(w, nil) } -func (d *deps) listFiles(files []git.NiceTree, w http.ResponseWriter) { +func (d *deps) listFiles(files []git.NiceTree, data map[string]any, w http.ResponseWriter) { tpath := filepath.Join(d.c.Template.Dir, "*") t := template.Must(template.ParseGlob(tpath)) - data := make(map[string]interface{}) data["files"] = files data["meta"] = d.c.Meta if err := t.ExecuteTemplate(w, "repo", data); err != nil { - Write500(w, *d.c) log.Println(err) return } } -func (d *deps) showFile(content string, w http.ResponseWriter) { +func (d *deps) showFile(content string, data map[string]any, w http.ResponseWriter) { tpath := filepath.Join(d.c.Template.Dir, "*") t := template.Must(template.ParseGlob(tpath)) - data := make(map[string]interface{}) + // TODO: Process content here. + data["content"] = content data["meta"] = d.c.Meta if err := t.ExecuteTemplate(w, "file", data); err != nil { - Write500(w, *d.c) log.Println(err) return }
M
templates/file.html
→
templates/file.html
@@ -10,7 +10,7 @@ <body>
{{ template "nav" . }} <main> <pre> - {{ .content }} +{{ .content }} </pre> </main> </body>
A
templates/log.html
@@ -0,0 +1,21 @@
+{{ define "log" }} +<html> +{{ template "head" . }} + + <header> + <h1>{{ .meta.Title }}</h1> + <h2>{{ .meta.Description }}</h2> + </header> + <body> + {{ template "nav" . }} + <main> + {{ $repo := .name }} + {{ range .commits }} + <p><a href="/{{ $repo }}/commit/{{ .Hash.String }}">{{ slice .Hash.String 0 8 }}<a> + — {{ .Author.Name }}</p> + <p><pre>{{ .Message }}</pre></p> + {{ end }} + </main> + </body> +</html> +{{ end }}
M
templates/repo.html
→
templates/repo.html
@@ -9,13 +9,41 @@ </header>
<body> {{ template "nav" . }} <main> + {{ $repo := .name }} + {{ $ref := .ref }} + {{ $parent := .parent }} + + <table> + <tr> + <td></td> + <td><a href="../">..</a> + </tr> {{ range .files }} - {{ if .IsFile }} - <p>{{ .Mode }} {{ .Name }} {{ .Size }} </p> - {{ else }} - <p>d-------- {{ .Name}}/</p> - {{ end }} + {{ if .IsFile }} + <tr> + <td><code>{{ .Mode }}</code></td> + <td> + {{ if $parent }} + <a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a> + {{ else }} + <a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a> + {{ end }} + </td> + </tr> + {{ else }} + <tr> + <td><code>{{ .Mode }}</code></td> + <td> + {{ if $parent }} + <a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a> + {{ else }} + <a href="{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a> + {{ end }} + </td> + </tr> + {{ end }} {{ end }} + </table> </main> </body> </html>