+ New

fierj

Public

Tiny personal git forge

5dbbfed75b04591be9b5f6a925f89e3dea8acb5a
diff --git a/git.go b/git.go
index c739300..3baab58 100644
--- a/git.go
+++ b/git.go
@@ -74,6 +74,9 @@ func InitRepo(cfg *Config, name string) error {
 	return nil
 }
 
+func (g *Git) Repo() string        { return g.Name }
+func (g *Git) Description() string { return "" }
+
 func (g *Git) List(ref, path string) ([]TreeEntry, error) {
 	args := []string{"ls-tree", "-l", ref}
 	if path != "" {
diff --git a/handlers.go b/handlers.go
index 3d386f8..11bb595 100644
--- a/handlers.go
+++ b/handlers.go
@@ -29,16 +29,16 @@ func Tree(cfg Config, tmpl *template.Template) http.HandlerFunc {
 		}
 		if git.IsEmpty() {
 			tmpl.ExecuteTemplate(w, "tree.html", map[string]any{
-				"Repo":    git.Name,
+				"Repo":    git.Repo(),
 				"Ref":     ref,
 				"Path":    "",
 				"Entries": []FileEntry{},
 				// "CloneURL":    fmt.Sprintf("%s@%s:%s.git", cfg.SSHUser, cfg.Host, repoName),
-				// "Description": repoDescription(repoPath),
-				"Branches": []string{},
-				"Tags":     []string{},
-				"Commits":  0,
-				"Empty":    true,
+				"Description": git.Description(),
+				"Branches":    []string{},
+				"Tags":        []string{},
+				"Commits":     0,
+				"Empty":       true,
 			})
 			return
 		}
@@ -66,18 +66,18 @@ func Tree(cfg Config, tmpl *template.Template) http.HandlerFunc {
 		}
 		readme := git.Readme(ref, treePath)
 		tmpl.ExecuteTemplate(w, "tree.html", map[string]any{
-			"Repo": git.Name,
+			"Repo": git.Repo(),
 			"Ref":  ref,
 			"Path": treePath,
 			// "Breadcrumb": makeBreadcrumb(treePath),
 			"Entries": fileEntries,
 			// "CloneURL":    fmt.Sprintf("%s@%s:%s.git", cfg.SSHUser, cfg.Host, repoName),
-			// "Description": repoDescription(repoPath),
-			// "Branches":    listBranches(repoPath),
-			// "Tags":        listTags(repoPath),
-			// "Commits":     commitCount(repoPath, ref),
-			"Readme":    readme,
-			"ActiveTab": "code",
+			"Description": git.Description(),
+			"Branches":    git.Branches(),
+			"Tags":        git.Tags(),
+			"Commits":     git.CommitCount(ref),
+			"Readme":      readme,
+			"ActiveTab":   "code",
 		})
 	}
 }
@@ -97,16 +97,16 @@ func Blob(cfg Config, tmpl *template.Template) http.HandlerFunc {
 			return
 		}
 		tmpl.ExecuteTemplate(w, "blob.html", map[string]any{
-			"Repo": git.Name,
+			"Repo": git.Repo(),
 			"Ref":  ref,
 			"Path": filePath,
 			// "Breadcrumb":  makeBreadcrumb(filePath),
-			"Content": content,
-			// "Description": repoDescription(repoPath),
-			// "Branches":    listBranches(repoPath),
-			// "Tags":        listTags(repoPath),
-			// "Commits":     commitCount(repoPath, ref),
-			"ActiveTab": "code",
+			"Content":     content,
+			"Description": git.Description(),
+			"Branches":    git.Branches(),
+			"Tags":        git.Tags(),
+			"Commits":     git.CommitCount(ref),
+			"ActiveTab":   "code",
 		})
 	}
 }
@@ -121,14 +121,14 @@ func Log(cfg Config, tmpl *template.Template) http.HandlerFunc {
 			return
 		}
 		data := map[string]any{
-			"Repo":       git.Name,
-			"Ref":        ref,
-			"CommitList": commits,
-			// "Description": repoDescription(repoPath),
-			// "Branches":    listBranches(repoPath),
-			// "Tags":        listTags(repoPath),
-			// "Commits":     commitCount(repoPath, ref),
-			"ActiveTab": "commits",
+			"Repo":        git.Repo(),
+			"Ref":         ref,
+			"CommitList":  commits,
+			"Description": git.Description(),
+			"Branches":    git.Branches(),
+			"Tags":        git.Tags(),
+			"Commits":     git.CommitCount(ref),
+			"ActiveTab":   "commits",
 		}
 		tmpl.ExecuteTemplate(w, "log.html", data)
 	}
