routes, templates: tree and log views

This commit is contained in:
Anirudh Oppiliappan 2022-12-11 21:17:04 +05:30
parent e0f34796a3
commit ce71721c6d
No known key found for this signature in database
GPG key ID: 8A93F96F78C5D4C4
6 changed files with 110 additions and 37 deletions

View file

@ -11,5 +11,6 @@ func Handlers(c *config.Config) *flow.Mux {
mux.HandleFunc("/:name", d.RepoIndex, "GET") mux.HandleFunc("/:name", d.RepoIndex, "GET")
mux.HandleFunc("/:name/tree/:ref/...", d.RepoTree, "GET") mux.HandleFunc("/:name/tree/:ref/...", d.RepoTree, "GET")
mux.HandleFunc("/:name/blob/:ref/...", d.FileContent, "GET") mux.HandleFunc("/:name/blob/:ref/...", d.FileContent, "GET")
mux.HandleFunc("/:name/log/:ref", d.Log, "GET")
return mux return mux
} }

View file

@ -1,13 +1,12 @@
package routes package routes
import ( import (
"html/template"
"log" "log"
"net/http" "net/http"
"path/filepath" "path/filepath"
"github.com/alexedwards/flow" "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/config"
"icyphox.sh/legit/git" "icyphox.sh/legit/git"
) )
@ -21,27 +20,25 @@ func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request) {
name = filepath.Clean(name) name = filepath.Clean(name)
// TODO: remove .git // TODO: remove .git
path := filepath.Join(d.c.Git.ScanPath, name+".git") path := filepath.Join(d.c.Git.ScanPath, name+".git")
repo, err := gogit.PlainOpen(path) gr, err := git.Open(path, "")
if err != nil { if err != nil {
Write404(w, *d.c) Write404(w, *d.c)
return return
} }
head, err := repo.Head() files, err := gr.FileTree("")
if err != nil { if err != nil {
Write500(w, *d.c) Write500(w, *d.c)
log.Println(err) log.Println(err)
return return
} }
files, err := git.FilesAtRef(repo, head.Hash(), "") data := make(map[string]any)
if err != nil { data["name"] = name
Write500(w, *d.c) // TODO: make this configurable
log.Println(err) data["ref"] = "master"
return
}
d.listFiles(files, w) d.listFiles(files, data, w)
return return
} }
@ -53,27 +50,25 @@ func (d *deps) RepoTree(w http.ResponseWriter, r *http.Request) {
name = filepath.Clean(name) name = filepath.Clean(name)
// TODO: remove .git // TODO: remove .git
path := filepath.Join(d.c.Git.ScanPath, name+".git") path := filepath.Join(d.c.Git.ScanPath, name+".git")
repo, err := gogit.PlainOpen(path) gr, err := git.Open(path, ref)
if err != nil { if err != nil {
Write404(w, *d.c) Write404(w, *d.c)
return return
} }
hash, err := repo.ResolveRevision(plumbing.Revision(ref)) files, err := gr.FileTree(treePath)
if err != nil { if err != nil {
Write500(w, *d.c) Write500(w, *d.c)
log.Println(err) log.Println(err)
return return
} }
files, err := git.FilesAtRef(repo, *hash, treePath) data := make(map[string]any)
if err != nil { data["name"] = name
Write500(w, *d.c) data["ref"] = ref
log.Println(err) data["parent"] = treePath
return
}
d.listFiles(files, w) d.listFiles(files, data, w)
return return
} }
@ -85,20 +80,50 @@ func (d *deps) FileContent(w http.ResponseWriter, r *http.Request) {
name = filepath.Clean(name) name = filepath.Clean(name)
// TODO: remove .git // TODO: remove .git
path := filepath.Join(d.c.Git.ScanPath, name+".git") path := filepath.Join(d.c.Git.ScanPath, name+".git")
repo, err := gogit.PlainOpen(path) gr, err := git.Open(path, ref)
if err != nil { if err != nil {
Write404(w, *d.c) Write404(w, *d.c)
return return
} }
hash, err := repo.ResolveRevision(plumbing.Revision(ref)) 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
}
commits, err := gr.Commits()
if err != nil { if err != nil {
Write500(w, *d.c) Write500(w, *d.c)
log.Println(err) log.Println(err)
return return
} }
contents, err := git.FileContentAtRef(repo, *hash, treePath) tpath := filepath.Join(d.c.Template.Dir, "*")
d.showFile(contents, w) 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 return
}
} }

View file

@ -24,31 +24,29 @@ func Write500(w http.ResponseWriter, c config.Config) {
t.Execute(w, nil) 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, "*") tpath := filepath.Join(d.c.Template.Dir, "*")
t := template.Must(template.ParseGlob(tpath)) t := template.Must(template.ParseGlob(tpath))
data := make(map[string]interface{})
data["files"] = files data["files"] = files
data["meta"] = d.c.Meta data["meta"] = d.c.Meta
if err := t.ExecuteTemplate(w, "repo", data); err != nil { if err := t.ExecuteTemplate(w, "repo", data); err != nil {
Write500(w, *d.c)
log.Println(err) log.Println(err)
return 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, "*") tpath := filepath.Join(d.c.Template.Dir, "*")
t := template.Must(template.ParseGlob(tpath)) t := template.Must(template.ParseGlob(tpath))
data := make(map[string]interface{}) // TODO: Process content here.
data["content"] = content data["content"] = content
data["meta"] = d.c.Meta data["meta"] = d.c.Meta
if err := t.ExecuteTemplate(w, "file", data); err != nil { if err := t.ExecuteTemplate(w, "file", data); err != nil {
Write500(w, *d.c)
log.Println(err) log.Println(err)
return return
} }

View file

@ -10,7 +10,7 @@
{{ template "nav" . }} {{ template "nav" . }}
<main> <main>
<pre> <pre>
{{ .content }} {{ .content }}
</pre> </pre>
</main> </main>
</body> </body>

21
templates/log.html Normal file
View file

@ -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>
&mdash; {{ .Author.Name }}</p>
<p><pre>{{ .Message }}</pre></p>
{{ end }}
</main>
</body>
</html>
{{ end }}

View file

@ -9,13 +9,41 @@
<body> <body>
{{ template "nav" . }} {{ template "nav" . }}
<main> <main>
{{ $repo := .name }}
{{ $ref := .ref }}
{{ $parent := .parent }}
<table>
<tr>
<td></td>
<td><a href="../">..</a>
</tr>
{{ range .files }} {{ range .files }}
{{ if .IsFile }} {{ if .IsFile }}
<p>{{ .Mode }} {{ .Name }} {{ .Size }} </p> <tr>
<td><code>{{ .Mode }}</code></td>
<td>
{{ if $parent }}
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a>
{{ else }} {{ else }}
<p>d-------- {{ .Name}}/</p> <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 }}
{{ end }} {{ end }}
</table>
</main> </main>
</body> </body>
</html> </html>