all repos — legit @ 7d3fed52adb19e535569da2720969eb8b15ee378

legit - simple git web interface in go (fork)

add raw file routes and allow readme to reference relative repo paths
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmPZo9oACgkQO3+8IhRO
Y5jW/Q/+M740eWMsKRYBaHdtRSzgCYPYG9wpTc3CklDIVpKhsXLy3vNpJlIjmXrb
CPA7U3wlWVYXe5jPeeDCME21++98HsEULgldZI2HMWFN7jy+x9S4mEjkrkJHDnFc
pJL5LqlKayIxsH150bHoUKKFQ8xk6DlbYSgoNqk/wCWz7EADnRsREJh2ZFTRLd3K
nVb1G8ZS/yTeeXA7acz1mhwgUlIKy1TrsDLbnPHzwJW7ipJyB2wykl6kC477z5lt
buWJmbG4jdFZqr3pVXf7h0VUasTet5e2RTNqLupIP/O6hv6g2jfQKFRTwzhYFJ3n
Pmu1UdF2+MKP8AnDnvy8nHE8PG0GQM5RdfDVu2pqxy8dE7FuEt1RMGve16oDVfgE
rFaO9RpWBqlqS5rBWwd5hCcj7cuRUPFE7RrPHKysaHyJjoKjw7CGEBQNDPtj4tZI
Nm0tQ4hP7VlmBsT7IcktKXRt+LHblhglKElgVdmJNw0gjlJPrz88cBhleuBK6ZYq
g9omxttBMidvUQawYtAzSva8hhiQV+A/FbNbSDL9/LunVqDdHs1R4p3xT8MYmZPv
yJS+RSS+dPObkzMTXHgjv9alTvgk3nbY3TzyyLZx035HlkXFu+aOUyNmF+76GLsh
2korFNOf/J5phEgcv1O55pyb8ZaCatM6/u8eHHQUuoVaEwT8qAM=
=rJ6S
-----END PGP SIGNATURE-----
commit

7d3fed52adb19e535569da2720969eb8b15ee378

parent

9bb6fb2afc0e1b7c2d6728543a0d9f020416c3ad

6 files changed, 47 insertions(+), 14 deletions(-)

jump to
M git/git.gogit/git.go

@@ -60,7 +60,7 @@ }

return c, nil } -func (g *GitRepo) FileContent(path string) (string, error) { +func (g *GitRepo) FileContent(path string, showBinary bool) (string, error) { c, err := g.r.CommitObject(g.h) if err != nil { return "", fmt.Errorf("commit object: %w", err)

@@ -78,7 +78,7 @@ }

isbin, _ := file.IsBinary() - if !isbin { + if showBinary || !isbin { return file.Contents() } else { return "Not displaying binary file", nil
M routes/handler.goroutes/handler.go

@@ -41,6 +41,7 @@ mux.HandleFunc("/", d.Index, "GET")

mux.HandleFunc("/static/:file", d.ServeStatic, "GET") mux.HandleFunc("/:name", d.Multiplex, "GET", "POST") mux.HandleFunc("/:name/tree/:ref/...", d.RepoTree, "GET") + mux.HandleFunc("/:name/blob/raw/:ref/...", d.ServeStaticInRepo, "GET") mux.HandleFunc("/:name/blob/:ref/...", d.FileContent, "GET") mux.HandleFunc("/:name/log/:ref", d.Log, "GET") mux.HandleFunc("/:name/commit/:ref", d.Diff, "GET")
M routes/routes.goroutes/routes.go

@@ -1,6 +1,7 @@

package routes import ( + "bytes" "fmt" "html/template" "log"

@@ -97,6 +98,13 @@ d.Write404(w)

return } + mainBranch, err := gr.FindMainBranch(d.c.Repo.MainBranch) + if err != nil { + d.Write500(w) + log.Println(err) + return + } + commits, err := gr.Commits() if err != nil { d.Write500(w)

@@ -107,7 +115,7 @@

var readmeContent template.HTML for _, readme := range d.c.Repo.Readme { ext := filepath.Ext(readme) - content, _ := gr.FileContent(readme) + content, _ := gr.FileContent(readme, false) if len(content) > 0 { switch ext { case ".md", ".mkd", ".markdown":

@@ -116,7 +124,7 @@ []byte(content),

blackfriday.WithExtensions(blackfriday.CommonExtensions), ) html := bluemonday.UGCPolicy().SanitizeBytes(unsafe) - readmeContent = template.HTML(html) + readmeContent = template.HTML(transformRelativeURLs(string(html), name, mainBranch)) default: readmeContent = template.HTML( fmt.Sprintf(`<pre>%s</pre>`, content),

@@ -128,13 +136,6 @@ }

if readmeContent == "" { log.Printf("no readme found for %s", name) - } - - mainBranch, err := gr.FindMainBranch(d.c.Repo.MainBranch) - if err != nil { - d.Write500(w) - log.Println(err) - return } tpath := filepath.Join(d.c.Dirs.Templates, "*")

@@ -212,12 +213,13 @@ d.Write404(w)

return } - contents, err := gr.FileContent(treePath) + contents, err := gr.FileContent(treePath, false) data := make(map[string]any) data["name"] = name data["ref"] = ref data["desc"] = getDescription(path) data["path"] = treePath + data["raw"] = fmt.Sprintf("/%s/blob/raw/%s/%s", name, ref, treePath) d.showFile(contents, data, w) return

@@ -344,6 +346,26 @@ if err := t.ExecuteTemplate(w, "refs", data); err != nil {

log.Println(err) return } +} + +func (d *deps) ServeStaticInRepo(w http.ResponseWriter, r *http.Request) { + f := flow.Param(r.Context(), "...") + p := flow.Param(r.Context(), "name") + ref := flow.Param(r.Context(), "ref") + + repoPath := filepath.Clean(filepath.Join(d.c.Repo.ScanPath, p)) + gr, err := git.Open(repoPath, ref) + if err != nil { + d.Write500(w) + return + } + + contents, err := gr.FileContent(f, true) + if err != nil { + d.Write500(w) + return + } + http.ServeContent(w, r, filepath.Base(f), time.Unix(0, 0), bytes.NewReader([]byte(contents))) } func (d *deps) ServeStatic(w http.ResponseWriter, r *http.Request) {
M routes/util.goroutes/util.go

@@ -1,14 +1,16 @@

package routes import ( + "fmt" "os" "path/filepath" + "strings" "git.icyphox.sh/legit/git" ) func isGoModule(gr *git.GitRepo) bool { - _, err := gr.FileContent("go.mod") + _, err := gr.FileContent("go.mod", false) return err == nil }

@@ -20,6 +22,13 @@ } else {

desc = "" } return +} + +func transformRelativeURLs(html, repoName, mainBranch string) string { + return strings.ReplaceAll( + html, + "=\"./", + fmt.Sprintf("=\"/%s/blob/raw/%s/", repoName, mainBranch)) } func (d *deps) isIgnored(name string) bool {
M static/style.cssstatic/style.css

@@ -247,6 +247,7 @@ grid-template-columns: 1rem minmax(0, 1fr);

gap: 1rem; padding: 0.5rem; background: var(--light-gray); + margin-top: 0.5rem; } .file-content {
M templates/file.htmltemplates/file.html

@@ -7,7 +7,7 @@ {{ template "repoheader" . }}

<body> {{ template "nav" . }} <main> - <p>{{ .path }}</p> + <p>{{ .path }} (<a href="{{ .raw }}">raw</a>)</p> <div class="file-wrapper"> <div class="line-numbers"> {{- range .linecount }}