Changes
31 changed files (+1040/-993)
-
-
@@ -9,36 +9,16 @@ "github.com/bluekeyes/go-gitdiff/gitdiff""github.com/go-git/go-git/v5/plumbing/object" ) type TextFragment struct { Header string Lines []gitdiff.Line } type Diff struct { Name struct { Old string New string } TextFragments []TextFragment IsBinary bool IsNew bool IsDelete bool } // A nicer git diff representation. type NiceDiff struct { Commit struct { Message string Author object.Signature This string Parent string } Commit *object.Commit Parent *object.Commit Stat struct { FilesChanged int Insertions int Deletions int } Diff []Diff Files []*gitdiff.File } func (g *GitRepo) Diff() (*NiceDiff, error) {
-
@@ -77,29 +57,12 @@ log.Println(err)} nd := NiceDiff{} nd.Commit.This = c.Hash.String() if parent.Hash.IsZero() { nd.Commit.Parent = "" } else { nd.Commit.Parent = parent.Hash.String() } nd.Commit.Author = c.Author nd.Commit.Message = c.Message nd.Commit = c nd.Parent = parent nd.Files = diffs for _, d := range diffs { ndiff := Diff{} ndiff.Name.New = d.NewName ndiff.Name.Old = d.OldName ndiff.IsBinary = d.IsBinary ndiff.IsNew = d.IsNew ndiff.IsDelete = d.IsDelete for _, tf := range d.TextFragments { ndiff.TextFragments = append(ndiff.TextFragments, TextFragment{ Header: tf.Header(), Lines: tf.Lines, }) for _, l := range tf.Lines { switch l.Op { case gitdiff.OpAdd:
-
@@ -109,8 +72,6 @@ nd.Stat.Deletions += 1} } } nd.Diff = append(nd.Diff, ndiff) } nd.Stat.FilesChanged = len(diffs)
-
-
-
@@ -19,6 +19,8 @@INSTALLING This application requires Go >= v1.24.1. Clone it, 'go build' it.
-
-
routes/data.go (new)
-
@@ -0,0 +1,160 @@// This file defines the data passed to templates. // // Copyright 2025 Shota FUJI <pockawoooh@gmail.com> // SPDX-License-Identifier: MIT package routes import ( "html/template" "git.icyphox.sh/legit/config" "git.icyphox.sh/legit/git" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" ) // repositorySummary contains overview of a git repository. type repositorySummary struct { // DisplayName is a directory name without ".git" suffix. DisplayName string // DirName is a directory name of the repository. DirName string // Description is a contents of "description" text file in the repository root. Description string // LastCommitAtRelative is a relative datetime string of last commit. // For example, "1 hour ago" or "2 years ago". LastCommitAtRelative string LastCommit *object.Commit } // repoListData is a data object passed to "repo-list" template. type repoListData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config // Repositories is a slice of every repositories legit sees. Repositories []repositorySummary } // repositoryMeta is a shared data object passed to every pages under each repositories. type repositoryMeta struct { // DisplayName is a directory name without ".git" suffix. DisplayName string // DirName is a directory name of the repository. DirName string // Description is a contents of "description" text file in the repository root. Description string // Ref is a ref for the current context. If a page is not tied to refs, default branch // will be set. Ref string } // repoTopData is a data object passed to "repo-top" template. type repoTopData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config Meta repositoryMeta // Rendered README. Readme template.HTML // DefaultBranch is textual representation of repository's default branch. DefaultBranch string // RecentCommits is a list of recent commits made in the default branch. RecentCommits []*object.Commit // Whether this repository is available as Go Module. IsGoModule bool } // repoRefsData is a data object passed to "repo-refs" template. type repoRefsData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config Meta repositoryMeta // Tags is a list of git tags (annotate and lightweight) in the repository. Tags []*git.TagReference Branches []*plumbing.Reference } // repoTreeRefData is a data object passed to "repo-tree-ref" template. type repoTreeRefData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config Meta repositoryMeta // Path to the current directory. On repository root, this is empty slice. Path []string // Files is a list of files for the current directory. Files []git.NiceTree } // repoBlobRefData is a data object passed to "repo-blob-ref" template. type repoBlobRefData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config Meta repositoryMeta // Path to the blob. Path []string // Content of the blob. Content string SyntaxHighlightedContent template.HTML // LineNumbers holds sequential numbers starting from 1 up to line count of the blob. LineNumbers []uint } // repoLogRefData is a data object passed to "repo-log-ref" template. type repoLogRefData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config Meta repositoryMeta // Commits made to the ref. Commits []*object.Commit } // repoCommitData is a data object passed to "repo-commit" template. type repoCommitData struct { // Config represents a resolved config based on "config.yaml". Config *config.Config Meta repositoryMeta Commit *object.Commit Parent *object.Commit Diff *git.NiceDiff } // error404Data is a data object passed to "404" template. type error404Data struct { // Config represents a resolved config based on "config.yaml". Config *config.Config } // error500Data is a data object passed to "500" template. type error500Data struct { // Config represents a resolved config based on "config.yaml". Config *config.Config }
-
-
-
@@ -11,7 +11,6 @@ "path/filepath""sort" "strconv" "strings" "time" "git.icyphox.sh/legit/config" "git.icyphox.sh/legit/git"
-
@@ -33,20 +32,7 @@ log.Printf("reading scan path: %s", err)return } type info struct { DisplayName, Name, Desc, Idle string // UpdatedAt is a formatted datetime of the repository's last commit. UpdatedAt string // UpdatedAtRaw is RFC3339 formatted datetime of the repository's last commit. UpdatedAtRaw string // d holds last update time same to UpdatedAt, for sorting purpose. d time.Time } infos := []info{} summaries := []repositorySummary{} for _, dir := range dirs { name := dir.Name()
-
@@ -74,29 +60,28 @@ log.Println(err)return } infos = append(infos, info{ DisplayName: getDisplayName(name), Name: name, Desc: getDescription(path), Idle: humanize.Time(c.Author.When), UpdatedAt: c.Author.When.Format(time.DateTime), UpdatedAtRaw: c.Author.When.Format(time.RFC3339), d: c.Author.When, summaries = append(summaries, repositorySummary{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), LastCommitAtRelative: humanize.Time(c.Author.When), LastCommit: c, }) } sort.Slice(infos, func(i, j int) bool { return infos[j].d.Before(infos[i].d) sort.Slice(summaries, func(i, j int) bool { return summaries[j].LastCommit.Author.When.Before(summaries[i].LastCommit.Author.When) }) tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) data := make(map[string]interface{}) data["meta"] = d.c.Meta data["info"] = infos data := repoListData{ Config: d.c, Repositories: summaries, } if err := t.ExecuteTemplate(w, "index", data); err != nil { if err := t.ExecuteTemplate(w, "repo-list", data); err != nil { log.Println(err) return }
-
@@ -170,18 +155,21 @@ if len(commits) >= 3 {commits = commits[:3] } data := make(map[string]any) data["name"] = name data["displayname"] = getDisplayName(name) data["ref"] = mainBranch data["readme"] = readmeContent data["commits"] = commits data["desc"] = getDescription(path) data["servername"] = d.c.Server.Name data["meta"] = d.c.Meta data["gomod"] = isGoModule(gr) data := repoTopData{ Config: d.c, Meta: repositoryMeta{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), Ref: mainBranch, }, Readme: readmeContent, DefaultBranch: mainBranch, RecentCommits: commits, IsGoModule: isGoModule(gr), } if err := t.ExecuteTemplate(w, "repo", data); err != nil { if err := t.ExecuteTemplate(w, "repo-top", data); err != nil { log.Println(err) return }
-
@@ -218,15 +206,31 @@ log.Println(err)return } data := make(map[string]any) data["name"] = name data["displayname"] = getDisplayName(name) data["ref"] = ref data["parent"] = treePath data["desc"] = getDescription(path) data["dotdot"] = filepath.Dir(treePath) relpath := []string{} if len(treePath) > 0 { relpath = strings.Split(treePath, "/") } data := repoTreeRefData{ Config: d.c, Meta: repositoryMeta{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), Ref: ref, }, Path: relpath, Files: files, } tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) if err := t.ExecuteTemplate(w, "repo-tree-ref", data); err != nil { log.Println(err) return } d.listFiles(files, data, w) return }
-
@@ -263,22 +267,66 @@ if err != nil {d.Write500(w) return } data := make(map[string]any) data["name"] = name data["displayname"] = getDisplayName(name) data["ref"] = ref data["desc"] = getDescription(path) data["path"] = treePath if raw { d.showRaw(contents, w) } else { if d.c.Meta.SyntaxHighlight == "" { d.showFile(contents, data, w) w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "text/plain") w.Write([]byte(contents)) return } lc, err := countLines(strings.NewReader(contents)) if err != nil { log.Printf("Failed to count lines for %s: %s", r.URL.Path, err) d.Write500(w) return } lines := make([]uint, lc) for i := range lines { if i < 0 { continue } lines[i] = uint(i + 1) } relpath := []string{} if len(treePath) > 0 { relpath = strings.Split(treePath, "/") } data := repoBlobRefData{ Config: d.c, Meta: repositoryMeta{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), Ref: ref, }, Path: relpath, Content: contents, LineNumbers: lines, } if d.c.Meta.SyntaxHighlight != "" { highlighted, err := highlightCode(treePath, contents, d.c.Meta.SyntaxHighlight) if err != nil { log.Println(err) } else { d.showFileWithHighlight(treePath, contents, data, w) data.SyntaxHighlightedContent = highlighted } } tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) if err := t.ExecuteTemplate(w, "repo-blob-ref", data); err != nil { log.Println(err) return } return } func (d *deps) Archive(w http.ResponseWriter, r *http.Request) {
-
@@ -369,16 +417,18 @@tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) data := make(map[string]interface{}) data["commits"] = commits data["meta"] = d.c.Meta data["name"] = name data["displayname"] = getDisplayName(name) data["ref"] = ref data["desc"] = getDescription(path) data["log"] = true data := repoLogRefData{ Config: d.c, Meta: repositoryMeta{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), Ref: ref, }, Commits: commits, } if err := t.ExecuteTemplate(w, "log", data); err != nil { if err := t.ExecuteTemplate(w, "repo-log-ref", data); err != nil { log.Println(err) return }
-
@@ -414,18 +464,20 @@tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) data := make(map[string]interface{}) data := repoCommitData{ Config: d.c, Meta: repositoryMeta{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), Ref: diff.Commit.Hash.String(), }, Commit: diff.Commit, Parent: diff.Parent, Diff: diff, } data["commit"] = diff.Commit data["stat"] = diff.Stat data["diff"] = diff.Diff data["meta"] = d.c.Meta data["name"] = name data["displayname"] = getDisplayName(name) data["ref"] = ref data["desc"] = getDescription(path) if err := t.ExecuteTemplate(w, "commit", data); err != nil { if err := t.ExecuteTemplate(w, "repo-commit", data); err != nil { log.Println(err) return }
-
@@ -464,19 +516,29 @@ d.Write500(w)return } 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, "*") t := template.Must(template.ParseGlob(tpath)) data := make(map[string]interface{}) data["meta"] = d.c.Meta data["name"] = name data["displayname"] = getDisplayName(name) data["branches"] = branches data["tags"] = tags data["desc"] = getDescription(path) data := repoRefsData{ Config: d.c, Meta: repositoryMeta{ DisplayName: getDisplayName(name), DirName: name, Description: getDescription(path), Ref: mainBranch, }, Tags: tags, Branches: branches, } if err := t.ExecuteTemplate(w, "refs", data); err != nil { if err := t.ExecuteTemplate(w, "repo-refs", data); err != nil { log.Println(err) return }
-
-
-
@@ -1,150 +1,36 @@package routes import ( "bytes" "html/template" "io" "log" "net/http" "path/filepath" "strings" "git.icyphox.sh/legit/git" "github.com/alecthomas/chroma/v2/formatters/html" "github.com/alecthomas/chroma/v2/lexers" "github.com/alecthomas/chroma/v2/styles" ) func (d *deps) Write404(w http.ResponseWriter) { tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) w.WriteHeader(404) if err := t.ExecuteTemplate(w, "404", nil); err != nil { log.Printf("404 template: %s", err) } } func (d *deps) Write500(w http.ResponseWriter) { tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) w.WriteHeader(500) if err := t.ExecuteTemplate(w, "500", nil); err != nil { log.Printf("500 template: %s", err) } } func (d *deps) listFiles(files []git.NiceTree, data map[string]any, w http.ResponseWriter) { tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) data["files"] = files data["meta"] = d.c.Meta if err := t.ExecuteTemplate(w, "tree", data); err != nil { log.Println(err) return } } func countLines(r io.Reader) (int, error) { buf := make([]byte, 32*1024) bufLen := 0 count := 0 nl := []byte{'\n'} for { c, err := r.Read(buf) if c > 0 { bufLen += c } count += bytes.Count(buf[:c], nl) switch { case err == io.EOF: /* handle last line not having a newline at the end */ if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' { count++ } return count, nil case err != nil: return 0, err } } } func (d *deps) showFileWithHighlight(name, content string, data map[string]any, w http.ResponseWriter) { tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) lexer := lexers.Get(name) if lexer == nil { lexer = lexers.Get(".txt") } style := styles.Get(d.c.Meta.SyntaxHighlight) if style == nil { style = styles.Get("monokailight") } formatter := html.New( html.WithLineNumbers(true), html.WithLinkableLineNumbers(true, "L"), ) iterator, err := lexer.Tokenise(nil, content) if err != nil { d.Write500(w) return } var code bytes.Buffer err = formatter.Format(&code, style, iterator) if err != nil { d.Write500(w) return data := error404Data{ Config: d.c, } data["content"] = template.HTML(code.String()) data["meta"] = d.c.Meta data["chroma"] = true if err := t.ExecuteTemplate(w, "file", data); err != nil { log.Println(err) return w.WriteHeader(404) if err := t.ExecuteTemplate(w, "404", data); err != nil { log.Printf("404 template: %s", err) } } func (d *deps) showFile(content string, data map[string]any, w http.ResponseWriter) { func (d *deps) Write500(w http.ResponseWriter) { tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath)) lc, err := countLines(strings.NewReader(content)) if err != nil { // Non-fatal, we'll just skip showing line numbers in the template. log.Printf("counting lines: %s", err) data := error500Data{ Config: d.c, } lines := make([]int, lc) if lc > 0 { for i := range lines { lines[i] = i + 1 } } data["linecount"] = lines data["content"] = content data["meta"] = d.c.Meta data["chroma"] = false if err := t.ExecuteTemplate(w, "file", data); err != nil { log.Println(err) return w.WriteHeader(500) if err := t.ExecuteTemplate(w, "500", data); err != nil { log.Printf("500 template: %s", err) } } func (d *deps) showRaw(content string, w http.ResponseWriter) { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "text/plain") w.Write([]byte(content)) return }
-
-
-
@@ -1,12 +1,20 @@package routes import ( "bytes" "fmt" "html/template" "io" "io/fs" "log" "net/http" "os" "path/filepath" "strings" "github.com/alecthomas/chroma/v2/formatters/html" "github.com/alecthomas/chroma/v2/lexers" "github.com/alecthomas/chroma/v2/styles" "git.icyphox.sh/legit/git" )
-
@@ -116,3 +124,58 @@func setMIME(w http.ResponseWriter, mime string) { w.Header().Add("Content-Type", mime) } func countLines(r io.Reader) (int, error) { buf := make([]byte, 32*1024) bufLen := 0 count := 0 nl := []byte{'\n'} for { c, err := r.Read(buf) if c > 0 { bufLen += c } count += bytes.Count(buf[:c], nl) switch { case err == io.EOF: /* handle last line not having a newline at the end */ if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' { count++ } return count, nil case err != nil: return 0, err } } } func highlightCode(fileName string, code string, styleQuery string) (template.HTML, error) { lexer := lexers.Get(fileName) // Do not process if no appropriate highlighter was found. if lexer == nil { return "", nil } style := styles.Get(styleQuery) if style == nil { return "", fmt.Errorf("No chroma style found for '%s'", styleQuery) } formatter := html.New() iter, err := lexer.Tokenise(nil, code) if err != nil { return "", fmt.Errorf("Failed to tokenize code: %s", err) } var output bytes.Buffer err = formatter.Format(&output, style, iter) if err != nil { return "", fmt.Errorf("Failed to highlight code: %s", err) } return template.HTML(output.String()), nil }
-
-
-
static/style.css (deleted)
-
@@ -1,332 +0,0 @@:root { --white: #fff; --light: #f4f4f4; --cyan: #509c93; --light-gray: #eee; --medium-gray: #ddd; --gray: #6a6a6a; --dark: #444; --darker: #222; --sans-font: -apple-system, BlinkMacSystemFont, "Inter", "Roboto", "Segoe UI", sans-serif; --display-font: -apple-system, BlinkMacSystemFont, "Inter", "Roboto", "Segoe UI", sans-serif; --mono-font: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', 'Roboto Mono', Menlo, Consolas, monospace; } @media (prefers-color-scheme: dark) { :root { color-scheme: dark light; --light: #181818; --cyan: #76c7c0; --light-gray: #333; --medium-gray: #444; --gray: #aaa; --dark: #ddd; --darker: #f4f4f4; --white: #000; } } html { background: var(--white); -webkit-text-size-adjust: none; font-family: var(--sans-font); font-weight: 380; } pre { font-family: var(--mono-font); } ::selection { background: var(--medium-gray); opacity: 0.3; } * { box-sizing: border-box; padding: 0; margin: 0; } body { max-width: 1000px; padding: 0 13px; margin: 40px auto; } main, footer { font-size: 1rem; padding: 0; line-height: 160%; } header h1, h2, h3 { font-family: var(--display-font); } h2 { font-weight: 400; } strong { font-weight: 500; } main h1 { padding: 10px 0 10px 0; } main h2 { font-size: 18px; } main h2, h3 { padding: 20px 0 15px 0; } nav { padding: 0.4rem 0 1.5rem 0; } nav ul { padding: 0; margin: 0; list-style: none; padding-bottom: 20px; } nav ul li { padding-right: 10px; display: inline-block; } a { margin: 0; padding: 0; box-sizing: border-box; text-decoration: none; word-wrap: break-word; } a { color: var(--darker); border-bottom: 1.5px solid var(--medium-gray); } a:hover { border-bottom: 1.5px solid var(--gray); } .index { padding-top: 2em; display: grid; grid-template-columns: 6em 1fr minmax(0, 7em); grid-row-gap: 0.5em; min-width: 0; } .clone-url { padding-top: 2rem; } .clone-url pre { color: var(--dark); white-space: pre-wrap; } .desc { font-weight: normal; color: var(--gray); font-style: italic; } .tree { display: grid; grid-template-columns: 10ch auto 1fr; grid-row-gap: 0.5em; grid-column-gap: 1em; min-width: 0; } .log { display: grid; grid-template-columns: 20rem minmax(0, 1fr); grid-row-gap: 0.8em; grid-column-gap: 8rem; margin-bottom: 2em; padding-bottom: 1em; border-bottom: 1.5px solid var(--medium-gray); } .log pre { white-space: pre-wrap; } .mode, .size { font-family: var(--mono-font); } .size { text-align: right; } .readme pre { white-space: pre-wrap; overflow-x: auto; } .readme { background: var(--light-gray); padding: 0.5rem; } .readme ul { padding: revert; } .readme img { max-width: 100%; } .diff { margin: 1rem 0 1rem 0; padding: 1rem 0 1rem 0; border-bottom: 1.5px solid var(--medium-gray); } .diff pre { overflow: scroll; } .diff-stat { padding: 1rem 0 1rem 0; } .commit-hash, .commit-email { font-family: var(--mono-font); } .commit-email:before { content: '<'; } .commit-email:after { content: '>'; } .commit { margin-bottom: 1rem; } .commit pre { padding-bottom: 1rem; white-space: pre-wrap; } .diff-stat ul li { list-style: none; padding-left: 0.5em; } .diff-add { color: green; } .diff-del { color: red; } .diff-noop { color: var(--gray); } .ref { font-family: var(--sans-font); font-size: 14px; color: var(--gray); display: inline-block; padding-top: 0.7em; } .refs pre { white-space: pre-wrap; padding-bottom: 0.5rem; } .refs strong { padding-right: 1em; } .line-numbers { white-space: pre-line; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none; -o-user-select: none; user-select: none; display: flex; float: left; flex-direction: column; margin-right: 1ch; } .file-wrapper { display: flex; flex-direction: row; grid-template-columns: 1rem minmax(0, 1fr); gap: 1rem; padding: 0.5rem; background: var(--light-gray); overflow-x: auto; } .chroma-file-wrapper { display: flex; flex-direction: row; grid-template-columns: 1rem minmax(0, 1fr); overflow-x: auto; } .file-content { background: var(--light-gray); overflow-y: hidden; overflow-x: auto; } .diff-type { color: var(--gray); } .commit-info { color: var(--gray); padding-bottom: 1.5rem; font-size: 0.85rem; } @media (max-width: 600px) { .index { grid-row-gap: 0.8em; } .log { grid-template-columns: 1fr; grid-row-gap: 0em; } .index { grid-template-columns: 1fr; grid-row-gap: 0em; } .index-name:not(:first-child) { padding-top: 1.5rem; } .commit-info:not(:last-child) { padding-bottom: 1.5rem; } pre { font-size: 0.8rem; } }
-
-
templates/404.html (deleted)
-
@@ -1,13 +0,0 @@{{ define "404" }} <html> <title>404</title> {{ template "head" . }} <body> {{ template "nav" . }} <main> <h3>404 — nothing like that here.</h3> </main> </body> </html> {{ end }}
-
-
templates/404.html.tmpl (new)
-
@@ -0,0 +1,28 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "404" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} <title>{{ .Config.Meta.Title }}</title> {{- if .Config.Meta.Description }} <meta name="description" content="{{ .Config.Meta.Description }}" /> {{- end }} </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> </ol> </header> <main> <h1>Page not found</h1> </main> </body> </html> {{- end }}
-
-
templates/500.html (deleted)
-
@@ -1,13 +0,0 @@{{ define "500" }} <html> <title>500</title> {{ template "head" . }} <body> {{ template "nav" . }} <main> <h3>500 — something broke!</h3> </main> </body> </html> {{ end }}
-
-
templates/500.html.tmpl (new)
-
@@ -0,0 +1,30 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "500" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} <title>{{ .Config.Meta.Title }}</title> {{- if .Config.Meta.Description }} <meta name="description" content="{{ .Config.Meta.Description }}" /> {{- end }} </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> </ol> </header> <main> <h1>Internal error</h1> <p>Sorry, we can't serve this page due to our application error.</p> </main> </body> </html> {{- end }}
-
-
templates/commit.html (deleted)
-
@@ -1,104 +0,0 @@{{ define "commit" }} <html> {{ template "head" . }} {{ template "repoheader" . }} <body> {{ template "nav" . }} <main> <section class="commit"> <pre> {{- .commit.Message -}} </pre> <div class="commit-info"> {{ .commit.Author.Name }} <a href="mailto:{{ .commit.Author.Email }}" class="commit-email">{{ .commit.Author.Email}}</a> <div>{{ .commit.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div> </div> <div> <strong>commit</strong> <p><a href="/{{ .name }}/commit/{{ .commit.This }}" class="commit-hash"> {{ .commit.This }} </a> </p> </div> {{ if .commit.Parent }} <div> <strong>parent</strong> <p><a href="/{{ .name }}/commit/{{ .commit.Parent }}" class="commit-hash"> {{ .commit.Parent }} </a></p> </div> {{ end }} <div class="diff-stat"> <div> {{ .stat.FilesChanged }} files changed, {{ .stat.Insertions }} insertions(+), {{ .stat.Deletions }} deletions(-) </div> <div> <br> <strong>jump to</strong> {{ range .diff }} <ul> <li><a href="#{{ .Name.New }}">{{ .Name.New }}</a></li> </ul> {{ end }} </div> </div> </section> <section> {{ $repo := .name }} {{ $this := .commit.This }} {{ $parent := .commit.Parent }} {{ range .diff }} <div id="{{ .Name.New }}"> <div class="diff"> {{ if .IsNew }} <span class="diff-type">A</span> {{ end }} {{ if .IsDelete }} <span class="diff-type">D</span> {{ end }} {{ if not (or .IsNew .IsDelete) }} <span class="diff-type">M</span> {{ end }} {{ if .Name.Old }} <a href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a> {{ if .Name.New }} → <a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a> {{ end }} {{ else }} <a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a> {{- end -}} {{ if .IsBinary }} <p>Not showing binary file.</p> {{ else }} <pre> {{- range .TextFragments -}} <p>{{- .Header -}}</p> {{- range .Lines -}} {{- if eq .Op.String "+" -}} <span class="diff-add">{{ .String }}</span> {{- end -}} {{- if eq .Op.String "-" -}} <span class="diff-del">{{ .String }}</span> {{- end -}} {{- if eq .Op.String " " -}} <span class="diff-noop">{{ .String }}</span> {{- end -}} {{- end -}} {{- end -}} {{- end -}} </pre> </div> </div> {{ end }} </section> </main> </body> </html> {{ end }}
-
-
templates/file.html (deleted)
-
@@ -1,36 +0,0 @@{{ define "file" }} <html> {{ template "head" . }} {{ template "repoheader" . }} <body> {{ template "nav" . }} <main> <p>{{ .path }} (<a style="color: gray" href="?raw=true">view raw</a>)</p> {{if .chroma }} <div class="chroma-file-wrapper"> {{ .content }} </div> {{else}} <div class="file-wrapper"> <table> <tbody><tr> <td class="line-numbers"> <pre> {{- range .linecount }} <a id="L{{ . }}" href="#L{{ . }}">{{ . }}</a> {{- end -}} </pre> </td> <td class="file-content"> <pre> {{- .content -}} </pre> </td> </tbody></tr> </table> </div> {{end}} </main> </body> </html> {{ end }}
-
-
templates/head.html (deleted)
-
@@ -1,32 +0,0 @@{{ define "head" }} <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/style.css" type="text/css"> <link rel="icon" type="image/png" size="32x32" href="/static/legit.png"> {{ if .parent }} <title>{{ .meta.Title }} — {{ .name }} ({{ .ref }}): {{ .parent }}/</title> {{ else if .path }} <title>{{ .meta.Title }} — {{ .name }} ({{ .ref }}): {{ .path }}</title> {{ else if .files }} <title>{{ .meta.Title }} — {{ .name }} ({{ .ref }})</title> {{ else if .commit }} <title>{{ .meta.Title }} — {{ .name }}: {{ .commit.This }}</title> {{ else if .branches }} <title>{{ .meta.Title }} — {{ .name }}: refs</title> {{ else if .commits }} {{ if .log }} <title>{{ .meta.Title }} — {{ .name }}: log</title> {{ else }} <title>{{ .meta.Title }} — {{ .name }}</title> {{ end }} {{ else }} <title>{{ .meta.Title }}</title> {{ end }} {{ if and .servername .gomod }} <meta name="go-import" content="{{ .servername}}/{{ .name }} git https://{{ .servername }}/{{ .name }}"> {{ end }} <!-- other meta tags here --> </head> {{ end }}
-
-
templates/head.html.tmpl (new)
-
@@ -0,0 +1,16 @@<!-- Shared HTML tags to put inside <head> tag. Include inside <head> tag, like this: <head> {{ template "head" }} <title>Page Title</title> </head> Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{- define "head" -}} <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" type="image/png" /> {{- end }}
-
-
templates/index.html (deleted)
-
@@ -1,21 +0,0 @@{{ define "index" }} <html> {{ template "head" . }} <header> <h1>{{ .meta.Title }}</h1> <h2>{{ .meta.Description }}</h2> </header> <body> <main> <div class="index"> {{ range .info }} <div class="index-name"><a href="/{{ .Name }}">{{ .DisplayName }}</a></div> <div class="desc">{{ .Desc }}</div> <time datetime="{{ .UpdatedAtRaw }}" title="{{ .UpdatedAt }}">{{ .Idle }}</time> {{ end }} </div> </main> </body> </html> {{ end }}
-
-
templates/log.html (deleted)
-
@@ -1,25 +0,0 @@{{ define "log" }} <html> {{ template "head" . }} {{ template "repoheader" . }} <body> {{ template "nav" . }} <main> {{ $repo := .name }} <div class="log"> {{ range .commits }} <div> <div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div> <pre>{{ .Message }}</pre> </div> <div class="commit-info"> {{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a> <div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div> </div> {{ end }} </div> </main> </body> </html> {{ end }}
-
-
templates/nav.html (deleted)
-
@@ -1,14 +0,0 @@{{ define "nav" }} <nav> <ul> {{ if .name }} <li><a href="/{{ .name }}">summary</a> <li><a href="/{{ .name }}/refs">refs</a> {{ if .ref }} <li><a href="/{{ .name }}/tree/{{ .ref }}/">tree</a> <li><a href="/{{ .name }}/log/{{ .ref }}">log</a> {{ end }} {{ end }} </ul> </nav> {{ end }}
-
-
templates/refs.html (deleted)
-
@@ -1,40 +0,0 @@{{ define "refs" }} <html> {{ template "head" . }} {{ template "repoheader" . }} <body> {{ template "nav" . }} <main> {{ $name := .name }} <h3>branches</h3> <div class="refs"> {{ range .branches }} <div> <strong>{{ .Name.Short }}</strong> <a href="/{{ $name }}/tree/{{ .Name.Short }}/">browse</a> <a href="/{{ $name }}/log/{{ .Name.Short }}">log</a> <a href="/{{ $name }}/archive/{{ .Name.Short }}.tar.gz">tar.gz</a> </div> {{ end }} </div> {{ if .tags }} <h3>tags</h3> <div class="refs"> {{ range .tags }} <div> <strong>{{ .Name }}</strong> <a href="/{{ $name }}/tree/{{ .Name }}/">browse</a> <a href="/{{ $name }}/log/{{ .Name }}">log</a> <a href="/{{ $name }}/archive/{{ .Name }}.tar.gz">tar.gz</a> {{ if .Message }} <pre>{{ .Message }}</pre> </div> {{ end }} {{ end }} </div> {{ end }} </main> </body> </html> {{ end }}
-
-
-
@@ -0,0 +1,77 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-blob-ref" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} {{- $path := "" -}} {{- $name := "" -}} {{- range .Path -}} {{- $path = printf "%s/%s" $path . -}} {{- $name = . -}} {{- end -}} <title> {{ $path }} at {{ .Meta.Ref }} - {{ .Meta.DisplayName }} </title> <meta name="description" content='{{ $path }} in {{ .Meta.DisplayName }}' /> </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> <li> <a href="/{{ .Meta.DisplayName }}">{{ .Meta.DisplayName }}</a> </li> <li> <a href="/{{ .Meta.DisplayName }}/tree/{{ .Meta.Ref }}">Files</a> </li> {{- $path_slice := .Path -}} {{- $meta := .Meta }} {{ range $i, $segment := .Path -}} <li> {{- $trail := "" -}} {{- range $j, $seg := $path_slice -}} {{- if le $j $i }} {{- $trail = printf "%s/%s" $trail $seg -}} {{- end -}} {{- end -}} {{- $type := "tree" -}} {{- if eq $segment $name -}} {{- $type = "blob" -}} {{- end -}} <a href="/{{ $meta.DisplayName }}/{{ $type }}/{{ $meta.Ref }}{{ $trail }}">{{ $segment }}</a> </li> {{- end }} </ol> <span>{{ .Meta.DisplayName }}</span> {{ if .Meta.Description -}} <p>{{ .Meta.Description }}</p> {{- end -}} </header> {{ template "repo-nav" . }} <main> <div style="display:grid;grid-template-columns:max-content minmax(0,1fr);gap:1px 1ch;font-family:monospace;line-height:1.3;"> <ol style="list-style:none;padding:0;"> {{- range .LineNumbers -}} <li> <a id="L{{ . }}" href="#L{{ . }}">{{ . }}</a> </li> {{- end -}} </ol> {{ if .SyntaxHighlightedContent -}} {{ .SyntaxHighlightedContent }} {{- else -}} <pre><code> {{- .Content -}} </code></pre> {{- end }} </div> </main> </body> </html> {{- end }}
-
-
-
@@ -0,0 +1,134 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-commit" -}} <!DOCTYPE html> <html lang="en"> {{ $shorthash := slice .Commit.Hash.String 0 8 }} <head> {{ template "head" }} <title> {{ $shorthash }} - {{ .Meta.DisplayName }} </title> <meta name="description" content='{{ $shorthash }} in {{ .Meta.DisplayName }}' /> </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> <li> <a href="/{{ .Meta.DisplayName }}">{{ .Meta.DisplayName }}</a> </li> <li> <a href="/{{ .Meta.DisplayName }}/commit/{{ .Meta.Ref }}">{{ $shorthash }}</a> </li> </ol> <span>{{ .Meta.DisplayName }}</span> {{ if .Meta.Description -}} <p>{{ .Meta.Description }}</p> {{- end -}} </header> {{ template "repo-nav" . }} <main> <h1>{{ $shorthash }}</h1> <pre> {{- .Commit.Message -}} </pre> <h2>Metadata</h2> <dl> <dt>Author</dt> <dd> <a href="mailto:{{ .Commit.Author.Email }}"> {{- .Commit.Author.Name -}} </a> authored at <time datetime='{{ .Commit.Author.When.Format "2006-01-02T15:04:05-0700" }}'> {{ .Commit.Author.When.Format "2006-01-02 15:04:05 -0700" }} </time> </dd> <dt>Committer</dt> <dd> <a href="mailto:{{ .Commit.Committer.Email }}"> {{- .Commit.Committer.Name -}} </a> commited at <time datetime='{{ .Commit.Committer.When.Format "2006-01-02T15:04:05-0700" }}'> {{ .Commit.Committer.When.Format "2006-01-02 15:04:05 -0700" }} </time> </dd> {{- if .Commit.PGPSignature }} <dt>Signature</dt> <dd> <details> <summary>View</summary> <pre><code>{{ .Commit.PGPSignature }}</code></pre> </details> </dd> {{ end -}} {{- if not .Parent.Hash.IsZero }} <dt>Parent</dt> <dd> <a href="/{{ .Meta.DisplayName }}/commit/{{ .Parent.Hash.String }}"> {{- slice .Parent.Hash.String 0 8 -}} </a> </dd> {{ end -}} </dl> <h2>Changes</h2> <p> {{ .Diff.Stat.FilesChanged }} changed files (+{{ .Diff.Stat.Insertions }}/-{{ .Diff.Stat.Deletions }}) </p> <ul> {{ $meta := .Meta }} {{ $root := . }} {{- range .Diff.Files }} <li> <div> {{- if or .IsRename .IsDelete }} <a href="/{{ $meta.DisplayName }}/blob/{{ $root.Parent.Hash.String }}/{{ .OldName }}">{{ .OldName }}</a> {{- if .IsRename }} > {{- else }} (deleted) {{- end }} {{- end}} <a href="/{{ $meta.DisplayName }}/blob/{{ $root.Commit.Hash.String }}/{{ .NewName }}">{{ .NewName }}</a> {{- if not .OldName }} <span>(new)</span> {{ end -}} </div> <div> {{ if .IsBinary -}} <p>Diff for binary file is unavailable.</p> {{- else -}} <ul> {{- range .TextFragments }} <li> <span>{{ .Header }}</span> <pre> {{- range .Lines -}} {{- $op := "" -}} {{- if eq .Op.String "+" -}} {{- $op = "add" -}} {{- else if eq .Op.String "-" -}} {{- $op = "delete" -}} {{- end -}} <span data-op="{{ $op }}">{{ .String }}</span> {{- end -}} </pre> </li> {{ end -}} </ul> {{- end }} </div> </li> {{ end -}} </ul> </main> </body> </html> {{- end }}
-
-
templates/repo-header.html (deleted)
-
@@ -1,12 +0,0 @@{{ define "repoheader" }} <header> <h2> <a href="/">all repos</a> — {{ .displayname }} {{ if .ref }} <span class="ref">@ {{ .ref }}</span> {{ end }} </h2> <h3 class="desc">{{ .desc }}</h3> </header> {{ end }}
-
-
-
@@ -0,0 +1,47 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-list" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} <title>{{ .Config.Meta.Title }}</title> {{- if .Config.Meta.Description }} <meta name="description" content="{{ .Config.Meta.Description }}" /> {{- end }} </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> </ol> <h1>{{ .Config.Meta.Title }}</h1> </header> <main> <p>{{ .Config.Meta.Description }}</p> <ul> {{- range .Repositories }} <li> <a href="/{{ .DirName }}"> <span> {{- .DisplayName -}} </span> <span>{{ .Description }}</span> <time datetime='{{ .LastCommit.Author.When.Format "2006-01-02T15:04:05-0700" }}' title='{{ .LastCommit.Author.When.Format "2006-01-02 15:04:05 -0700" }}' > {{- .LastCommitAtRelative -}} </time> </a> </li> {{- end -}} </ul> </main> </body> </html> {{- end }}
-
-
-
@@ -0,0 +1,71 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-log-ref" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} <title> Commit history at {{ .Meta.Ref }} - {{ .Meta.DisplayName }} </title> <meta name="description" content='Commit history on {{ .Meta.DisplayName }} at {{ .Meta.Ref }}' /> </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> <li> <a href="/{{ .Meta.DisplayName }}">{{ .Meta.DisplayName }}</a> </li> <li> <a href="/{{ .Meta.DisplayName }}/log/{{ .Meta.Ref }}">Commits</a> </li> </ol> <span>{{ .Meta.DisplayName }}</span> {{ if .Meta.Description -}} <p>{{ .Meta.Description }}</p> {{- end -}} </header> {{ template "repo-nav" . }} <main> <h1>Commits at {{ .Meta.Ref }}</h1> <ol> {{- $meta := .Meta -}} {{ range .Commits -}} <li> <div> <a href="/{{ $meta.DisplayName }}/commit/{{ .Hash.String }}"> {{- slice .Hash.String 0 8 -}} </a> - <a href="mailto:{{ .Committer.Email }}"> {{- .Committer.Name -}} </a> comitted at <time datetime='{{ .Committer.When.Format "2006-01-02T15:04:05-0700" }}'> {{ .Committer.When.Format "2006-01-02 15:04:05 -0700" }} </time> </div> <div> <a href="mailto:{{ .Author.Email }}"> {{- .Author.Name -}} </a> authored at <time datetime='{{ .Author.When.Format "2006-01-02T15:04:05-0700" }}'> {{ .Author.When.Format "2006-01-02 15:04:05 -0700" }} </time> </div> <pre> {{- .Message -}} </pre> </li> {{- end }} </ol> </main> </body> </html> {{- end }}
-
-
-
@@ -0,0 +1,21 @@<!-- Navigation menu for repository pages. This template requires "Meta repositoryMeta" to be defined at the top of data structure. Do not forget to pass context down with dot. <body> {{ template "repo-nav" . }} <p>Foo</p> </body> Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-nav" -}} <nav> <a href="/{{ .Meta.DisplayName }}">Summary</a> <a href="/{{ .Meta.DisplayName }}/refs">Refs</a> <a href="/{{ .Meta.DisplayName }}/log/{{ .Meta.Ref }}">Commits</a> <a href="/{{ .Meta.DisplayName }}/tree/{{ .Meta.Ref }}">Files</a> </nav> {{- end -}}
-
-
-
@@ -0,0 +1,67 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-refs" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} <title>Refs - {{ .Meta.DisplayName }}</title> <meta name="description" content="Git refs of {{ .Meta.DisplayName }}" /> </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> <li> <a href="/{{ .Meta.DisplayName }}">{{ .Meta.DisplayName }}</a> </li> <li> <a href="/{{ .Meta.DisplayName }}/refs">Refs</a> </li> </ol> <span>{{ .Meta.DisplayName }}</span> {{ if .Meta.Description -}} <p>{{ .Meta.Description }}</p> {{- end -}} </header> {{ template "repo-nav" . }} <main> {{- $meta := .Meta -}} <h2>Branches</h2> <ul> {{- range .Branches }} <li> <span>{{ .Name.Short }}</span> <div> <a href="/{{ $meta.DisplayName }}/log/{{ .Name.Short }}">Commits</a> <a href="/{{ $meta.DisplayName }}/tree/{{ .Name.Short }}">Files</a> <a href="/{{ $meta.DisplayName }}/archive/{{ .Name.Short }}.tar.gz">Download archive</a> </div> </li> {{ end -}} </ul> <h2>Tags</h2> {{- if .Tags }} <ul> {{- range .Tags }} <li> <span>{{ .Name }}</span> <div> <a href="/{{ $meta.DisplayName }}/log/{{ .Name }}">Commits</a> <a href="/{{ $meta.DisplayName }}/tree/{{ .Name }}">Files</a> <a href="/{{ $meta.DisplayName }}/archive/{{ .Name }}.tar.gz">Download archive</a> </div> </li> {{ end -}} </ul> {{- else -}} <p>This repository has no tags.</p> {{ end -}} </main> </body> </html> {{- end }}
-
-
-
@@ -0,0 +1,80 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-top" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} <title>{{ .Meta.DisplayName }} | {{ .Config.Meta.Title }}</title> {{- if .Meta.Description }} <meta name="description" content="{{ .Meta.Description }}" /> {{- end }} {{- if and .IsGoModule .Config.Server.Name }} <meta name="go-import" content="{{ .Config.Server.Name }}/{{ .Meta.DisplayName }} git https://{{ .Config.Server.Name }}/{{ .Meta.DirName }}" /> {{- end }} </head> <body> <header> <ol> <li> <a href="/">Top</a> </li> <li> <a href="/{{ .Meta.DisplayName }}">{{ .Meta.DisplayName }}</a> </li> </ol> <span>{{ .Meta.DisplayName }}</span> {{ if .Meta.Description -}} <p>{{ .Meta.Description }}</p> {{- end -}} </header> {{ template "repo-nav" . }} <main> {{- .Readme -}} </main> <aside> <dl> <dt>Default branch</dt> <dd>{{ .DefaultBranch }}</dd> <dt>Clone URL</dt> <dd><code>https://{{ .Config.Server.Name }}/{{ .Meta.DirName }}</code></dd> {{- if and .IsGoModule .Config.Server.Name -}} <dt>Go Module</dt> <dd>{{ .Config.Server.Name }}/{{ .Meta.DisplayName }}</dd> {{- end -}} </dl> </aside> <aside> <h2>Recent commits</h2> <ol> {{ $meta := .Meta }} {{- range .RecentCommits }} <li> <div> <a href="/{{ $meta.DisplayName }}/commit/{{ .Hash.String }}"> {{- slice .Hash.String 0 8 -}} </a> - <a href="mailto:{{ .Committer.Email }}"> {{- .Committer.Name -}} </a> comitted at <time datetime='{{ .Committer.When.Format "2006-01-02T15:04:05-0700" }}'> {{ .Committer.When.Format "2006-01-02 15:04:05 -0700" }} </time> </div> <pre> {{- .Message -}} </pre> </li> {{- end -}} </ol> </aside> </body> </html> {{- end }}
-
-
-
@@ -0,0 +1,77 @@<!-- Copyright 2025 Shota FUJI <pockawoooh@gmail.com> SPDX-License-Identifier: MIT --> {{ define "repo-tree-ref" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head" }} {{- $path := "" -}} {{- range .Path -}} {{- $path = printf "%s/%s" $path . -}} {{- end -}} <title> {{ or $path "Files" }} at {{ .Meta.Ref }} - {{ .Meta.DisplayName }} </title> <meta name="description" content='{{ or $path "List of files" }} in {{ .Meta.DisplayName }}' /> </head> <body> {{- $meta := .Meta -}} <header> <ol> <li> <a href="/">Top</a> </li> <li> <a href="/{{ .Meta.DisplayName }}">{{ .Meta.DisplayName }}</a> </li> <li> <a href="/{{ .Meta.DisplayName }}/tree/{{ .Meta.Ref }}">Files</a> </li> {{- $path_slice := .Path -}} {{ range $i, $segment := .Path -}} <li> {{- $trail := "" -}} {{- range $j, $seg := $path_slice -}} {{- if le $j $i }} {{- $trail = printf "%s/%s" $trail $seg -}} {{- end -}} {{- end -}} <a href="/{{ $meta.DisplayName }}/tree/{{ $meta.Ref }}{{ $trail }}">{{ $segment }}</a> </li> {{- end }} </ol> <span>{{ .Meta.DisplayName }}</span> {{ if .Meta.Description -}} <p>{{ .Meta.Description }}</p> {{- end -}} </header> {{ template "repo-nav" . }} <main> {{- $prefix := $path -}} {{- if $prefix -}} {{- $prefix = printf "%s/" $prefix -}} {{- end -}} <ul> {{ range .Files -}} <li> {{ if not .IsFile -}} <a href="/{{ $meta.DisplayName }}/tree/{{ $meta.Ref }}/{{ $prefix }}{{ .Name }}"> {{ .Name }}/ </a> {{- else -}} <a href="/{{ $meta.DisplayName }}/blob/{{ $meta.Ref }}/{{ $prefix }}{{ .Name }}"> {{ .Name }} </a> {{- end }} <span>{{ .Mode }}</span> <span>{{ .Size }} bytes</span> </li> {{- end }} </ul> </main> </body> </html> {{- end }}
-
-
templates/repo.html (deleted)
-
@@ -1,38 +0,0 @@{{ define "repo" }} <html> {{ template "head" . }} {{ template "repoheader" . }} <body> {{ template "nav" . }} <main> {{ $repo := .name }} <div class="log"> {{ range .commits }} <div> <div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div> <pre>{{ .Message }}</pre> </div> <div class="commit-info"> {{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a> <div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div> </div> {{ end }} </div> {{- if .readme }} <article class="readme"> {{- .readme -}} </article> {{- end -}} <div class="clone-url"> <strong>clone</strong> <pre> git clone https://{{ .servername }}/{{ .name }} </pre> </div> </main> </body> </html> {{ end }}
-
-
templates/tree.html (deleted)
-
@@ -1,55 +0,0 @@{{ define "tree" }} <html> {{ template "head" . }} {{ template "repoheader" . }} <body> {{ template "nav" . }} <main> {{ $repo := .name }} {{ $ref := .ref }} {{ $parent := .parent }} <div class="tree"> {{ if $parent }} <div></div> <div></div> <div><a href="/{{ $repo }}/tree/{{ $ref }}/{{ .dotdot }}">..</a></div> {{ end }} {{ range .files }} {{ if not .IsFile }} <div class="mode">{{ .Mode }}</div> <div class="size">{{ .Size }}</div> <div> {{ if $parent }} <a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a> {{ else }} <a href="/{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a> {{ end }} </div> {{ end }} {{ end }} {{ range .files }} {{ if .IsFile }} <div class="mode">{{ .Mode }}</div> <div class="size">{{ .Size }}</div> <div> {{ if $parent }} <a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a> {{ else }} <a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a> {{ end }} </div> {{ end }} {{ end }} </div> <article> <pre> {{- if .readme }}{{ .readme }}{{- end -}} </pre> </article> </main> </body> </html> {{ end }}
-