Lindenii Project Forge
Commit info | |
---|---|
ID | 7491c424a00f0824f1d45b33d3b3f55fb0a7c4d8 |
Author | Runxi Yu<me@runxiyu.org> |
Author date | Tue, 11 Feb 2025 20:50:17 +0800 |
Committer | Runxi Yu<me@runxiyu.org> |
Committer date | Tue, 11 Feb 2025 20:50:17 +0800 |
Actions | Get patch |
repo_commit: Show chunks
package main import ( "net/http" "github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/diff"
)
type usable_file_patch struct { From diff.File To diff.File Chunks []diff.Chunk }
func handle_repo_commit(w http.ResponseWriter, r *http.Request) { data := make(map[string]any) // TODO: Sanitize path values group_name, repo_name, commit_id_string := r.PathValue("group_name"), r.PathValue("repo_name"), r.PathValue("commit_id") data["group_name"], data["repo_name"], data["commit_id"] = group_name, repo_name, commit_id_string repo, err := open_git_repo(group_name, repo_name) if err != nil { _, _ = w.Write([]byte("Error opening repo: " + err.Error())) return } commit_id := plumbing.NewHash(commit_id_string) commit_object, err := repo.CommitObject(commit_id) if err != nil { _, _ = w.Write([]byte("Error getting commit object: " + err.Error())) return } data["commit_object"] = commit_object parent_commit_object, err := commit_object.Parent(0) if err != nil { _, _ = w.Write([]byte("Error getting parent commit object: " + err.Error())) return } data["parent_commit_object"] = parent_commit_object patch, err := parent_commit_object.Patch(commit_object) if err != nil { _, _ = w.Write([]byte("Error getting patch of commit: " + err.Error())) return } data["patch"] = patch
/* for _, file_patch := range patch.FilePatches() { for _, chunk := range file_patch.Chunks() { }
usable_file_patches := make([]usable_file_patch, 0) for _, file_patch := range patch.FilePatches() { from, to := file_patch.Files() usable_file_patch := usable_file_patch{ Chunks: file_patch.Chunks(), From: from, To: to,
}
*/
usable_file_patches = append(usable_file_patches, usable_file_patch) } data["file_patches"] = usable_file_patches
err = templates.ExecuteTemplate(w, "repo_commit", data) if err != nil { _, _ = w.Write([]byte("Error rendering template: " + err.Error())) return } }
html { font-family: sans-serif; background-color: var(--background-color); color: var(--text-color); --background-color: hsl(0, 0%, 100%); --text-color: hsl(0, 0%, 0%); --link-color: hsl(320, 50%, 36%); --light-text-color: hsl(0, 0%, 45%); --darker-border-color: hsl(0, 0%, 72%); --lighter-border-color: hsl(0, 0%, 85%); --text-decoration-color: hsl(0, 0%, 72%); --darker-box-background-color: hsl(0, 0%, 92%); --lighter-box-background-color: hsl(0, 0%, 95%); } @media (prefers-color-scheme: dark) { html { --background-color: hsl(0, 0%, 0%); --text-color: hsl(0, 0%, 100%); --link-color: hsl(320, 50%, 76%); --light-text-color: hsl(0, 0%, 78%); --darker-border-color: hsl(0, 0%, 35%); --lighter-border-color: hsl(0, 0%, 25%); --text-decoration-color: hsl(0, 0%, 30%); --darker-box-background-color: hsl(0, 0%, 20%); --lighter-box-background-color: hsl(0, 0%, 15%); } } html, code, pre { font-size: 1rem; /* TODO: Not always correct */ } footer { margin-top: 1rem; margin-left: auto; margin-right: auto; display: block; padding: 0 5px; width: fit-content; text-align: center; color: var(--light-text-color); } footer a:link, footer a:visited { color: inherit; } .padding-wrapper { margin: 1rem auto; max-width: 60rem; padding: 0 5px; } a:link, a:visited { text-decoration-color: var(--text-decoration-color); color: var(--link-color); } code:not(pre > code) { background-color: var(--lighter-box-background-color); border-radius: 2px; padding: 2px; } table { border: var(--lighter-border-color) solid 1px; border-spacing: 0px; border-collapse: collapse; } table.wide { width: 100%; } td, th { padding: 3px 5px; border: var(--lighter-border-color) solid 1px; } th { background-color: var(--lighter-box-background-color); } th[scope=row] { text-align: left; } tr.title-row > th { background-color: var(--darker-box-background-color); } td > pre { margin: 0; } td#readme > *:last-child { margin-bottom: 0; } td#readme > *:first-child { margin-top: 0; } .commit-id { font-family: monospace; }
pre, .scroll {
.scroll {
overflow-x: auto; } .toggle-table-off, .toggle-table-on { display: none; } .toggle-table-off + table > thead > tr > th, .toggle-table-on + table > thead > tr > th { padding: 0; } .toggle-table-off + table > thead > tr > th > label, .toggle-table-on + table > thead > tr > th > label { width: 100%; display: inline-block; padding: 3px 1px; cursor: pointer; } .toggle-table-off:checked + table > tbody { display: none; } .toggle-table-on + table > tbody { display: none; } .toggle-table-on:checked + table > tbody { display: table-row-group; }
.chunk-unchanged { color: grey; } .chunk-addition { color: green; } .chunk-deletion { color: red; } .chunk-unknown { color: yellow; }
{{- define "repo_commit" -}} <!DOCTYPE html> <html lang="en"> <head> {{ template "head_common" . }} <title>{{ .group_name }}/repos/{{ .repo_name }} – Lindenii Forge</title> </head> <body class="repo-commit"> <div class="padding-wrapper scroll"> <table id="commit-info-table"> <thead> <tr class="title-row"> <th colspan="2">Commit Info</th> </tr> </thead> <tbody> <tr> <th scope="row">ID</th> <td>{{ .commit_id }}</td> </tr> <tr> <th scope="row">Author</th> <td>{{ .commit_object.Author.Name }} <<a href="mailto:{{ .commit_object.Author.Email }}">{{ .commit_object.Author.Email }}</a>></td> </tr> <tr> <th scope="row">Author Date</th> <td>{{ .commit_object.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</td> </tr> <tr> <th scope="row">Committer</th> <td>{{ .commit_object.Committer.Name }} <<a href="mailto:{{ .commit_object.Committer.Email }}">{{ .commit_object.Committer.Email }}</a>></td> </tr> <tr> <th scope="row">Committer Date</th> <td>{{ .commit_object.Committer.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</td> </tr> <tr> <th scope="row">Message</th> <td><pre>{{ .commit_object.Message }}</pre></td> </tr> </tbody> </table> </div> <div class="padding-wrapper scroll">
<pre>{{ .patch }}</pre> <p> </p>
{{ range .file_patches }} <div class="file-patch"> {{ .From.Path }} {{ .From.Mode }} → {{ .To.Path }} {{ .To.Mode }} {{ range .Chunks }} {{ if eq .Type 0 }} <pre class="chunk chunk-unchanged">{{ .Content }}</pre> {{ else if eq .Type 1 }} <pre class="chunk chunk-addition">{{ .Content }}</pre> {{ else if eq .Type 2 }} <pre class="chunk chunk-deletion">{{ .Content }}</pre> {{ else }} <pre class="chunk chunk-unknown">{{ .Content }}</pre> {{ end }} {{ end }} </div> {{ end }}
</div> <footer> {{ template "footer" . }} </footer> </body> </html> {{- end -}}