git-preview @ main

static git web frontend but with images and html previews + code truncation

routes/util.go

  1package routes
  2
  3import (
  4	"io/fs"
  5	"log"
  6	"os"
  7	"path/filepath"
  8	"strings"
  9
 10	"github.com/jxc2000-b/git-preview/git"
 11)
 12
 13func isGoModule(gr *git.GitRepo) bool {
 14	_, err := gr.FileContent("go.mod")
 15	return err == nil
 16}
 17
 18func getDisplayName(name string) string {
 19	return strings.TrimSuffix(name, ".git")
 20}
 21
 22func getDescription(path string) (desc string) {
 23	db, err := os.ReadFile(filepath.Join(path, "description"))
 24	if err == nil {
 25		desc = string(db)
 26	} else {
 27		desc = ""
 28	}
 29	return
 30}
 31
 32func (d *deps) isUnlisted(name string) bool {
 33	for _, i := range d.c.Repo.Unlisted {
 34		if name == i {
 35			return true
 36		}
 37	}
 38
 39	return false
 40}
 41
 42func (d *deps) isIgnored(name string) bool {
 43	for _, i := range d.c.Repo.Ignore {
 44		if name == i {
 45			return true
 46		}
 47	}
 48
 49	return false
 50}
 51
 52// soloRepo returns the repo name if the scan path holds exactly one
 53// visible repo — the site then behaves as a single-project preview
 54// (no index page, no "all repos" backlink).
 55func (d *deps) soloRepo() string {
 56	dirs, err := os.ReadDir(d.c.Repo.ScanPath)
 57	if err != nil {
 58		return ""
 59	}
 60	solo := ""
 61	for _, dir := range dirs {
 62		if !dir.IsDir() || d.isIgnored(dir.Name()) {
 63			continue
 64		}
 65		if solo != "" {
 66			return ""
 67		}
 68		solo = dir.Name()
 69	}
 70	return solo
 71}
 72
 73type repoInfo struct {
 74	Git      *git.GitRepo
 75	Path     string
 76	Category string
 77}
 78
 79func (d *deps) getAllRepos() ([]repoInfo, error) {
 80	repos := []repoInfo{}
 81	max := strings.Count(d.c.Repo.ScanPath, string(os.PathSeparator)) + 2
 82
 83	err := filepath.WalkDir(d.c.Repo.ScanPath, func(path string, de fs.DirEntry, err error) error {
 84		if err != nil {
 85			return err
 86		}
 87
 88		if de.IsDir() {
 89			// Check if we've exceeded our recursion depth
 90			if strings.Count(path, string(os.PathSeparator)) > max {
 91				return fs.SkipDir
 92			}
 93
 94			if d.isIgnored(path) {
 95				return fs.SkipDir
 96			}
 97
 98			// A bare repo should always have at least a HEAD file, if it
 99			// doesn't we can continue recursing
100			if _, err := os.Lstat(filepath.Join(path, "HEAD")); err == nil {
101				repo, err := git.Open(path, "")
102				if err != nil {
103					log.Println(err)
104				} else {
105					relpath, _ := filepath.Rel(d.c.Repo.ScanPath, path)
106					repos = append(repos, repoInfo{
107						Git:      repo,
108						Path:     relpath,
109						Category: d.category(path),
110					})
111					// Since we found a Git repo, we don't want to recurse
112					// further
113					return fs.SkipDir
114				}
115			}
116		}
117		return nil
118	})
119
120	return repos, err
121}
122
123func (d *deps) category(path string) string {
124	return strings.TrimPrefix(filepath.Dir(strings.TrimPrefix(path, d.c.Repo.ScanPath)), string(os.PathSeparator))
125}
126