Skip to content

Commit

Permalink
Merge branch 'master' into sshurl
Browse files Browse the repository at this point in the history
  • Loading branch information
quaintdev authored Mar 22, 2023
2 parents b2a5ad4 + d1774f5 commit 880b42a
Show file tree
Hide file tree
Showing 20 changed files with 251 additions and 71 deletions.
11 changes: 11 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package config
import (
"fmt"
"os"
"path/filepath"

"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -40,5 +41,15 @@ func Read(f string) (*Config, error) {
return nil, fmt.Errorf("parsing config: %w", err)
}

if c.Repo.ScanPath, err = filepath.Abs(c.Repo.ScanPath); err != nil {
return nil, err
}
if c.Dirs.Templates, err = filepath.Abs(c.Dirs.Templates); err != nil {
return nil, err
}
if c.Dirs.Static, err = filepath.Abs(c.Dirs.Static); err != nil {
return nil, err
}

return &c, nil
}
25 changes: 25 additions & 0 deletions contrib/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM golang:1.19-alpine AS builder

WORKDIR /app

COPY . ./

RUN apk add gcc musl-dev libc-dev

RUN go mod download
RUN go mod verify
RUN go build -o legit

FROM alpine:latest

WORKDIR /app

COPY static ./static
COPY templates ./templates
COPY config.yaml ./
COPY --from=builder /app/legit ./

EXPOSE 5555

CMD ["./legit"]

15 changes: 15 additions & 0 deletions contrib/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: "3"
services:
legit:
container_name: legit
build:
context: ../
dockerfile: ../contrib/Dockerfile
restart: unless-stopped
ports:
- "5555:5555"
volumes:
- /var/www/git:/var/www/git
- ../config.yaml:/app/config.yaml
- ../static:/app/static
- ../templates:/app/templates
28 changes: 28 additions & 0 deletions git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package git

import (
"fmt"
"sort"

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
Expand All @@ -13,6 +14,21 @@ type GitRepo struct {
h plumbing.Hash
}

type TagList []*object.Tag

func (self TagList) Len() int {
return len(self)
}

func (self TagList) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
}

// sorting tags in reverse chronological order
func (self TagList) Less(i, j int) bool {
return self[i].Tagger.When.After(self[j].Tagger.When)
}

