vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
|
2a8f7cef
Keenan Nemetz
10d ago
|
1 | package index |
| 2 | ||
| 3 | // The overview's stored summaries: the default branch's recent commits, the | |
|
a32a859a
Keenan Nemetz
5d ago
|
4 | // languages it is mostly made of, and the repository's tags. |
|
2a8f7cef
Keenan Nemetz
10d ago
|
5 | // |
|
a32a859a
Keenan Nemetz
5d ago
|
6 | // All three change when a ref moves, so they are written then (see RefreshHead |
| 7 | // and RefreshTags) and read as rows. A repository page then has no reason to | |
| 8 | // walk the tree or the history. | |
|
2a8f7cef
Keenan Nemetz
10d ago
|
9 | |
|
d37d301f
Keenan Nemetz
20h ago
|
10 | import "rodent.software/vole/internal/lang" |
|
2a8f7cef
Keenan Nemetz
10d ago
|
11 | |
| 12 | type CommitRow struct { | |
| 13 | SHA string | |
| 14 | Subject string | |
| 15 | Author string | |
| 16 | When int64 | |
| 17 | } | |
| 18 | ||
| 19 | // TagRow is one entry of refs/tags, peeled to the commit it names. | |
| 20 | type TagRow struct { | |
| 21 | Name string | |
| 22 | OID string | |
| 23 | Commit string | |
| 24 | Annotated bool | |
| 25 | Tagger string | |
| 26 | When int64 | |
| 27 | Subject string | |
| 28 | } | |
| 29 | ||
| 30 | // RecentCommits returns the default branch's newest commits, newest first. It is | |
| 31 | // the first page of the history, recorded when the tip was pushed. | |
| 32 | func (s *Store) RecentCommits(repoID string, n int) ([]CommitRow, error) { | |
| 33 | q := `SELECT sha, subject, author, when_at FROM repo_commits WHERE repo_id=? ORDER BY pos` | |
| 34 | args := []any{repoID} | |
| 35 | if n > 0 { | |
| 36 | q += ` LIMIT ?` | |
| 37 | args = append(args, n) | |
| 38 | } | |
| 39 | rows, err := s.db.Query(q, args...) | |
| 40 | if err != nil { | |
| 41 | return nil, err | |
| 42 | } | |
| 43 | defer rows.Close() | |
| 44 | var out []CommitRow | |
| 45 | for rows.Next() { | |
| 46 | var c CommitRow | |
| 47 | if err := rows.Scan(&c.SHA, &c.Subject, &c.Author, &c.When); err != nil { | |
| 48 | return nil, err | |
| 49 | } | |
| 50 | out = append(out, c) | |
| 51 | } | |
| 52 | return out, rows.Err() | |
| 53 | } | |
| 54 | ||
| 55 | // Languages returns the default branch's language groups by size, largest first. | |
| 56 | // The rows include "Other", so a percentage has a total to divide by. | |
| 57 | func (s *Store) Languages(repoID string) ([]lang.Share, error) { | |
| 58 | rows, err := s.db.Query(`SELECT name, bytes FROM repo_languages WHERE repo_id=? ORDER BY bytes DESC, name`, repoID) | |
| 59 | if err != nil { | |
| 60 | return nil, err | |
| 61 | } | |
| 62 | defer rows.Close() | |
| 63 | var out []lang.Share | |
| 64 | for rows.Next() { | |
| 65 | var sh lang.Share | |
| 66 | if err := rows.Scan(&sh.Name, &sh.Bytes); err != nil { | |
| 67 | return nil, err | |
| 68 | } | |
| 69 | out = append(out, sh) | |
| 70 | } | |
| 71 | return out, rows.Err() | |
| 72 | } | |
| 73 | ||
| 74 | // Tags returns the repository's tags, newest first, which is the order the | |
| 75 | // releases section shows. | |
| 76 | func (s *Store) Tags(repoID string, n int) ([]TagRow, error) { | |
| 77 | q := `SELECT name, oid, commit_sha, annotated, tagger, when_at, subject | |
| 78 | FROM repo_tags WHERE repo_id=? ORDER BY when_at DESC, name` | |
| 79 | args := []any{repoID} | |
| 80 | if n > 0 { | |
| 81 | q += ` LIMIT ?` | |
| 82 | args = append(args, n) | |
| 83 | } | |
| 84 | rows, err := s.db.Query(q, args...) | |
| 85 | if err != nil { | |
| 86 | return nil, err | |
| 87 | } | |
| 88 | defer rows.Close() | |
| 89 | var out []TagRow | |
| 90 | for rows.Next() { | |
| 91 | var t TagRow | |
| 92 | if err := rows.Scan(&t.Name, &t.OID, &t.Commit, &t.Annotated, &t.Tagger, &t.When, &t.Subject); err != nil { | |
| 93 | return nil, err | |
| 94 | } | |
| 95 | out = append(out, t) | |
| 96 | } | |
| 97 | return out, rows.Err() | |
| 98 | } |