vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Record the default branch summary when a push lands
8dc56e4e258dd56e2c20776f80d61dbed4993f31 · Keenan Nemetz · 9d ago · parent 20442b59
Record the default branch summary when a push lands The landing card showed the default branch tip and the language it is mostly made of by running `symbolic-ref`, `rev-parse`, `log -1` and `ls-tree -r` per repository on every home page read. Those facts change only when a push moves the branch, so the push now records them. - `repos` carries head_sha, head_subject, head_author, head_when, language and lang_class, and `Index.Entry` returns them with the rest of the row. - `Store.RefreshHead` recomputes the summary and skips the tree walk when the recorded tip is still the branch tip, so a metadata or tag push costs one rev-parse. It runs from post-receive, from the rebuild, and after the default branch changes in settings. - The language mapping moved to `internal/lang`, shared by the web pages and the summary; `fileClass` and `languageFor` are now one table. - The home cards read the head, language, counts, ACL and newest event time from the index. The home page starts no git process at all; the all-git card builder stays as the fallback for a Web without an index. Load harness at concurrency 4 with three repositories: home goes from 243 to 749 req/s, p50 from 16 ms to 5 ms, and the server runs no git child process for those requests.
server/web/overview.go +2−63
| @@ -9,9 +9,7 @@ import ( | |||
| 9 | 9 | "html/template" | |
| 10 | 10 | "io" | |
| 11 | 11 | "net/http" | |
| 12 | "path" | ||
| 13 | 12 | "sort" | |
| 14 | "strings" | ||
| 15 | 13 | "time" | |
| 16 | 14 | ||
| 17 | 15 | "github.com/rodent-software/vole/ci/runs" | |
| @@ -19,6 +17,7 @@ import ( | |||
| 19 | 17 | "github.com/rodent-software/vole/forge/index" | |
| 20 | 18 | "github.com/rodent-software/vole/forge/repo" | |
| 21 | 19 | "github.com/rodent-software/vole/internal/format" | |
| 20 | "github.com/rodent-software/vole/internal/lang" | ||
| 22 | 21 | ) | |
| 23 | 22 | ||
| 24 | 23 | // maxReadmeBytes is the largest README rendered on the overview. A file past it | |
| @@ -222,7 +221,7 @@ func languageShares(blobs map[string]git.Blob) []languageShare { | |||
| 222 | 221 | byName := map[string]int64{} | |
| 223 | 222 | var total int64 | |
| 224 | 223 | for _, b := range blobs { | |
| 225 | name := languageFor(b.Path) | ||
| 224 | name := lang.For(b.Path) | ||
| 226 | 225 | byName[name] += b.Size | |
| 227 | 226 | total += b.Size | |
| 228 | 227 | } | |
| @@ -253,63 +252,3 @@ func languageShares(blobs map[string]git.Blob) []languageShare { | |||
| 253 | 252 | } | |
| 254 | 253 | return list | |
| 255 | 254 | } | |
| 256 | |||
| 257 | func languageFor(name string) string { | ||
| 258 | switch strings.ToLower(path.Ext(name)) { | ||
| 259 | case ".go": | ||
| 260 | return "Go" | ||
| 261 | case ".js", ".mjs", ".cjs": | ||
| 262 | return "JavaScript" | ||
| 263 | case ".ts", ".tsx": | ||
| 264 | return "TypeScript" | ||
| 265 | case ".jsx": | ||
| 266 | return "JavaScript" | ||
| 267 | case ".py": | ||
| 268 | return "Python" | ||
| 269 | case ".rs": | ||
| 270 | return "Rust" | ||
| 271 | case ".rb": | ||
| 272 | return "Ruby" | ||
| 273 | case ".java": | ||
| 274 | return "Java" | ||
| 275 | case ".kt", ".kts": | ||
| 276 | return "Kotlin" | ||
| 277 | case ".c", ".h": | ||
| 278 | return "C" | ||
| 279 | case ".cc", ".cpp", ".hpp": | ||
| 280 | return "C++" | ||
| 281 | case ".cs": | ||
| 282 | return "C#" | ||
| 283 | case ".sh", ".bash", ".zsh": | ||
| 284 | return "Shell" | ||
| 285 | case ".md", ".markdown": | ||
| 286 | return "Markdown" | ||
| 287 | case ".html", ".htm": | ||
| 288 | return "HTML" | ||
| 289 | case ".css", ".scss", ".sass": | ||
| 290 | return "CSS" | ||
| 291 | case ".json": | ||
| 292 | return "JSON" | ||
| 293 | case ".yml", ".yaml": | ||
| 294 | return "YAML" | ||
| 295 | case ".toml": | ||
| 296 | return "TOML" | ||
| 297 | case ".sql": | ||
| 298 | return "SQL" | ||
| 299 | case ".proto": | ||
| 300 | return "Protocol Buffers" | ||
| 301 | case ".lua": | ||
| 302 | return "Lua" | ||
| 303 | case ".php": | ||
| 304 | return "PHP" | ||
| 305 | case ".swift": | ||
| 306 | return "Swift" | ||
| 307 | case ".ex", ".exs": | ||
| 308 | return "Elixir" | ||
| 309 | case ".zig": | ||
| 310 | return "Zig" | ||
| 311 | case "": | ||
| 312 | return "Other" | ||
| 313 | } | ||
| 314 | return "Other" | ||
| 315 | } | ||