Hi… I am well aware that this diff view is very suboptimal. It will be fixed when the refactored server comes along!
Add more documentation comments
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> // Package database provides stubs and wrappers for databases. package database import ( "context" "github.com/jackc/pgx/v5/pgxpool" )
// Database is a wrapper around pgxpool.Pool to provide a common interface for // other packages in the forge.
type Database struct {
	*pgxpool.Pool
}
// Open opens a new database connection pool using the provided connection // string. It returns a Database instance and an error if any occurs. // It is run indefinitely in the background.
func Open(connString string) (Database, error) {
	db, err := pgxpool.New(context.Background(), connString)
	return Database{db}, err
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> // Package embed provides embedded filesystems created in build-time. package embed import "embed"
// Source contains the licenses and source tarballs collected at build time. // It is intended to be served to the user. //
//go:embed LICENSE* source.tar.gz var Source embed.FS
// Resources contains the templates and static files used by the web interface, // as well as the git backend daemon and the hookc helper. //
//go:embed forged/templates/* forged/static/* //go:embed hookc/hookc git2d/git2d var Resources embed.FS
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> // Package git2c provides routines to interact with the git2d backend daemon. package git2c import ( "fmt" "net" "git.sr.ht/~sircmpwn/go-bare" )
// Client represents a connection to the git2d backend daemon.
type Client struct {
SocketPath string
socketPath string
conn net.Conn writer *bare.Writer reader *bare.Reader }
// NewClient establishes a connection to a git2d socket and returns a new Client.
func NewClient(socketPath string) (*Client, error) {
	conn, err := net.Dial("unix", socketPath)
	if err != nil {
		return nil, fmt.Errorf("git2d connection failed: %w", err)
	}
	writer := bare.NewWriter(conn)
	reader := bare.NewReader(conn)
	return &Client{
SocketPath: socketPath,
socketPath: socketPath,
conn: conn, writer: writer, reader: reader, }, nil }
// Close terminates the underlying socket connection.
func (c *Client) Close() error {
	if c.conn != nil {
		return c.conn.Close()
	}
	return nil
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package git2c import ( "encoding/hex" "errors" "fmt" "io" )
// CmdIndex requests a repository index from git2d and returns the list of commits // and the contents of a README file if available.
func (c *Client) CmdIndex(repoPath string) ([]Commit, *FilenameContents, error) {
	if err := c.writer.WriteData([]byte(repoPath)); err != nil {
		return nil, nil, fmt.Errorf("sending repo path failed: %w", err)
	}
	if err := c.writer.WriteUint(1); err != nil {
		return nil, nil, fmt.Errorf("sending command failed: %w", err)
	}
	status, err := c.reader.ReadUint()
	if err != nil {
		return nil, nil, fmt.Errorf("reading status failed: %w", err)
	}
	if status != 0 {
		return nil, nil, fmt.Errorf("git2d error: %d", status)
	}
	// README
	readmeRaw, err := c.reader.ReadData()
	if err != nil {
		readmeRaw = nil
	}
	readmeFilename := "README.md" // TODO
	readme := &FilenameContents{Filename: readmeFilename, Content: readmeRaw}
	// Commits
	var commits []Commit
	for {
		id, err := c.reader.ReadData()
		if err != nil {
			if errors.Is(err, io.EOF) {
				break
			}
			return nil, nil, fmt.Errorf("reading commit ID failed: %w", err)
		}
		title, _ := c.reader.ReadData()
		authorName, _ := c.reader.ReadData()
		authorEmail, _ := c.reader.ReadData()
		authorDate, _ := c.reader.ReadData()
		commits = append(commits, Commit{
			Hash:    hex.EncodeToString(id),
			Author:  string(authorName),
			Email:   string(authorEmail),
			Date:    string(authorDate),
			Message: string(title),
		})
	}
	return commits, readme, nil
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package git2c import ( "errors" "fmt" "io" )
// CmdTreeRaw queries git2d for a tree or blob object at the given path within the repository. // It returns either a directory listing or the contents of a file.
func (c *Client) CmdTreeRaw(repoPath, pathSpec string) ([]TreeEntry, string, error) {
	if err := c.writer.WriteData([]byte(repoPath)); err != nil {
		return nil, "", fmt.Errorf("sending repo path failed: %w", err)
	}
	if err := c.writer.WriteUint(2); err != nil {
		return nil, "", fmt.Errorf("sending command failed: %w", err)
	}
	if err := c.writer.WriteData([]byte(pathSpec)); err != nil {
		return nil, "", fmt.Errorf("sending path failed: %w", err)
	}
	status, err := c.reader.ReadUint()
	if err != nil {
		return nil, "", fmt.Errorf("reading status failed: %w", err)
	}
	switch status {
	case 0:
		kind, err := c.reader.ReadUint()
		if err != nil {
			return nil, "", fmt.Errorf("reading object kind failed: %w", err)
		}
		switch kind {
		case 1:
			// Tree
			count, err := c.reader.ReadUint()
			if err != nil {
				return nil, "", fmt.Errorf("reading entry count failed: %w", err)
			}
			var files []TreeEntry
			for range count {
				typeCode, err := c.reader.ReadUint()
				if err != nil {
					return nil, "", fmt.Errorf("error reading entry type: %w", err)
				}
				mode, err := c.reader.ReadUint()
				if err != nil {
					return nil, "", fmt.Errorf("error reading entry mode: %w", err)
				}
				size, err := c.reader.ReadUint()
				if err != nil {
					return nil, "", fmt.Errorf("error reading entry size: %w", err)
				}
				name, err := c.reader.ReadData()
				if err != nil {
					return nil, "", fmt.Errorf("error reading entry name: %w", err)
				}
				files = append(files, TreeEntry{
					Name:      string(name),
					Mode:      fmt.Sprintf("%06o", mode),
					Size:      size,
					IsFile:    typeCode == 2,
					IsSubtree: typeCode == 1,
				})
			}
			return files, "", nil
		case 2:
			// Blob
			content, err := c.reader.ReadData()
			if err != nil && !errors.Is(err, io.EOF) {
				return nil, "", fmt.Errorf("error reading file content: %w", err)
			}
			return nil, string(content), nil
		default:
			return nil, "", fmt.Errorf("unknown kind: %d", kind)
		}
	case 3:
		return nil, "", fmt.Errorf("path not found: %s", pathSpec)
	default:
		return nil, "", fmt.Errorf("unknown status code: %d", status)
	}
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package git2c
// Commit represents a single commit object retrieved from the git2d daemon.
type Commit struct {
	Hash    string
	Author  string
	Email   string
	Date    string
	Message string
}
// FilenameContents holds the filename and byte contents of a file, such as a README.
type FilenameContents struct {
	Filename string
	Content  []byte
}
// TreeEntry represents a file or directory entry within a Git tree object.
type TreeEntry struct {
	Name      string
	Mode      string
	Size      uint64
	IsFile    bool
	IsSubtree bool
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> // Package irc provides basic IRC bot functionality. package irc import ( "crypto/tls" "log/slog" "net" "go.lindenii.runxiyu.org/forge/forged/internal/misc" irc "go.lindenii.runxiyu.org/lindenii-irc" )
// Config contains IRC connection and identity settings for the bot. // This should usually be a part of the primary config struct.
type Config struct {
	Net   string `scfg:"net"`
	Addr  string `scfg:"addr"`
	TLS   bool   `scfg:"tls"`
	SendQ uint   `scfg:"sendq"`
	Nick  string `scfg:"nick"`
	User  string `scfg:"user"`
	Gecos string `scfg:"gecos"`
}
// Bot represents an IRC bot client that handles events and allows for sending messages.
type Bot struct {
	config            *Config
	ircSendBuffered   chan string
	ircSendDirectChan chan misc.ErrorBack[string]
}
// NewBot creates a new Bot instance using the provided configuration.
func NewBot(c *Config) (b *Bot) {
	b = &Bot{
		config: c,
	}
	return
}
// Connect establishes a new IRC session and starts handling incoming and outgoing messages. // This method blocks until an error occurs or the connection is closed.
func (b *Bot) Connect() error {
	var err error
	var underlyingConn net.Conn
	if b.config.TLS {
		underlyingConn, err = tls.Dial(b.config.Net, b.config.Addr, nil)
	} else {
		underlyingConn, err = net.Dial(b.config.Net, b.config.Addr)
	}
	if err != nil {
		return err
	}
	defer underlyingConn.Close()
	conn := irc.NewConn(underlyingConn)
	logAndWriteLn := func(s string) (n int, err error) {
		slog.Debug("irc tx", "line", s)
		return conn.WriteString(s + "\r\n")
	}
	_, err = logAndWriteLn("NICK " + b.config.Nick)
	if err != nil {
		return err
	}
	_, err = logAndWriteLn("USER " + b.config.User + " 0 * :" + b.config.Gecos)
	if err != nil {
		return err
	}
	readLoopError := make(chan error)
	writeLoopAbort := make(chan struct{})
	go func() {
		for {
			select {
			case <-writeLoopAbort:
				return
			default:
			}
			msg, line, err := conn.ReadMessage()
			if err != nil {
				readLoopError <- err
				return
			}
			slog.Debug("irc rx", "line", line)
			switch msg.Command {
			case "001":
				_, err = logAndWriteLn("JOIN #chat")
				if err != nil {
					readLoopError <- err
					return
				}
			case "PING":
				_, err = logAndWriteLn("PONG :" + msg.Args[0])
				if err != nil {
					readLoopError <- err
					return
				}
			case "JOIN":
				c, ok := msg.Source.(irc.Client)
				if !ok {
					slog.Error("unable to convert source of JOIN to client")
				}
				if c.Nick != b.config.Nick {
					continue
				}
			default:
			}
		}
	}()
	for {
		select {
		case err = <-readLoopError:
			return err
		case line := <-b.ircSendBuffered:
			_, err = logAndWriteLn(line)
			if err != nil {
				select {
				case b.ircSendBuffered <- line:
				default:
					slog.Error("unable to requeue message", "line", line)
				}
				writeLoopAbort <- struct{}{}
				return err
			}
		case lineErrorBack := <-b.ircSendDirectChan:
			_, err = logAndWriteLn(lineErrorBack.Content)
			lineErrorBack.ErrorChan <- err
			if err != nil {
				writeLoopAbort <- struct{}{}
				return err
			}
		}
	}
}
// SendDirect sends an IRC message directly to the connection and bypasses
// the buffering system.
func (b *Bot) SendDirect(line string) error {
	ech := make(chan error, 1)
	b.ircSendDirectChan <- misc.ErrorBack[string]{
		Content:   line,
		ErrorChan: ech,
	}
	return <-ech
}
// Send queues a message to be sent asynchronously via the buffered send queue. // If the queue is full, the message is dropped and an error is logged.
func (b *Bot) Send(line string) {
	select {
	case b.ircSendBuffered <- line:
	default:
		slog.Error("irc sendq full", "line", line)
	}
}
// TODO: Delay and warnings?
// ConnectLoop continuously attempts to maintain an IRC session. // If the connection drops, it automatically retries with no delay.
func (b *Bot) ConnectLoop() {
	b.ircSendBuffered = make(chan string, b.config.SendQ)
	b.ircSendDirectChan = make(chan misc.ErrorBack[string])
	for {
		err := b.Connect()
		slog.Error("irc session error", "error", err)
	}
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package misc
// ErrorBack wraps a value and a channel for communicating an associated error. // Typically used to get an error response after sending data across a channel.
type ErrorBack[T any] struct {
	Content   T
	ErrorChan chan error
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package misc import ( "io" "io/fs" "os" )
// DeployBinary copies the contents of a binary file to the target destination path. // The destination file is created with executable permissions.
func DeployBinary(src fs.File, dst string) (err error) {
	var dstFile *os.File
	if dstFile, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o755); err != nil {
		return err
	}
	defer dstFile.Close()
	_, err = io.Copy(dstFile, src)
	return err
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package misc
// FirstOrPanic returns the value or panics if the error is non-nil.
func FirstOrPanic[T any](v T, err error) T {
	if err != nil {
		panic(err)
	}
	return v
}
// NoneOrPanic panics if the provided error is non-nil.
func NoneOrPanic(err error) {
	if err != nil {
		panic(err)
	}
}
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
package misc
import (
	"errors"
	"net/http"
	"net/url"
	"strings"
)
var (
	ErrDupRefSpec = errors.New("duplicate ref spec")
	ErrNoRefSpec  = errors.New("no ref spec")
)
// getParamRefTypeName looks at the query parameters in an HTTP request and
// returns its ref name and type, if any.
func GetParamRefTypeName(request *http.Request) (retRefType, retRefName string, err error) {
	rawQuery := request.URL.RawQuery
	queryValues, err := url.ParseQuery(rawQuery)
	if err != nil {
		return
	}
	done := false
	for _, refType := range []string{"commit", "branch", "tag"} {
		refName, ok := queryValues[refType]
		if ok {
			if done {
				err = ErrDupRefSpec
				return
			}
			done = true
			if len(refName) != 1 {
				err = ErrDupRefSpec
				return
			}
			retRefName = refName[0]
			retRefType = refType
		}
	}
	if !done {
		err = ErrNoRefSpec
	}
	return
}
// ParseReqURI parses an HTTP request URL, and returns a slice of path segments
// and the query parameters. It handles %2F correctly.
func ParseReqURI(requestURI string) (segments []string, params url.Values, err error) {
	path, paramsStr, _ := strings.Cut(requestURI, "?")
	segments, err = PathToSegments(path)
	if err != nil {
		return
	}
	params, err = url.ParseQuery(paramsStr)
	return
}
// PathToSegments splits a path into unescaped segments. It handles %2F correctly.
func PathToSegments(path string) (segments []string, err error) {
	segments = strings.Split(strings.TrimPrefix(path, "/"), "/")
	for i, segment := range segments {
		segments[i], err = url.PathUnescape(segment)
		if err != nil {
			return
		}
	}
	return
}
// RedirectDir returns true and redirects the user to a version of the URL with
// a trailing slash, if and only if the request URL does not already have a
// trailing slash.
func RedirectDir(writer http.ResponseWriter, request *http.Request) bool {
	requestURI := request.RequestURI
	pathEnd := strings.IndexAny(requestURI, "?#")
	var path, rest string
	if pathEnd == -1 {
		path = requestURI
	} else {
		path = requestURI[:pathEnd]
		rest = requestURI[pathEnd:]
	}
	if !strings.HasSuffix(path, "/") {
		http.Redirect(writer, request, path+"/"+rest, http.StatusSeeOther)
		return true
	}
	return false
}
// RedirectNoDir returns true and redirects the user to a version of the URL
// without a trailing slash, if and only if the request URL has a trailing
// slash.
func RedirectNoDir(writer http.ResponseWriter, request *http.Request) bool {
	requestURI := request.RequestURI
	pathEnd := strings.IndexAny(requestURI, "?#")
	var path, rest string
	if pathEnd == -1 {
		path = requestURI
	} else {
		path = requestURI[:pathEnd]
		rest = requestURI[pathEnd:]
	}
	if strings.HasSuffix(path, "/") {
		http.Redirect(writer, request, strings.TrimSuffix(path, "/")+rest, http.StatusSeeOther)
		return true
	}
	return false
}
// RedirectUnconditionally unconditionally redirects the user back to the
// current page while preserving query parameters.
func RedirectUnconditionally(writer http.ResponseWriter, request *http.Request) {
	requestURI := request.RequestURI
	pathEnd := strings.IndexAny(requestURI, "?#")
	var path, rest string
	if pathEnd == -1 {
		path = requestURI
	} else {
		path = requestURI[:pathEnd]
		rest = requestURI[pathEnd:]
	}
	http.Redirect(writer, request, path+rest, http.StatusSeeOther)
}
// SegmentsToURL joins URL segments to the path component of a URL.
// Each segment is escaped properly first.
func SegmentsToURL(segments []string) string {
	for i, segment := range segments {
		segments[i] = url.PathEscape(segment)
	}
	return strings.Join(segments, "/")
}
// AnyContain returns true if and only if ss contains a string that contains c.
func AnyContain(ss []string, c string) bool {
	for _, s := range ss {
		if strings.Contains(s, c) {
			return true
		}
	}
	return false
}
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
package oldgit
import (
	"errors"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/object"
)
// CommitToPatch creates an [object.Patch] from the first parent of a given
// [object.Commit].
//
// TODO: This function should be deprecated as it only diffs with the first
// parent and does not correctly handle merge commits.
func CommitToPatch(commit *object.Commit) (parentCommitHash plumbing.Hash, patch *object.Patch, err error) {
	var parentCommit *object.Commit
	var commitTree *object.Tree
	parentCommit, err = commit.Parent(0)
	switch {
	case errors.Is(err, object.ErrParentNotFound):
		if commitTree, err = commit.Tree(); err != nil {
			return
		}
		if patch, err = NullTree.Patch(commitTree); err != nil {
			return
		}
	case err != nil:
		return
	default:
		parentCommitHash = parentCommit.Hash
		if patch, err = parentCommit.Patch(commit); err != nil {
			return
		}
	}
	return
}
// NullTree is a tree object that is empty and has no hash.
var NullTree object.Tree //nolint:gochecknoglobals
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package render import ( "bytes" "html/template" chromaHTML "github.com/alecthomas/chroma/v2/formatters/html" chromaLexers "github.com/alecthomas/chroma/v2/lexers" chromaStyles "github.com/alecthomas/chroma/v2/styles" )
// Highlight returns HTML with syntax highlighting for the given file content, // using Chroma. The lexer is selected based on the filename. // If tokenization or formatting fails, a fallback <pre> block is returned with the error.
func Highlight(filename, content string) template.HTML {
	lexer := chromaLexers.Match(filename)
	if lexer == nil {
		lexer = chromaLexers.Fallback
	}
	iterator, err := lexer.Tokenise(nil, content)
	if err != nil {
		return template.HTML("<pre>Error tokenizing file: " + err.Error() + "</pre>") //#nosec G203`
	}
	var buf bytes.Buffer
	style := chromaStyles.Get("autumn")
	formatter := chromaHTML.New(
		chromaHTML.WithClasses(true),
		chromaHTML.TabWidth(8),
	)
	if err := formatter.Format(&buf, style, iterator); err != nil {
		return template.HTML("<pre>Error formatting file: " + err.Error() + "</pre>") //#nosec G203
	}
	return template.HTML(buf.Bytes()) //#nosec G203
}
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> package web import ( "html/template" "net/http" )
// ErrorPage404 renders a 404 Not Found error page using the "404" template.
func ErrorPage404(templates *template.Template, w http.ResponseWriter, params map[string]any) {
	w.WriteHeader(http.StatusNotFound)
	_ = templates.ExecuteTemplate(w, "404", params)
}
// ErrorPage400 renders a 400 Bad Request error page using the "400" template. // The error message is passed via the "complete_error_msg" template param.
func ErrorPage400(templates *template.Template, w http.ResponseWriter, params map[string]any, msg string) {
	w.WriteHeader(http.StatusBadRequest)
	params["complete_error_msg"] = msg
	_ = templates.ExecuteTemplate(w, "400", params)
}
// ErrorPage400Colon renders a 400 Bad Request error page telling the user // that we migrated from : to -.
func ErrorPage400Colon(templates *template.Template, w http.ResponseWriter, params map[string]any) {
	w.WriteHeader(http.StatusBadRequest)
	_ = templates.ExecuteTemplate(w, "400_colon", params)
}
// ErrorPage403 renders a 403 Forbidden error page using the "403" template. // The error message is passed via the "complete_error_msg" template param.
func ErrorPage403(templates *template.Template, w http.ResponseWriter, params map[string]any, msg string) {
	w.WriteHeader(http.StatusForbidden)
	params["complete_error_msg"] = msg
	_ = templates.ExecuteTemplate(w, "403", params)
}
// ErrorPage451 renders a 451 Unavailable For Legal Reasons error page using the "451" template. // The error message is passed via the "complete_error_msg" template param.
func ErrorPage451(templates *template.Template, w http.ResponseWriter, params map[string]any, msg string) {
	w.WriteHeader(http.StatusUnavailableForLegalReasons)
	params["complete_error_msg"] = msg
	_ = templates.ExecuteTemplate(w, "451", params)
}
// ErrorPage500 renders a 500 Internal Server Error page using the "500" template. // The error message is passed via the "complete_error_msg" template param.
func ErrorPage500(templates *template.Template, w http.ResponseWriter, params map[string]any, msg string) {
	w.WriteHeader(http.StatusInternalServerError)
	params["complete_error_msg"] = msg
	_ = templates.ExecuteTemplate(w, "500", params)
}
// ErrorPage501 renders a 501 Not Implemented error page using the "501" template.
func ErrorPage501(templates *template.Template, w http.ResponseWriter, params map[string]any) {
	w.WriteHeader(http.StatusNotImplemented)
	_ = templates.ExecuteTemplate(w, "501", params)
}