aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-04-03 16:10:16 +0800
committerRunxi Yu <me@runxiyu.org>2025-04-03 16:46:43 +0800
commit347717688fbccabbc9de649f4a0be51d18ea65e8 (patch)
tree7cb3c66007048a5ede9af1618e7d3fdfbd934b5c
parentRename commitDisplay to commitDisplayOld (diff)
downloadforge-347717688fbccabbc9de649f4a0be51d18ea65e8.tar.gz
forge-347717688fbccabbc9de649f4a0be51d18ea65e8.tar.zst
forge-347717688fbccabbc9de649f4a0be51d18ea65e8.zip
HTTP: Use git2d for the repo index
-rw-r--r--go.mod1
-rw-r--r--go.sum4
-rw-r--r--http_handle_repo_index.go149
3 files changed, 76 insertions, 78 deletions
diff --git a/go.mod b/go.mod
index 2ee258f..ab91bcd 100644
--- a/go.mod
+++ b/go.mod
@@ -22,6 +22,7 @@ require (
require (
dario.cat/mergo v1.0.1 // indirect
+ git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
diff --git a/go.sum b/go.sum
index 593a0f6..1aab91c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,8 @@
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw=
+git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9 h1:Ahny8Ud1LjVMMAlt8utUFKhhxJtwBAualvsbc/Sk7cE=
+git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
@@ -108,6 +111,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
diff --git a/http_handle_repo_index.go b/http_handle_repo_index.go
index 6852fe7..6534df1 100644
--- a/http_handle_repo_index.go
+++ b/http_handle_repo_index.go
@@ -4,109 +4,102 @@
package main
import (
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "net"
"net/http"
"strings"
- "time"
- "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/object"
- "github.com/go-git/go-git/v5/plumbing/storer"
+ "git.sr.ht/~sircmpwn/go-bare"
)
-// httpHandleRepoIndex provides the front page of a repo.
-func httpHandleRepoIndex(writer http.ResponseWriter, _ *http.Request, params map[string]any) {
- var repo *git.Repository
- var repoName string
- var groupPath []string
- var refHash plumbing.Hash
- var refHashSlice []byte
- var err error
- var commitObj *object.Commit
- var tree *object.Tree
- var notes []string
- var branches []string
- var branchesIter storer.ReferenceIter
- var commits []commitDisplayOld
+type commitDisplay struct {
+ Hash string
+ Author string
+ Email string
+ Date string
+ Message string
+}
+
+// httpHandleRepoIndex provides the front page of a repo using git2d.
+func httpHandleRepoIndex(w http.ResponseWriter, req *http.Request, params map[string]any) {
+ repoName := params["repo_name"].(string)
+ groupPath := params["group_path"].([]string)
- repo, repoName, groupPath = params["repo"].(*git.Repository), params["repo_name"].(string), params["group_path"].([]string)
+ _, repoPath, _, _, _, _, _ := getRepoInfo(req.Context(), groupPath, repoName, "") // TODO: Don't use getRepoInfo
+ var notes []string
if strings.Contains(repoName, "\n") || sliceContainsNewlines(groupPath) {
notes = append(notes, "Path contains newlines; HTTP Git access impossible")
}
- refHash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string))
+ conn, err := net.Dial("unix", config.Git.Socket)
if err != nil {
- goto no_ref
+ errorPage500(w, params, "git2d connection failed: "+err.Error())
+ return
}
- refHashSlice = refHash[:]
+ defer conn.Close()
- branchesIter, err = repo.Branches()
- if err == nil {
- _ = branchesIter.ForEach(func(branch *plumbing.Reference) error {
- branches = append(branches, branch.Name().Short())
- return nil
- })
+ writer := bare.NewWriter(conn)
+ if err := writer.WriteData([]byte(repoPath)); err != nil {
+ errorPage500(w, params, "sending repo path failed: "+err.Error())
+ return
}
- params["branches"] = branches
- if value, found := indexCommitsDisplayCache.Get(refHashSlice); found {
- if value != nil {
- commits = value
- } else {
- goto readme
- }
- } else {
- start := time.Now()
- commits, err = getRecentCommitsDisplay(repo, refHash, 5)
- if err != nil {
- commits = nil
- }
- cost := time.Since(start).Nanoseconds()
- indexCommitsDisplayCache.Set(refHashSlice, commits, cost)
- if err != nil {
- goto readme
- }
+ reader := bare.NewReader(conn)
+ status, err := reader.ReadUint()
+ if err != nil {
+ errorPage500(w, params, "reading status failed: "+err.Error())
+ return
+ }
+ if status != 0 {
+ errorPage500(w, params, fmt.Sprintf("git2d error: %d", status))
+ return
}
- params["commits"] = commits
-
-readme:
+ /* README */
+ readmeRaw, err := reader.ReadData()
+ if err != nil {
+ readmeRaw = nil
+ }
+ readmeFilename, readmeRendered := renderReadme(readmeRaw, "README.md")
- if value, found := treeReadmeCache.Get(refHashSlice); found {
- params["files"] = value.DisplayTree
- params["readme_filename"] = value.ReadmeFilename
- params["readme"] = value.ReadmeRendered
- } else {
- start := time.Now()
- if commitObj, err = repo.CommitObject(refHash); err != nil {
- goto no_ref
+ /* Commits */
+ var commits []commitDisplay
+ for {
+ id, err := reader.ReadData()
+ if err != nil {
+ if errors.Is(err, io.EOF) {
+ break
+ }
+ errorPage500(w, params, "error reading commit ID: "+err.Error())
+ return
}
- if tree, err = commitObj.Tree(); err != nil {
- goto no_ref
- }
- displayTree := makeDisplayTree(tree)
- readmeFilename, readmeRendered := renderReadmeAtTree(tree)
- cost := time.Since(start).Nanoseconds()
-
- params["files"] = displayTree
- params["readme_filename"] = readmeFilename
- params["readme"] = readmeRendered
-
- entry := treeReadmeCacheEntry{
- DisplayTree: displayTree,
- ReadmeFilename: readmeFilename,
- ReadmeRendered: readmeRendered,
- }
- treeReadmeCache.Set(refHashSlice, entry, cost)
+ title, _ := reader.ReadData()
+ authorName, _ := reader.ReadData()
+ authorEmail, _ := reader.ReadData()
+ authorDate, _ := reader.ReadData()
+
+ commits = append(commits, commitDisplay{
+ Hash: hex.EncodeToString(id),
+ Author: string(authorName),
+ Email: string(authorEmail),
+ Date: string(authorDate),
+ Message: string(title),
+ })
}
-no_ref:
-
+ params["commits"] = commits
+ params["readme_filename"] = readmeFilename
+ params["readme"] = readmeRendered
params["http_clone_url"] = genHTTPRemoteURL(groupPath, repoName)
params["ssh_clone_url"] = genSSHRemoteURL(groupPath, repoName)
params["notes"] = notes
- renderTemplate(writer, "repo_index", params)
+ renderTemplate(w, "repo_index", params)
+
+ // TODO: Caching
}