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