func Open(path string, ref string) (*GitRepo, error) {
var err error
g := GitRepo{}
Expand Down Expand Up @@ -94,10 +110,22 @@ func (g *GitRepo) Tags() ([]*object.Tag, error) {
tags := []*object.Tag{}

_ = ti.ForEach(func(t *object.Tag) error {
for i, existing := range tags {
if existing.Name == t.Name {
if t.Tagger.When.After(existing.Tagger.When) {
tags[i] = t
}
return nil
}
}
tags = append(tags, t)
return nil
})

var tagList TagList
tagList = tags
sort.Sort(tagList)

return tags, nil
}

Expand Down
10 changes: 6 additions & 4 deletions git/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (g *GitRepo) FileTree(path string) ([]NiceTree, error) {
}

if path == "" {
files = makeNiceTree(tree.Entries)
files = makeNiceTree(tree)
} else {
o, err := tree.FindEntry(path)
if err != nil {
Expand All @@ -32,7 +32,7 @@ func (g *GitRepo) FileTree(path string) ([]NiceTree, error) {
return nil, err
}

files = makeNiceTree(subtree.Entries)
files = makeNiceTree(subtree)
}
}

Expand All @@ -48,15 +48,17 @@ type NiceTree struct {
IsSubtree bool
}

func makeNiceTree(es []object.TreeEntry) []NiceTree {
func makeNiceTree(t *object.Tree) []NiceTree {
nts := []NiceTree{}

for _, e := range es {
for _, e := range t.Entries {
mode, _ := e.Mode.ToOSFileMode()
sz, _ := t.Size(e.Name)
nts = append(nts, NiceTree{
Name: e.Name,
Mode: mode.String(),
IsFile: e.Mode.IsFile(),
Size: sz,
})
}

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/go-git/go-git/v5 v5.5.1
github.com/microcosm-cc/bluemonday v1.0.21
github.com/russross/blackfriday/v2 v2.1.0
golang.org/x/sys v0.3.0
golang.org/x/sys v0.5.0
gopkg.in/yaml.v3 v3.0.0
)

Expand All @@ -32,7 +32,7 @@ require (
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.4.0 // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/tools v0.4.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
Expand All @@ -118,19 +118,19 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
Expand Down
10 changes: 5 additions & 5 deletions readme
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
legit
-----

A git web frontend written in Go.
A git web frontend written in Go.

Pronounced however you like; I prefer channeling my beret-wearing
Frenchman, and say "Oui, il est le git!"
Pronounced however you like; I prefer channeling my inner beret-wearing
Frenchman, and saying "Oui, il est le git!"

But yeah it's pretty legit, no cap on god fr fr.

Expand Down Expand Up @@ -59,13 +59,13 @@ These options are fairly self-explanatory, but of note are:
traverse subdirs yet.
• repo.readme: readme files to look for. Markdown isn't rendered.
• repo.mainBranch: main branch names to look for.
• repo.ignore: repos to ignore.
• repo.ignore: repos to ignore, relative to scanPath.
• server.name: used for go-import meta tags and clone URLs.


NOTES

• Run legit behind a TLS terminating proxy like relayd(8) or nginx.
• Run legit behind a TLS terminating proxy like relayd(8) or nginx.
• Cloning only works in bare repos -- this is a limitation inherent to git. You
can still view bare repos just fine in legit.
• The default head.html template uses my CDN to fetch fonts -- you may
Expand Down
3 changes: 3 additions & 0 deletions routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request) {
data["desc"] = getDescription(path)
data["servername"] = d.c.Server.Name
data["sshurl"] = "git@" + d.c.Server.Name + ":" + d.c.Repo.ScanPath
data["gomod"] = isGoModule(gr)

if err := t.ExecuteTemplate(w, "repo", data); err != nil {
log.Println(err)
Expand Down Expand Up @@ -190,6 +191,7 @@ func (d *deps) RepoTree(w http.ResponseWriter, r *http.Request) {
data["ref"] = ref
data["parent"] = treePath
data["desc"] = getDescription(path)
data["dotdot"] = filepath.Dir(treePath)

d.listFiles(files, data, w)
return
Expand Down Expand Up @@ -254,6 +256,7 @@ func (d *deps) Log(w http.ResponseWriter, r *http.Request) {
data["name"] = name
data["ref"] = ref
data["desc"] = getDescription(path)
data["log"] = true

if err := t.ExecuteTemplate(w, "log", data); err != nil {
log.Println(err)
Expand Down
8 changes: 8 additions & 0 deletions routes/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,23 @@ func (d *deps) listFiles(files []git.NiceTree, data map[string]any, w http.Respo

func countLines(r io.Reader) (int, error) {
buf := make([]byte, 32*1024)
bufLen := 0
count := 0
nl := []byte{'\n'}

for {
c, err := r.Read(buf)
if c > 0 {
bufLen += c
}
count += bytes.Count(buf[:c], nl)

switch {
case err == io.EOF:
/* handle last line not having a newline at the end */
if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' {
count++
}
return count, nil
case err != nil:
return 0, err
Expand Down
64 changes: 64 additions & 0 deletions routes/util.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package routes

import (
"io/fs"
"log"
"os"
"path/filepath"
"strings"

"git.icyphox.sh/legit/git"
)

func isGoModule(gr *git.GitRepo) bool {
_, err := gr.FileContent("go.mod")
return err == nil
}

func getDescription(path string) (desc string) {
db, err := os.ReadFile(filepath.Join(path, "description"))
if err == nil {
Expand All @@ -24,3 +34,57 @@ func (d *deps) isIgnored(name string) bool {

return false
}

type repoInfo struct {
Git *git.GitRepo
Path string
Category string
}

func (d *deps) getAllRepos() ([]repoInfo, error) {
repos := []repoInfo{}
max := strings.Count(d.c.Repo.ScanPath, string(os.PathSeparator)) + 2

err := filepath.WalkDir(d.c.Repo.ScanPath, func(path string, de fs.DirEntry, err error) error {
if err != nil {
return err
}

if de.IsDir() {
// Check if we've exceeded our recursion depth
if strings.Count(path, string(os.PathSeparator)) > max {
return fs.SkipDir
}

if d.isIgnored(path) {
return fs.SkipDir
}

// A bare repo should always have at least a HEAD file, if it
// doesn't we can continue recursing
if _, err := os.Lstat(filepath.Join(path, "HEAD")); err == nil {
repo, err := git.Open(path, "")
if err != nil {
log.Println(err)
} else {
relpath, _ := filepath.Rel(d.c.Repo.ScanPath, path)
repos = append(repos, repoInfo{
Git: repo,
Path: relpath,
Category: d.category(path),
})
// Since we found a Git repo, we don't want to recurse
// further
return fs.SkipDir
}
}
}
return nil
})

return repos, err
}

func (d *deps) category(path string) string {
return strings.TrimPrefix(filepath.Dir(strings.TrimPrefix(path, d.c.Repo.ScanPath)), string(os.PathSeparator))
}
Loading

0 comments on commit 880b42a

Please sign in to comment.