docs: code comments

Signed-off-by: jolheiser <john.olheiser@gmail.com>
ffdhall
jolheiser 2024-01-18 22:41:16 -06:00
parent 5f408c1fb1
commit 22cdff623a
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
9 changed files with 57 additions and 21 deletions

View File

@ -51,6 +51,7 @@ func PathExists(path string) (bool, error) {
return true, err
}
// Tree returns the git tree at a given ref/rev
func (r Repo) Tree(ref string) (*object.Tree, error) {
g, err := r.Git()
if err != nil {
@ -70,6 +71,7 @@ func (r Repo) Tree(ref string) (*object.Tree, error) {
return c.Tree()
}
// FileInfo is the information for a file in a tree
type FileInfo struct {
Path string
IsDir bool
@ -77,10 +79,13 @@ type FileInfo struct {
Size string
}
// Name returns the last part of the FileInfo.Path
func (f FileInfo) Name() string {
return filepath.Base(f.Path)
}
// Dir returns the given dirpath in the given ref as a slice of FileInfo
// Sorted alphabetically, dirs first
func (r Repo) Dir(ref, path string) ([]FileInfo, error) {
t, err := r.Tree(ref)
if err != nil {
@ -119,6 +124,7 @@ func (r Repo) Dir(ref, path string) ([]FileInfo, error) {
return fis, nil
}
// FileContent returns the content of a file in the git tree at a given ref/rev
func (r Repo) FileContent(ref, file string) (string, error) {
t, err := r.Tree(ref)
if err != nil {

View File

@ -8,11 +8,13 @@ import (
"path/filepath"
)
// RepoMeta is the meta information a Repo can have
type RepoMeta struct {
Description string `json:"description"`
Private bool `json:"private"`
}
// Update updates meta given another RepoMeta
func (m *RepoMeta) Update(meta RepoMeta) error {
data, err := json.Marshal(meta)
if err != nil {
@ -25,13 +27,14 @@ func (r Repo) metaPath() string {
return filepath.Join(r.path, "ugit.json")
}
// SaveMeta saves the meta info of a Repo
func (r Repo) SaveMeta() error {
// Compatibility with gitweb, because why not
// Ignoring the error because it's not technically detrimental to ugit
desc, err := os.Create(filepath.Join(r.path, "description"))
if err == nil {
defer desc.Close()
desc.WriteString(r.Meta.Description)
_, _ = desc.WriteString(r.Meta.Description)
}
fi, err := os.Create(r.metaPath())

View File

@ -20,16 +20,19 @@ import (
"github.com/go-git/go-git/v5/utils/ioutil"
)
// ReadWriteContexter is the interface required to operate on git protocols
type ReadWriteContexter interface {
io.ReadWriteCloser
Context() context.Context
}
// Protocol handles the endpoint and server of the git protocols
type Protocol struct {
endpoint *transport.Endpoint
server transport.Transport
}
// NewProtocol constructs a Protocol for a given repo
func NewProtocol(repoPath string) (Protocol, error) {
endpoint, err := transport.NewEndpoint("/")
if err != nil {
@ -44,6 +47,7 @@ func NewProtocol(repoPath string) (Protocol, error) {
}, nil
}
// HTTPInfoRefs handles the inforef part of the HTTP protocol
func (p Protocol) HTTPInfoRefs(rwc ReadWriteContexter) error {
session, err := p.server.NewUploadPackSession(p.endpoint, nil)
if err != nil {
@ -73,10 +77,12 @@ func (p Protocol) infoRefs(rwc ReadWriteContexter, session transport.UploadPackS
return nil
}
// HTTPUploadPack handles the upload-pack process for HTTP
func (p Protocol) HTTPUploadPack(rwc ReadWriteContexter) error {
return p.uploadPack(rwc, false)
}
// SSHUploadPack handles the upload-pack process for SSH
func (p Protocol) SSHUploadPack(rwc ReadWriteContexter) error {
return p.uploadPack(rwc, true)
}
@ -112,6 +118,7 @@ func (p Protocol) uploadPack(rwc ReadWriteContexter, ssh bool) error {
return nil
}
// SSHReceivePack handles the receive-pack process for SSH
func (p Protocol) SSHReceivePack(rwc ReadWriteContexter, repo *Repo) error {
buf := bufio.NewReader(rwc)
@ -213,6 +220,7 @@ func handlePushOptions(repo *Repo, opts []*packp.Option) error {
return nil
}
// UpdateServerInfo handles updating server info for the git repo
func UpdateServerInfo(repo string) error {
r, err := git.PlainOpen(repo)
if err != nil {

View File

@ -15,15 +15,18 @@ import (
"github.com/go-git/go-git/v5/plumbing/object"
)
// Repo is a git repository
type Repo struct {
path string
Meta RepoMeta
}
// Name returns the human-friendly name, the dir name without the .git suffix
func (r Repo) Name() string {
return strings.TrimSuffix(filepath.Base(r.path), ".git")
}
// NewRepo constructs a Repo given a dir and name
func NewRepo(dir, name string) (*Repo, error) {
if !strings.HasSuffix(name, ".git") {
name += ".git"
@ -98,6 +101,7 @@ type Commit struct {
Author string
Email string
When time.Time
// Extra
Stats CommitStats
Patch string
@ -125,19 +129,22 @@ type CommitFileEntry struct {
Commit string
}
// Short returns the first eight characters of the SHA
func (c Commit) Short() string {
return c.SHA[:8]
}
// Summary returns the first line of the commit, suitable for a <summary>
func (c Commit) Summary() string {
return strings.Split(c.Message, "\n")[0]
}
// Details returns all lines *after* the first, suitable for <details>
func (c Commit) Details() string {
return strings.Join(strings.Split(c.Message, "\n")[1:], "\n")
}
// Commit gets a specific commit by SHA
// Commit gets a specific commit by SHA, including all commit information
func (r Repo) Commit(sha string) (Commit, error) {
repo, err := r.Git()
if err != nil {
@ -147,7 +154,7 @@ func (r Repo) Commit(sha string) (Commit, error) {
return commit(repo, sha, true)
}
// LastCommit returns the last commit of the repo
// LastCommit returns the last commit of the repo without any extra information
func (r Repo) LastCommit() (Commit, error) {
repo, err := r.Git()
if err != nil {
@ -313,15 +320,8 @@ func (r Repo) Tags() ([]Tag, error) {
var tags []Tag
if err := tgs.ForEach(func(tag *plumbing.Reference) error {
obj, err := repo.TagObject(tag.Hash())
switch err {
case nil:
tags = append(tags, Tag{
Name: obj.Name,
Annotation: obj.Message,
Signature: obj.PGPSignature,
When: obj.Tagger.When,
})
case plumbing.ErrObjectNotFound:
switch {
case errors.Is(err, plumbing.ErrObjectNotFound):
commit, err := repo.CommitObject(tag.Hash())
if err != nil {
return err
@ -332,6 +332,13 @@ func (r Repo) Tags() ([]Tag, error) {
Signature: commit.PGPSignature,
When: commit.Author.When,
})
case err == nil:
tags = append(tags, Tag{
Name: obj.Name,
Annotation: obj.Message,
Signature: obj.PGPSignature,
When: obj.Tagger.When,
})
default:
return err
}

View File

@ -6,12 +6,11 @@ import (
"bytes"
_ "embed"
"fmt"
"go.jolheiser.com/ugit/internal/html/markup"
"go/format"
"os"
"os/exec"
"go.jolheiser.com/ugit/internal/html"
"github.com/alecthomas/chroma/v2/styles"
)
@ -33,6 +32,7 @@ func main() {
}
}
// Generate tailwind code from templ templates and combine with other misc CSS
func tailwind() error {
fmt.Println("generating tailwind...")
@ -48,13 +48,13 @@ func tailwind() error {
fmt.Println("generating chroma styles...")
latte := styles.Get("catppuccin-latte")
if err := html.Formatter.WriteCSS(tmp, latte); err != nil {
if err := markup.Formatter.WriteCSS(tmp, latte); err != nil {
return err
}
tmp.WriteString("@media (prefers-color-scheme: dark) {")
mocha := styles.Get("catppuccin-mocha")
if err := html.Formatter.WriteCSS(tmp, mocha); err != nil {
if err := markup.Formatter.WriteCSS(tmp, mocha); err != nil {
return err
}
tmp.WriteString("}")

View File

@ -1,4 +1,4 @@
package html
package markup
import (
"io"
@ -10,6 +10,7 @@ import (
)
var (
// Formatter is the default formatter
Formatter = html.New(
html.WithLineNumbers(true),
html.WithLinkableLineNumbers(true, "L"),
@ -19,6 +20,7 @@ var (
basicFormatter = html.New(
html.WithClasses(true),
)
// Code is the entrypoint for formatting
Code = code{}
)
@ -44,6 +46,7 @@ func (c code) setup(source []byte, fileName string) (chroma.Iterator, *chroma.St
return iter, style, nil
}
// Basic formats code without any extras
func (c code) Basic(source []byte, fileName string, writer io.Writer) error {
iter, style, err := c.setup(source, fileName)
if err != nil {
@ -52,6 +55,7 @@ func (c code) Basic(source []byte, fileName string, writer io.Writer) error {
return basicFormatter.Format(writer, style, iter)
}
// Convert formats code with line numbers, links, etc.
func (c code) Convert(source []byte, fileName string, writer io.Writer) error {
iter, style, err := c.setup(source, fileName)
if err != nil {

View File

@ -1,4 +1,4 @@
package html
package markup
import (
"bytes"
@ -48,6 +48,7 @@ var markdown = goldmark.New(
),
)
// Readme transforms a readme, potentially from markdown, into HTML
func Readme(repo *git.Repo, ref, path string) (string, error) {
var readme string
var err error
@ -98,6 +99,9 @@ type markdownContext struct {
type astTransformer struct{}
// Transform does two main things
// 1. Changes images to work relative to the source and wraps them in links
// 2. Changes links to work relative to the source
func (a astTransformer) Transform(node *ast.Document, _ text.Reader, pc parser.Context) {
_ = ast.Walk(node, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {

View File

@ -20,14 +20,17 @@ func (h httpError) Unwrap() error {
return h.err
}
// Error returns a generic 500 error
func Error(err error) httpError {
return Status(err, http.StatusInternalServerError)
}
// Status returns a set status with the error
func Status(err error, status int) httpError {
return httpError{err: err, status: status}
}
// Handler transforms an http handler + error into a stdlib handler
func Handler(fn func(w http.ResponseWriter, r *http.Request) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil {

View File

@ -3,6 +3,7 @@ package http
import (
"bytes"
"errors"
"go.jolheiser.com/ugit/internal/html/markup"
"io/fs"
"mime"
"net/http"
@ -46,7 +47,7 @@ func (rh repoHandler) repoTree(ref, path string) http.HandlerFunc {
return httperr.Error(err)
}
readmeContent, err := html.Readme(repo, ref, path)
readmeContent, err := markup.Readme(repo, ref, path)
if err != nil {
return httperr.Error(err)
}
@ -92,7 +93,7 @@ func (rh repoHandler) repoFile(w http.ResponseWriter, r *http.Request, repo *git
}
var buf bytes.Buffer
if err := html.Code.Convert([]byte(content), filepath.Base(path), &buf); err != nil {
if err := markup.Code.Convert([]byte(content), filepath.Base(path), &buf); err != nil {
return httperr.Error(err)
}
@ -195,7 +196,7 @@ func (rh repoHandler) repoCommit(w http.ResponseWriter, r *http.Request) error {
for idx, p := range commit.Files {
var patch bytes.Buffer
if err := html.Code.Basic([]byte(p.Patch), "commit.patch", &patch); err != nil {
if err := markup.Code.Basic([]byte(p.Patch), "commit.patch", &patch); err != nil {
return httperr.Error(err)
}
commit.Files[idx].Patch = patch.String()