diff options
author | Runxi Yu <me@runxiyu.org> | 2025-02-10 08:57:33 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-02-10 08:57:33 +0800 |
commit | 6b0a78df8bb6071534848502003446b57ac515f4 (patch) | |
tree | 2a473447a26b856acb207a3e7c6452cd657d052c | |
parent | repo_index: Use the first line of the commit message (diff) | |
download | forge-6b0a78df8bb6071534848502003446b57ac515f4.tar.gz forge-6b0a78df8bb6071534848502003446b57ac515f4.tar.zst forge-6b0a78df8bb6071534848502003446b57ac515f4.zip |
repo_tree: Initialize handler (copied over from index)
-rw-r--r-- | handle_repo_tree.go | 95 | ||||
-rw-r--r-- | main.go | 1 | ||||
-rw-r--r-- | templates/repo_tree_dir.html | 40 |
3 files changed, 136 insertions, 0 deletions
diff --git a/handle_repo_tree.go b/handle_repo_tree.go new file mode 100644 index 0000000..0ee8870 --- /dev/null +++ b/handle_repo_tree.go @@ -0,0 +1,95 @@ +package main + +import ( + "bytes" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/microcosm-cc/bluemonday" + "github.com/yuin/goldmark" + "html/template" + "net/http" + "path/filepath" +) + +func handle_repo_tree(w http.ResponseWriter, r *http.Request) { + data := make(map[string]any) + // TODO: Sanitize path values + project_name, repo_name := r.PathValue("project_name"), r.PathValue("repo_name") + data["project_name"], data["repo_name"] = project_name, repo_name + repo, err := git.PlainOpen(filepath.Join(config.Git.Root, project_name, repo_name+".git")) + if err != nil { + w.Write([]byte("Error opening repo: " + err.Error())) + return + } + head, err := repo.Head() + if err != nil { + w.Write([]byte("Error getting repo HEAD: " + err.Error())) + return + } + head_hash := head.Hash() + commit_iter, err := repo.Log(&git.LogOptions{From: head_hash}) + if err != nil { + w.Write([]byte("Error getting repo commits: " + err.Error())) + return + } + recent_commits := make([]*object.Commit, 0) + defer commit_iter.Close() + for range 3 { + this_recent_commit, err := commit_iter.Next() + if err != nil { + w.Write([]byte("Error getting a recent commit: " + err.Error())) + return + } + recent_commits = append(recent_commits, this_recent_commit) + } + data["commits"] = recent_commits + commit_object, err := repo.CommitObject(head_hash) + if err != nil { + w.Write([]byte("Error getting commit object: " + err.Error())) + return + } + tree, err := commit_object.Tree() + if err != nil { + w.Write([]byte("Error getting file tree: " + err.Error())) + return + } + readme_file, err := tree.File("README.md") + if err != nil { + w.Write([]byte("Error getting file: " + err.Error())) + return + } + readme_file_contents, err := readme_file.Contents() + var readme_rendered_unsafe bytes.Buffer + err = goldmark.Convert([]byte(readme_file_contents), &readme_rendered_unsafe) + if err != nil { + readme_rendered_unsafe.WriteString("Unable to render README: " + err.Error()) + return + } + readme_rendered_safe := template.HTML(bluemonday.UGCPolicy().SanitizeBytes(readme_rendered_unsafe.Bytes())) + data["readme"] = readme_rendered_safe + + display_git_tree := make([]display_git_tree_entry_t, 0) + for _, entry := range tree.Entries { + display_git_tree_entry := display_git_tree_entry_t{} + os_mode, err := entry.Mode.ToOSFileMode() + if err != nil { + display_git_tree_entry.Mode = "----" + } else { + display_git_tree_entry.Mode = os_mode.String()[:4] + } + display_git_tree_entry.Is_file = entry.Mode.IsFile() + display_git_tree_entry.Size, err = tree.Size(entry.Name) + if err != nil { + display_git_tree_entry.Size = 0 + } + display_git_tree_entry.Name = entry.Name + display_git_tree = append(display_git_tree, display_git_tree_entry) + } + data["files"] = display_git_tree + + err = templates.ExecuteTemplate(w, "repo_tree_dir", data) + if err != nil { + w.Write([]byte("Error rendering template: " + err.Error())) + return + } +} @@ -33,6 +33,7 @@ func main() { http.HandleFunc("/{$}", handle_index) http.HandleFunc("/{project_name}/repos/{repo_name}/", handle_repo_index) + http.HandleFunc("/{project_name}/repos/{repo_name}/tree/{ref}/{rest...}", handle_repo_tree) listener, err := net.Listen(config.HTTP.Net, config.HTTP.Addr) if err != nil { diff --git a/templates/repo_tree_dir.html b/templates/repo_tree_dir.html new file mode 100644 index 0000000..6708f0c --- /dev/null +++ b/templates/repo_tree_dir.html @@ -0,0 +1,40 @@ +{{- define "repo_tree_dir" -}} +<!DOCTYPE html> +<html> +<head> +<link rel="stylesheet" href="/static/style.css" /> +<title>{{ .project_name }}/repos/{{ .repo_name }}/{{ .path }}</title> +</head> +<body class="repo-index"> +<div class="padding-wrapper"> +<table id="file-tree"> +<thead> +<tr> +<th scope="col">Mode</th> +<th scope="col">Name</th> +<th scope="col">Size</th> +</tr> +</thead> +<tbody> +{{- range .files }} +<tr> +<td class="file-mode">{{ .Mode }}</td> +<td class="file-name">{{ .Name }}</td> +<td class="file-size">{{ .Size }}</td> +</tr> +{{- end }} +</tbody> +</table> +</div> +<div class="padding-wrapper"> +<div id="refs"> +</div> +</div> +<div class="padding-wrapper"> +<div id="readme"> +{{ .readme -}} +</div> +</div> +</body> +</html> +{{- end -}} |