Add local cargo registry type
- serve sparse index and config.json for local cargo repos from a cargo_index table - add Web API publish, yank and unyank under the local repo api root - drop index lines when the crate file is deleted
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"git.unkin.net/unkin/artifactapi/internal/provider"
|
||||
)
|
||||
|
||||
func (db *DB) InsertCargoIndexEntry(ctx context.Context, e *provider.CargoIndexEntry) error {
|
||||
_, err := db.Pool.Exec(ctx, `
|
||||
INSERT INTO cargo_index (repo_name, file_path, name, version, line, yanked)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
`, e.RepoName, e.FilePath, e.Name, e.Version, e.Line, e.Yanked)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) ListCargoIndexEntries(ctx context.Context, repoName, name string) ([]provider.CargoIndexEntry, error) {
|
||||
rows, err := db.Pool.Query(ctx, `
|
||||
SELECT repo_name, file_path, name, version, line, yanked
|
||||
FROM cargo_index
|
||||
WHERE repo_name = $1 AND lower(name) = $2
|
||||
ORDER BY id
|
||||
`, repoName, strings.ToLower(name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []provider.CargoIndexEntry
|
||||
for rows.Next() {
|
||||
var e provider.CargoIndexEntry
|
||||
if err := rows.Scan(&e.RepoName, &e.FilePath, &e.Name, &e.Version, &e.Line, &e.Yanked); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, e)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
// SetCargoYanked reports false when no such crate version exists.
|
||||
func (db *DB) SetCargoYanked(ctx context.Context, repoName, name, version string, yanked bool) (bool, error) {
|
||||
tag, err := db.Pool.Exec(ctx, `
|
||||
UPDATE cargo_index SET yanked = $4
|
||||
WHERE repo_name = $1 AND lower(name) = $2 AND version = $3
|
||||
`, repoName, strings.ToLower(name), version, yanked)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return tag.RowsAffected() > 0, nil
|
||||
}
|
||||
|
||||
func (db *DB) DeleteCargoIndexEntry(ctx context.Context, repoName, filePath string) error {
|
||||
_, err := db.Pool.Exec(ctx, `DELETE FROM cargo_index WHERE repo_name = $1 AND file_path = $2`, repoName, filePath)
|
||||
return err
|
||||
}
|
||||
@@ -425,3 +425,38 @@ func TestRPMMetadata(t *testing.T) {
|
||||
t.Fatalf("list rpm rows: %v %v", len(rows), err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCargoIndex(t *testing.T) {
|
||||
requireDB(t)
|
||||
for _, v := range []string{"0.1.0", "0.2.0"} {
|
||||
if err := testDB.InsertCargoIndexEntry(ctx(), &provider.CargoIndexEntry{
|
||||
RepoName: "cargo-db", FilePath: "crates/Unkin-Hello/Unkin-Hello-" + v + ".crate",
|
||||
Name: "Unkin-Hello", Version: v, Line: `{"vers":"` + v + `"}`,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
found, err := testDB.SetCargoYanked(ctx(), "cargo-db", "unkin-hello", "0.1.0", true)
|
||||
if err != nil || !found {
|
||||
t.Fatalf("yank: found=%v err=%v", found, err)
|
||||
}
|
||||
if found, _ := testDB.SetCargoYanked(ctx(), "cargo-db", "unkin-hello", "9.9.9", true); found {
|
||||
t.Error("yank of a missing version reported found")
|
||||
}
|
||||
|
||||
entries, err := testDB.ListCargoIndexEntries(ctx(), "cargo-db", "unkin-hello")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(entries) != 2 || entries[0].Version != "0.1.0" || !entries[0].Yanked || entries[1].Yanked {
|
||||
t.Fatalf("entries = %+v", entries)
|
||||
}
|
||||
|
||||
if err := testDB.DeleteCargoIndexEntry(ctx(), "cargo-db", entries[0].FilePath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if entries, _ = testDB.ListCargoIndexEntries(ctx(), "cargo-db", "UNKIN-HELLO"); len(entries) != 1 {
|
||||
t.Fatalf("after delete: %+v", entries)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user