Documentation ¶
Overview ¶
gwi stands for Git Web Interface, so it lets you customize the appearance of your git repositories using templates. gwi is intended to be run on servers where your bare git repositories are located, so it can detect and render them correctly.
gwi works in a simple way: it is a web server, and your request's path points which user and repo are selected, i.e.:
GET root/user/repo/action/args
selects the repository named repo from the user named user. Those are just hierarchical abstractions. Then the next folder in the path defines the template it will run, in this case the action, so gwi will execute a template named action.html with the selected repo information available. Lastly, everything that comes after action is part of args, and it is passed to templates under the Args field.
Some paths have special purposes and cannot be used by templates, they are:
- /user/repo/zip: for making archives
- /user/repo/info/refs: this and the following are used by git
- /user/repo/git-receive-pack
- /user/repo/git-upload-pack
Creating template files with the names above will disable some features.
User authentication ¶
gwi currently only supports HTTP Basic flow, authorization/authentication is only needed in the git-recive-pack handler. For user validation this project provides the Vault interface, which you should implement. Consult the FileVault struct for an example.
Template functions ¶
This package provides functions that you can call in your templates, letting you query the data you want in an efficient way. Currently we export the following functions:
- usage
- users
- repos
- head
- thread
- mails
- desc
- branches
- tags
- log
- commits
- commit
- tree
- files
- file
- markdown
Which can be called on templates using the standard template syntax.
To see complete details about them see FuncMapTempl.
Handlers ¶
gwi comes with 2 handlers: Main and List, which are meant to be used in different situations. See their respective docs for their use.
The default branch for git is main.
Examples ¶
The most simple way of using this is initializing and using the handle function:
package main import ( "net/http" "blmayer.dev/gwi" ) func main() { // init user vault v, err := NewFileVault("users.json", "--salt--") // handle error // gwi config struct c := gwi.Config{ Root: "path/to/git/folder", PagesRoot: "path/to/html-templates", ... } g, _ := gwi.NewFromConfig(c, v) // handle error err := http.ListenAndServe(":8080", g.Handle()) // handle err }
Another good example is [main_test.go].
Using templates provided:
Repo has {{commits .Ref}} commits.
Will print the number of commits on the repo.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var FuncMapTempl = map[string]any{ "usage": diskUsage, "users": func() []string { return nil }, "repos": func(user string) []string { return nil }, "head": func() *plumbing.Reference { return nil }, "threads": func(section string) []any { return nil }, "mails": func(thread string) []any { return nil }, "desc": func(ref plumbing.Hash) string { return "" }, "branches": func(ref plumbing.Hash) []*plumbing.Reference { return nil }, "tags": func() []*plumbing.Reference { return nil }, "log": func(ref plumbing.Hash) []*object.Commit { return nil }, "commits": func(ref plumbing.Hash) int { return -1 }, "commit": func(ref plumbing.Hash) *object.Commit { return nil }, "tree": func(ref plumbing.Hash) []File { return nil }, "files": func(ref plumbing.Hash) int { return -1 }, "file": func(ref plumbing.Hash, name string) string { return "" }, "markdown": mdown, "wrap": wrap, }
FuncMapTempl gives the signatures for all functions available on templates.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { Domain string MailAddress string PagesRoot string Root string LogLevel slog.Level Functions map[string]func(p ...any) any }
Config is used to configure the gwi application, things like Root and PagesRoot are the central part that make gwi work. Domain, MailAddress and Functions are mostly used to enhance the information displayed on templates.
type FileVault ¶
FileVault is one example implementation that reads users from a JSON file. It implements the Vault interface, which is used to authorize/ authenticate users.
func NewFileVault ¶
NewFileVault creates a Vault that uses the file at path as user database. The salt parameter is used to fuzz user's passwords.
type Gwi ¶
type Gwi struct {
// contains filtered or unexported fields
}
GWI is the git instance, it exports the handlers that are used to handle git requests
func (*Gwi) Handle ¶
Handle returns all handlers defined here, it should be used to handle requests, as this provides the list and main handlers in the correct path.
func (*Gwi) ListHandler ¶
func (g *Gwi) ListHandler(w http.ResponseWriter, r *http.Request)
ListHandler is used for listing users, or repos for a user given in the URL path, this handler is useful for creating listings of projects, as this is very light on reads, and can be executed more often. It populates the template data with just User and Repo fields, along with 2 functions: users and repos.
func (*Gwi) MainHandler ¶
func (g *Gwi) MainHandler(w http.ResponseWriter, r *http.Request)
MainHandler is the handler used to display information about a repository. It contains all functions defined it FuncMapTempl with the correct user and repo selected; and provides the complete Info struct as data to the template. This handler is used to display data like commits, files, branches and tags about a given repo.
type Info ¶
type Info struct { User string Repo string Ref plumbing.Hash RefName string Args string Git *git.Repository }
Info is the structure that is passed as data to templates being executed. The values are filled with the selected repo and user given on the URL.
type User ¶
User interface represents what a user should provide at a minimum. This interface is available on templates and is also used internaly.