about summary refs log tree commit diff
path: root/handlers/git/git.go
diff options
context:
space:
mode:
Diffstat (limited to 'handlers/git/git.go')
-rw-r--r--handlers/git/git.go60
1 files changed, 60 insertions, 0 deletions
diff --git a/handlers/git/git.go b/handlers/git/git.go
new file mode 100644
index 0000000..30e8d8f
--- /dev/null
+++ b/handlers/git/git.go
@@ -0,0 +1,60 @@
+// Copyright 2022 Terin Stock.
+// SPDX-License-Identifier: MPL-2.0
+
+package git
+
+import (
+	"fmt"
+	"log"
+	"net/http"
+	"net/http/cgi"
+
+	"github.com/rs/zerolog"
+)
+
+type Options struct {
+	CGI       string
+	ReposRoot string
+	ExportAll bool
+	Logger    zerolog.Logger
+}
+
+type Builder struct {
+	handler  *cgi.Handler
+	register Register
+}
+
+type Register interface {
+	Register(path string, handler http.Handler)
+}
+
+func New(options Options) *Builder {
+	e := []string{
+		fmt.Sprintf("GIT_PROJECT_ROOT=%s", options.ReposRoot),
+	}
+
+	if options.ExportAll {
+		e = append(e, "GIT_HTTP_EXPORT_ALL=true")
+	}
+
+	return &Builder{
+		handler: &cgi.Handler{
+			Path:   options.CGI,
+			Dir:    options.ReposRoot,
+			Env:    e,
+			Logger: log.New(options.Logger, "", 0),
+			Stderr: options.Logger.Level(zerolog.ErrorLevel),
+		},
+	}
+}
+
+func (b *Builder) WithRegister(r Register) *Builder {
+	b.register = r
+	return b
+}
+
+func (b *Builder) Build() (http.Handler, error) {
+	b.register.Register("/{g:.*\\.git/(?:HEAD|info/refs|git-(?:upload|receive)-pack)$}", b.handler)
+
+	return b.handler, nil
+}