From 6f5e22e764283262ae8c6519bb030766db0fd35b Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 6 Apr 2025 09:58:02 +0800 Subject: Add more documentation comments --- forged/internal/database/database.go | 5 +++++ forged/internal/embed/embed.go | 6 ++++++ forged/internal/git2c/client.go | 7 +++++-- forged/internal/git2c/cmd_index.go | 2 ++ forged/internal/git2c/cmd_treeraw.go | 2 ++ forged/internal/git2c/git_types.go | 3 +++ forged/internal/irc/bot.go | 11 ++++++++++- forged/internal/misc/back.go | 2 ++ forged/internal/misc/deploy.go | 2 ++ forged/internal/misc/panic.go | 2 ++ forged/internal/misc/url.go | 1 + forged/internal/oldgit/patch.go | 1 + forged/internal/render/chroma.go | 3 +++ forged/internal/web/error_pages.go | 12 ++++++++++++ 14 files changed, 56 insertions(+), 3 deletions(-) diff --git a/forged/internal/database/database.go b/forged/internal/database/database.go index a482624..b995adc 100644 --- a/forged/internal/database/database.go +++ b/forged/internal/database/database.go @@ -10,10 +10,15 @@ import ( "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 diff --git a/forged/internal/embed/embed.go b/forged/internal/embed/embed.go index c9eeeb3..1f0dcdf 100644 --- a/forged/internal/embed/embed.go +++ b/forged/internal/embed/embed.go @@ -6,9 +6,15 @@ 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 diff --git a/forged/internal/git2c/client.go b/forged/internal/git2c/client.go index d178c47..82454d1 100644 --- a/forged/internal/git2c/client.go +++ b/forged/internal/git2c/client.go @@ -11,13 +11,15 @@ import ( "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 { @@ -28,13 +30,14 @@ func NewClient(socketPath string) (*Client, error) { 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() diff --git a/forged/internal/git2c/cmd_index.go b/forged/internal/git2c/cmd_index.go index a705a63..8862b2c 100644 --- a/forged/internal/git2c/cmd_index.go +++ b/forged/internal/git2c/cmd_index.go @@ -10,6 +10,8 @@ import ( "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) diff --git a/forged/internal/git2c/cmd_treeraw.go b/forged/internal/git2c/cmd_treeraw.go index c93480a..492cb84 100644 --- a/forged/internal/git2c/cmd_treeraw.go +++ b/forged/internal/git2c/cmd_treeraw.go @@ -9,6 +9,8 @@ import ( "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) diff --git a/forged/internal/git2c/git_types.go b/forged/internal/git2c/git_types.go index da685bf..bf13f05 100644 --- a/forged/internal/git2c/git_types.go +++ b/forged/internal/git2c/git_types.go @@ -3,6 +3,7 @@ package git2c +// Commit represents a single commit object retrieved from the git2d daemon. type Commit struct { Hash string Author string @@ -11,11 +12,13 @@ type Commit struct { 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 diff --git a/forged/internal/irc/bot.go b/forged/internal/irc/bot.go index 89de024..046799f 100644 --- a/forged/internal/irc/bot.go +++ b/forged/internal/irc/bot.go @@ -13,6 +13,8 @@ import ( 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"` @@ -23,12 +25,14 @@ type Config struct { 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, @@ -36,6 +40,8 @@ func NewBot(c *Config) (b *Bot) { 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 @@ -148,6 +154,8 @@ func (b *Bot) SendDirect(line string) error { 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: @@ -156,7 +164,8 @@ func (b *Bot) Send(line string) { } } -// 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]) diff --git a/forged/internal/misc/back.go b/forged/internal/misc/back.go index ef4ed22..5351359 100644 --- a/forged/internal/misc/back.go +++ b/forged/internal/misc/back.go @@ -3,6 +3,8 @@ 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 diff --git a/forged/internal/misc/deploy.go b/forged/internal/misc/deploy.go index 0f24f49..3ee5f92 100644 --- a/forged/internal/misc/deploy.go +++ b/forged/internal/misc/deploy.go @@ -9,6 +9,8 @@ import ( "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 { diff --git a/forged/internal/misc/panic.go b/forged/internal/misc/panic.go index 94cd47a..34c49c5 100644 --- a/forged/internal/misc/panic.go +++ b/forged/internal/misc/panic.go @@ -3,6 +3,7 @@ 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) @@ -10,6 +11,7 @@ func FirstOrPanic[T any](v T, err error) T { return v } +// NoneOrPanic panics if the provided error is non-nil. func NoneOrPanic(err error) { if err != nil { panic(err) diff --git a/forged/internal/misc/url.go b/forged/internal/misc/url.go index b77d8ce..0f9dc04 100644 --- a/forged/internal/misc/url.go +++ b/forged/internal/misc/url.go @@ -60,6 +60,7 @@ func ParseReqURI(requestURI string) (segments []string, params url.Values, err e 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, "/"), "/") diff --git a/forged/internal/oldgit/patch.go b/forged/internal/oldgit/patch.go index 30bf8e8..fc8ef98 100644 --- a/forged/internal/oldgit/patch.go +++ b/forged/internal/oldgit/patch.go @@ -39,4 +39,5 @@ func CommitToPatch(commit *object.Commit) (parentCommitHash plumbing.Hash, patch return } +// NullTree is a tree object that is empty and has no hash. var NullTree object.Tree //nolint:gochecknoglobals diff --git a/forged/internal/render/chroma.go b/forged/internal/render/chroma.go index c1a1869..64bfde0 100644 --- a/forged/internal/render/chroma.go +++ b/forged/internal/render/chroma.go @@ -12,6 +12,9 @@ import ( 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
 block is returned with the error.
 func Highlight(filename, content string) template.HTML {
 	lexer := chromaLexers.Match(filename)
 	if lexer == nil {
diff --git a/forged/internal/web/error_pages.go b/forged/internal/web/error_pages.go
index 200e9d3..2ba9a1a 100644
--- a/forged/internal/web/error_pages.go
+++ b/forged/internal/web/error_pages.go
@@ -8,40 +8,52 @@ import (
 	"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)
-- 
cgit v1.2.3