registry

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package registry resolves a package id (optionally pinned to a version) against a small set of user-configured registries, closing the vision document's aspirational install-by-identifier command (section 9.2: "patchcord plugin install io.patchcord.postgresql@1.0.0", "depuis un registre futur") and unblocking bundle updates (ADR-0044).

A registry is nothing more than a name pointing at a local directory or a plain http(s) URL serving a static index.json plus package files — no bespoke server, no auth, no commerce (CLAUDE.md §1.9: the cloud is never required). This package only resolves and downloads; installing what it downloads is unchanged and stays the job of internal/plugins, internal/apps, internal/bundles InstallPackage.

Index

Constants

View Source
const IndexFileName = "index.json"

IndexFileName is the file every registry (local directory or http(s) location) must serve at its root.

Variables

View Source
var ErrNotFound = errors.New("registry entry not found")

ErrNotFound is returned by Remove when no registry with the given name is configured, and by Resolve when no configured registry lists the requested package id.

View Source
var ErrUnknownVersion = errors.New("unknown package version")

ErrUnknownVersion is returned by Resolve when the registry that lists a package id does not list the requested version.

Functions

func Add

func Add(ctx context.Context, db *sql.DB, name, location string) error

Add records location under name. Re-adding the same name updates its location instead of failing — reconfiguring a registry's address is not an error. location is not validated here (no existence check, no reachability probe): like trust.Add does not check a key file exists, a registry is only ever validated lazily, the first time something resolves against it.

func Fetch

func Fetch(ctx context.Context, resolved Resolved, destDir string) (string, error)

Fetch downloads/copies the package resolved by Resolve into a new file under destDir (created if it does not exist yet) and returns its path. The caller owns the result and its parent directory — the same os.MkdirTemp + defer os.RemoveAll staging pattern internal/bundles and internal/apps already use for a package file before InstallPackage.

func ParseRef

func ParseRef(ref string) (id, version string)

ParseRef splits ref into an id and an optional version: "id@version" or a bare "id". An empty version means "resolve to the registry's declared latest" — unlike bundles.splitPluginDependency's requires_plugins dependencies (which must always pin an exact version), a bare id is a valid, meaningful reference here.

func Remove

func Remove(ctx context.Context, db *sql.DB, name string) error

Remove deletes a configured registry by name. It returns ErrNotFound if no registry with that name is configured.

Types

type Index

type Index struct {
	SchemaVersion int                   `json:"schemaVersion"`
	Packages      map[string]IndexEntry `json:"packages"`
}

Index is a registry's index.json: every package it serves, by id.

type IndexEntry

type IndexEntry struct {
	Kind     string            `json:"kind"`
	Latest   string            `json:"latest"`
	Versions map[string]string `json:"versions"`
}

IndexEntry is one package's entry in a registry index. Versions maps a version string to the package file's path, relative to the registry's own location. Latest names the version Resolve picks when the caller does not pin one — an explicit declaration by the index's author, never inferred by comparing version strings (nothing in this codebase parses or orders versions numerically; see bundles.splitPluginDependency's exact-string-equality dependency check for the same choice).

type Registry

type Registry struct {
	Name     string
	Location string
	AddedAt  time.Time
}

Registry is one configured package registry, as recorded in the database.

func List

func List(ctx context.Context, db *sql.DB) ([]Registry, error)

List returns every configured registry, oldest-added first — the order Resolve consults them in. rowid breaks ties between registries added within the same second.

type Resolved

type Resolved struct {
	RegistryName     string
	RegistryLocation string
	ID               string
	Kind             string
	Version          string
	// contains filtered or unexported fields
}

Resolved is a package entry found in one configured registry, with enough information for Fetch to retrieve its file.

func Resolve

func Resolve(ctx context.Context, db *sql.DB, id, version string) (Resolved, error)

Resolve looks up id (at version, or the registry's declared "latest" if version is empty) across every configured registry, in the order List returns them (added_at, oldest first).

The first registry whose index lists id wins, even if a later registry also has it — resolution never mixes sources for one id. Three distinct outcomes are not equivalent, though:

  • a registry whose index cannot be read or parsed at all fails Resolve immediately, naming that registry: a broken registry is never silently skipped in favor of a working one further down the list, since that would mask a real configuration mistake;
  • a registry that is read successfully but simply does not list id is not an error — Resolve moves on to the next configured registry;
  • once id is found in some registry, that registry is the chosen source: if it does not list the requested version, Resolve returns ErrUnknownVersion immediately rather than searching other registries for that version.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL