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.
|
7f547ca3
Keenan Nemetz
10d ago
|
1 | package index |
| 2 | ||
| 3 | // Release artifacts on the metadata branch: releases/<tag>/<name> holds a git-lfs | |
| 4 | // pointer, and the pointer is the record. The index stores the pointer's name, | |
| 5 | // object id and size, which is what a release page lists and what a download | |
| 6 | // needs before it asks the LFS store for the bytes. | |
| 7 | // | |
| 8 | // This is the one part of the branch whose authoritative copy is a tag, not a | |
| 9 | // file: a tag can be deleted and recreated. The rows are replaced from the tree | |
| 10 | // whenever the releases/ path changes, so they always describe the current | |
| 11 | // branch. | |
| 12 | ||
| 13 | import ( | |
|
d37d301f
Keenan Nemetz
17h ago
|
14 | "rodent.software/vole/metadata" |
|
7f547ca3
Keenan Nemetz
10d ago
|
15 | ) |
| 16 | ||
| 17 | // replaceArtifacts replaces every artifact row for a repository. Artifacts are a | |
| 18 | // small, whole set: a release page shows a tag's files and the cost of rewriting | |
| 19 | // the set is one statement when releases/ changes. | |
| 20 | func replaceArtifacts(tx execer, repoID string, byTag map[string][]metadata.Artifact) error { | |
| 21 | if _, err := tx.Exec(`DELETE FROM artifacts WHERE repo_id=?`, repoID); err != nil { | |
| 22 | return err | |
| 23 | } | |
| 24 | for tag, list := range byTag { | |
| 25 | for _, a := range list { | |
| 26 | if _, err := tx.Exec( | |
| 27 | `INSERT OR REPLACE INTO artifacts(repo_id, tag, name, oid, size) VALUES(?,?,?,?,?)`, | |
| 28 | repoID, tag, a.Name, a.OID, a.Size); err != nil { | |
| 29 | return err | |
| 30 | } | |
| 31 | } | |
| 32 | } | |
| 33 | return nil | |
| 34 | } | |
| 35 | ||
| 36 | // Artifacts returns the files attached to one tag, sorted by name. A tag with | |
| 37 | // nothing attached is an empty list, which is also what a tag that predates the | |
| 38 | // index's first read returns; the release page shows the same "no artifacts" | |
| 39 | // state either way. | |
| 40 | func (s *Store) Artifacts(repoID, tag string) ([]metadata.Artifact, error) { | |
| 41 | rows, err := s.db.Query( | |
| 42 | `SELECT name, oid, size FROM artifacts WHERE repo_id=? AND tag=? ORDER BY name`, | |
| 43 | repoID, tag) | |
| 44 | if err != nil { | |
| 45 | return nil, err | |
| 46 | } | |
| 47 | defer rows.Close() | |
| 48 | var out []metadata.Artifact | |
| 49 | for rows.Next() { | |
| 50 | var a metadata.Artifact | |
| 51 | if err := rows.Scan(&a.Name, &a.OID, &a.Size); err != nil { | |
| 52 | return nil, err | |
| 53 | } | |
| 54 | out = append(out, a) | |
| 55 | } | |
| 56 | return out, rows.Err() | |
| 57 | } |