this repo has no description
1package routes
2
3import (
4 "fmt"
5 "io/fs"
6 "log"
7 "net/http"
8 "os"
9 "path/filepath"
10 "strings"
11
12 "github.com/go-chi/chi/v5"
13 "github.com/icyphox/bild/auth"
14 "github.com/icyphox/bild/git"
15 "github.com/microcosm-cc/bluemonday"
16)
17
18func sanitize(content []byte) []byte {
19 return bluemonday.UGCPolicy().SanitizeBytes([]byte(content))
20}
21
22func isGoModule(gr *git.GitRepo) bool {
23 _, err := gr.FileContent("go.mod")
24 return err == nil
25}
26
27func displayRepoName(r *http.Request) string {
28 user := r.Context().Value("did").(string)
29 name := chi.URLParam(r, "name")
30
31 handle, err := auth.ResolveIdent(r.Context(), user)
32 if err != nil {
33 log.Printf("failed to resolve ident: %s: %s", user, err)
34 return fmt.Sprintf("%s/%s", user, name)
35 }
36
37 return fmt.Sprintf("@%s/%s", handle.Handle.String(), name)
38}
39
40func didPath(r *http.Request) string {
41 did := r.Context().Value("did").(string)
42 path := filepath.Join(did, chi.URLParam(r, "name"))
43 filepath.Clean(path)
44 return path
45}
46
47func trimDotGit(name string) string {
48 return strings.TrimSuffix(name, ".git")
49}
50
51func getDescription(path string) (desc string) {
52 db, err := os.ReadFile(filepath.Join(path, "description"))
53 if err == nil {
54 desc = string(db)
55 } else {
56 desc = ""
57 }
58 return
59}
60
61func (h *Handle) isUnlisted(name string) bool {
62 for _, i := range h.c.Repo.Unlisted {
63 if name == i {
64 return true
65 }
66 }
67
68 return false
69}
70
71func (h *Handle) isIgnored(name string) bool {
72 for _, i := range h.c.Repo.Ignore {
73 if name == i {
74 return true
75 }
76 }
77
78 return false
79}
80
81type repoInfo struct {
82 Git *git.GitRepo
83 Path string
84 Category string
85}
86
87func (d *Handle) getAllRepos() ([]repoInfo, error) {
88 repos := []repoInfo{}
89 max := strings.Count(d.c.Repo.ScanPath, string(os.PathSeparator)) + 2
90
91 err := filepath.WalkDir(d.c.Repo.ScanPath, func(path string, de fs.DirEntry, err error) error {
92 if err != nil {
93 return err
94 }
95
96 if de.IsDir() {
97 // Check if we've exceeded our recursion depth
98 if strings.Count(path, string(os.PathSeparator)) > max {
99 return fs.SkipDir
100 }
101
102 if d.isIgnored(path) {
103 return fs.SkipDir
104 }
105
106 // A bare repo should always have at least a HEAD file, if it
107 // doesn't we can continue recursing
108 if _, err := os.Lstat(filepath.Join(path, "HEAD")); err == nil {
109 repo, err := git.Open(path, "")
110 if err != nil {
111 log.Println(err)
112 } else {
113 relpath, _ := filepath.Rel(d.c.Repo.ScanPath, path)
114 repos = append(repos, repoInfo{
115 Git: repo,
116 Path: relpath,
117 Category: d.category(path),
118 })
119 // Since we found a Git repo, we don't want to recurse
120 // further
121 return fs.SkipDir
122 }
123 }
124 }
125 return nil
126 })
127
128 return repos, err
129}
130
131func (d *Handle) category(path string) string {
132 return strings.TrimPrefix(filepath.Dir(strings.TrimPrefix(path, d.c.Repo.ScanPath)), string(os.PathSeparator))
133}
134
135func setContentDisposition(w http.ResponseWriter, name string) {
136 h := "inline; filename=\"" + name + "\""
137 w.Header().Add("Content-Disposition", h)
138}
139
140func setGZipMIME(w http.ResponseWriter) {
141 setMIME(w, "application/gzip")
142}
143
144func setMIME(w http.ResponseWriter, mime string) {
145 w.Header().Add("Content-Type", mime)
146}