@@ -144,17 +144,33 @@ func Diff(cfg Config, tmpl *template.Template) http.HandlerFunc {
 			return
 		}
 		if err := tmpl.ExecuteTemplate(w, "commit.html", map[string]any{
-			"Repo": git.Name,
-			"Ref":  ref,
-			"Diff": commit,
-			"Hash": ref,
-			// "Description": repoDescription(repoPath),
-			// "Branches":    listBranches(repoPath),
-			// "Tags":        listTags(repoPath),
-			// "Commits":     commitCount(repoPath, ref),
-			"ActiveTab": "commits",
+			"Repo":        git.Repo(),
+			"Ref":         ref,
+			"Diff":        commit,
+			"Hash":        ref,
+			"Description": git.Description(),
+			"Branches":    git.Branches(),
+			"Tags":        git.Tags(),
+			"Commits":     git.CommitCount(ref),
+			"ActiveTab":   "commits",
 		}); err != nil {
 			slog.Error("failed to execute template", "error", err)
 		}
 	}
 }
+
+func Refs(cfg Config, tmpl *template.Template) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		git := &Git{Dir: cfg.Dir, Name: r.PathValue("repo")}
+		ref := git.DefaultBranch()
+		tmpl.ExecuteTemplate(w, "refs.html", map[string]any{
+			"Repo":        git.Repo(),
+			"Ref":         ref,
+			"Branches":    git.Branches(),
+			"Tags":        git.Tags(),
+			"Description": git.Description(),
+			"Commits":     git.CommitCount(ref),
+			"ActiveTab":   "refs",
+		})
+	}
+}
diff --git a/main.go b/main.go
index 72cc929..73e7e16 100644
--- a/main.go
+++ b/main.go
@@ -86,11 +86,12 @@ func main() {
 
 	mux := http.NewServeMux()
 
-	mux.HandleFunc("/{repo}", Tree(cfg, tmpl))
-	mux.HandleFunc("/{repo}/tree/{ref}/{path...}", Tree(cfg, tmpl))
-	mux.HandleFunc("/{repo}/blob/{ref}/{path...}", Blob(cfg, tmpl))
-	mux.HandleFunc("/{repo}/log/{ref}", Log(cfg, tmpl))
-	mux.HandleFunc("/{repo}/commit/{ref}", Diff(cfg, tmpl))
+	mux.HandleFunc("GET /{repo}", Tree(cfg, tmpl))
+	mux.HandleFunc("GET /{repo}/tree/{ref}/{path...}", Tree(cfg, tmpl))
+	mux.HandleFunc("GET /{repo}/blob/{ref}/{path...}", Blob(cfg, tmpl))
+	mux.HandleFunc("GET /{repo}/log/{ref}", Log(cfg, tmpl))
+	mux.HandleFunc("GET /{repo}/commit/{ref}", Diff(cfg, tmpl))
+	mux.HandleFunc("GET /{repo}/refs/", Refs(cfg, tmpl))
 
 	srv := &http.Server{
 		Addr:    cfg.Addr,
diff --git a/templates/refs.html b/templates/refs.html
new file mode 100644
index 0000000..e2d0cf8
--- /dev/null
+++ b/templates/refs.html
@@ -0,0 +1,41 @@
+{{template "head" .}}
+{{define "title"}}refs - {{.Repo}} - fierj{{end}}
+{{template "repo-header" .}}
+{{template "repo-tabs" .}}
+
+<div class="refs-container">
+    {{if .Branches}}
+    <div class="refs-section">
+        <h3>Branches</h3>
+        <div class="thread-list">
+            {{range .Branches}}
+            <div class="thread-list-item">
+                <svg class="icon thread-icon-open" viewBox="0 0 16 16" fill="currentColor"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Z"/></svg>
+                <div class="thread-list-content">
+                    <a href="/{{$.Repo}}/tree/{{.}}" class="thread-title">{{.}}</a>
+                    {{if eq . $.DefaultBranch}}<span class="label label-default">default</span>{{end}}
+                </div>
+            </div>
+            {{end}}
+        </div>
+    </div>
+    {{end}}
+    {{if .Tags}}
+    <div class="refs-section">
+        <h3>Tags</h3>
+        <div class="thread-list">
+            {{range .Tags}}
+            <div class="thread-list-item">
+                <svg class="icon thread-icon-open" viewBox="0 0 16 16" fill="currentColor"><path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"/></svg>
+                <div class="thread-list-content">
+                    <a href="/{{$.Repo}}/tree/{{.}}" class="thread-title">{{.}}</a>
+                </div>
+            </div>
+            {{end}}
+        </div>
+    </div>
+    {{end}}
+</div>
+
+{{template "foot" .}}
+