aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-04-06 09:58:02 +0800
committerRunxi Yu <me@runxiyu.org>2025-04-06 09:58:02 +0800
commit6f5e22e764283262ae8c6519bb030766db0fd35b (patch)
treec56038bd7b5dc31d5bae5dd6e323688725c5262e
parentFix load ordering issue that causes the forge title to disappear (diff)
downloadforge-6f5e22e764283262ae8c6519bb030766db0fd35b.tar.gz
forge-6f5e22e764283262ae8c6519bb030766db0fd35b.tar.zst
forge-6f5e22e764283262ae8c6519bb030766db0fd35b.zip
Add more documentation comments
-rw-r--r--forged/internal/database/database.go5
-rw-r--r--forged/internal/embed/embed.go6
-rw-r--r--forged/internal/git2c/client.go7
-rw-r--r--forged/internal/git2c/cmd_index.go2
-rw-r--r--forged/internal/git2c/cmd_treeraw.go2
-rw-r--r--forged/internal/git2c/git_types.go3
-rw-r--r--forged/internal/irc/bot.go11
-rw-r--r--forged/internal/misc/back.go2
-rw-r--r--forged/internal/misc/deploy.go2
-rw-r--r--forged/internal/misc/panic.go2
-rw-r--r--forged/internal/misc/url.go1
-rw-r--r--forged/internal/oldgit/patch.go1
-rw-r--r--forged/internal/render/chroma.go3
-rw-r--r--forged/internal/web/error_pages.go12
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 <pre> 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)