gwi

package module
v0.22.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2023 License: GPL-2.0 Imports: 25 Imported by: 0

README

GWI stands for Git Web Interface, that is it delivers a ready to use visualization and management tool atop of your git repositories.

With GWI you can easily host your own git platform customized to your needs. Some features are:

  • Easy to setup
  • Pages are templates you can customize
  • Does not depend on git or CGI scripts
  • Lightweight
  • Free
  • Under active development

This project is in early stages of development, and some features may be missing. If you want to request a feature or report a bug, follow the instructions at the author's git.

Go Report Card Go Reference

If you like to star it on GitHub, we have a mirror repo there: GitHub

Thank you!

Usage

The simplest way of using this project is the following example:

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
}

Examples

Users

To get a list of your users is simple:

<ul>
	{{range users}}
	<li>{{.}}</li>
	{{end}}
</ul>
File tree

To get the file tree for the current reference:

<table>
    <tr>
        <th>Mode</th>
        <th>Size</th>
        <th>Name</th>
    </tr>
    {{range tree .Ref}}
    <tr>
        <td>{{.Mode}}</td>
        <td>{{.Size}}</td>
	<td>{{.Name}}</td>
    </tr>
    {{end}}
</table>

Will print a nice list of your project files.

Commits

Using the functions commits and commit you're able to see a list of commits and check details of each one:

<table>
    <tr>
        <th>Time</th>
        <th>Author</th>
        <th>Message</th>
    </tr>
    {{range commits .Ref}}
    <tr>
        <td>{{.Author.When.String}}</td>
        <td>{{.Author.Name}}</td>
	<td>{{.Message}}</td>
    </tr>
    {{end}}
</table>

To get the list, and the following show a commit's details:

{{with commit .Ref}}

<p><b>Commited at:</b> {{.Committer.When.String}}</p>
<p><b>Author:</b> {{.Committer.Name}} ({{.Committer.Email}})</p>
<p><b>Message:</b></p>
<p>{{.Message}}</p>
{{end}}

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

View Source
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 File

type File struct {
	*object.File
	Size int64
}

type FileVault

type FileVault struct {
	Users map[string]User
	// contains filtered or unexported fields
}

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

func NewFileVault(path, salt string) (FileVault, error)

NewFileVault creates a Vault that uses the file at path as user database. The salt parameter is used to fuzz user's passwords.

func (FileVault) GetUser

func (f FileVault) GetUser(login string) User

func (FileVault) Validate

func (f FileVault) Validate(login, pass string) bool

Validate is used to check if a user and pass combination is valid. This is used on git receive pack. User and pass parameters are received from HTTP Basic authorization flow.

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 NewFromConfig

func NewFromConfig(cfg Config, vault Vault) (Gwi, error)

func (*Gwi) Handle

func (g *Gwi) Handle() http.Handler

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 Usage

type Usage struct {
	Total int
	Free  int
	Used  int
}

type User

type User interface {
	Email() string
	Login() string
	Pass() string
}

User interface represents what a user should provide at a minimum. This interface is available on templates and is also used internaly.

type Vault

type Vault interface {
	GetUser(login string) User
	Validate(login, pass string) bool
}

Vault is used to authenticate write calls to git repositories, the Vault implementation FileVault is a simple example that uses salt and hashes to store and validate users. In real applications you should use a better approache and implement your own Vault interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL