Documentation
¶
Overview ¶
Package catalog provides tool catalog schema, caching, and search operations.
This package implements Layer 3 (Discovery) operations:
- Fetch: Download catalog from registry servers
- Cache: Store catalog locally with expiration
- Search: Find tools by name, description, or capabilities
Security Boundary (CRITICAL) ¶
This package is for DISCOVERY and DISPLAY ONLY.
Catalog data must NEVER influence:
- Which binary gets executed
- Whether a binary is considered verified
- What digest is expected
- What signer identity is trusted
The lockfile and Sigstore verification are the ONLY security sources of truth. Catalog provides publisher names and descriptions for display purposes only.
This package MUST NOT be imported by:
- internal/dispatch (tool execution)
- internal/collector (collector execution)
- internal/tool (tool resolution)
- internal/component (component management)
Only CLI-layer code (cmd/epack/toolcmd/catalog.go) should import this package.
Index ¶
- Constants
- Variables
- func CatalogPath() (string, error)
- func ClearCache() error
- func Dir() (string, error)
- func Exists() bool
- func MetaPath() (string, error)
- func WriteCatalog(catalog *Catalog) error
- func WriteMeta(meta *CatalogMeta) error
- type Catalog
- type CatalogComponent
- type CatalogMeta
- type CatalogSource
- type ComponentKind
- type FetchOptions
- type FetchResult
- type LookupResult
- type MatchType
- type MetaStatus
- type SearchOptions
- type SearchResult
Constants ¶
const ( // CatalogFileName is the name of the cached catalog file. CatalogFileName = "catalog.json" // MetaFileName is the name of the catalog metadata file. MetaFileName = "catalog.json.meta" // CacheDirName is the epack cache directory name. CacheDirName = "epack" )
const ( MetaStatusOK = schema.MetaStatusOK // Successful fetch, catalog updated MetaStatusNotModified = schema.MetaStatusNotModified // 304 response, cache still valid MetaStatusError = schema.MetaStatusError // Fetch failed )
const ( MatchExact = schema.MatchExact // Exact name match MatchPrefix = schema.MatchPrefix // Name starts with query MatchSubstring = schema.MatchSubstring // Name, description, or publisher contains query )
const ( KindCollector = componenttypes.KindCollector KindTool = componenttypes.KindTool KindRemote = componenttypes.KindRemote KindUtility = componenttypes.KindUtility )
const DefaultCatalogURL = "https://registry.epack.dev/catalog.json"
DefaultCatalogURL is the default catalog URL.
const FetchTimeout = limits.DefaultHTTPTimeout
FetchTimeout is the maximum time to wait for catalog fetch. Uses the central HTTP timeout limit for consistency.
const GitHubHTTPSPrefix = "https://github.com/"
GitHubHTTPSPrefix is the required prefix for GitHub repository URLs.
const MetaVersion = schema.MetaVersion
MetaVersion is the current meta file version.
const SchemaVersion = schema.SchemaVersion
SchemaVersion is the current catalog schema version.
Variables ¶
var ErrNoCatalog = errors.E(errors.CatalogNotFound, "no cached catalog found; run 'epack tool catalog refresh'", nil)
ErrNoCatalog is returned when no cached catalog exists.
var ErrNoMeta = errors.E(errors.CatalogMetaNotFound, "no catalog metadata found", nil)
ErrNoMeta is returned when no catalog metadata exists.
var ErrNotFound = errors.E(errors.ComponentNotFound, "component not found in catalog", nil)
ErrNotFound is returned when a component is not found in the catalog.
Functions ¶
func CatalogPath ¶
CatalogPath returns the full path to the cached catalog file.
func Dir ¶
Dir returns the epack cache directory path. Uses XDG_CACHE_HOME on Unix, or platform-appropriate defaults.
Precedence:
- $XDG_CACHE_HOME/epack (if XDG_CACHE_HOME set)
- ~/.cache/epack (Unix)
- %LOCALAPPDATA%\epack\cache (Windows)
func WriteCatalog ¶
WriteCatalog writes the catalog to the cache directory. Creates the cache directory if it doesn't exist.
SECURITY: Uses safefile.OpenForWrite to prevent symlink attacks. O_NOFOLLOW atomically refuses to follow symlinks at file creation time, preventing attackers from swapping files with symlinks.
Note: We don't validate the entire cache path for symlinks because system symlinks (e.g., /var -> /private/var on macOS) are legitimate.
func WriteMeta ¶
func WriteMeta(meta *CatalogMeta) error
WriteMeta writes the catalog metadata file. Creates the cache directory if it doesn't exist.
SECURITY: Uses safefile.OpenForWrite to prevent symlink attacks. O_NOFOLLOW atomically refuses to follow symlinks at file creation time, preventing attackers from swapping files with symlinks.
Types ¶
type Catalog ¶
Catalog is the component catalog schema v1. This is INFORMATIONAL ONLY - never use for security decisions.
func ParseCatalog ¶
ParseCatalog parses catalog JSON with tolerant decoding. Unknown fields are silently ignored for forward compatibility.
func ReadCatalog ¶
ReadCatalog reads the cached catalog, enforcing size limits. Returns ErrNoCatalog if no cached catalog exists.
SECURITY: Uses safefile.ReadFile to refuse symlinks, preventing an attacker from swapping the cache file with a symlink to read arbitrary files or cause the application to process attacker-controlled data.
type CatalogComponent ¶
type CatalogComponent = schema.CatalogComponent
CatalogComponent contains display information about a component. NOTE: No trust assertions (verified_by, signatures, etc.) - catalog is for discovery only.
func FindComponentByName ¶
func FindComponentByName(c *Catalog, name string) (CatalogComponent, bool)
FindComponentByName finds a tool by exact name match. Note: This only searches the Tools array. For kind-aware lookup, use LookupComponentInCatalog or Catalog.FindByNameAndKind directly. Returns the component and true if found, or zero value and false if not found.
type CatalogMeta ¶
type CatalogMeta = schema.CatalogMeta
CatalogMeta stores metadata about the cached catalog. Stored separately from catalog.json for easy debugging.
func GetCachedMeta ¶
func GetCachedMeta() *CatalogMeta
GetCachedMeta returns the cached meta for use in conditional requests. Returns nil if no meta exists.
func ParseMeta ¶
func ParseMeta(data []byte) (*CatalogMeta, error)
ParseMeta parses meta JSON with strict decoding. Unknown fields cause an error since we control this format.
func ReadMeta ¶
func ReadMeta() (*CatalogMeta, error)
ReadMeta reads the catalog metadata file. Returns ErrNoMeta if no metadata exists.
SECURITY: Uses safefile.ReadFile to refuse symlinks.
type CatalogSource ¶
type CatalogSource = schema.CatalogSource
CatalogSource identifies where the catalog was fetched from.
type ComponentKind ¶
type ComponentKind = componenttypes.ComponentKind
ComponentKind identifies the type of component.
type FetchOptions ¶
type FetchOptions struct {
// URL to fetch catalog from. If empty, uses DefaultCatalogURL.
URL string
// ETag from previous fetch for conditional request.
ETag string
// LastModified from previous fetch for conditional request.
LastModified string
// HTTPClient to use. If nil, uses default client with timeout.
HTTPClient *http.Client
// InsecureAllowHTTP permits HTTP requests to localhost/127.0.0.1 for testing.
// SECURITY: Only set this in tests. Production code should never set this.
// CLI: --insecure-allow-http
InsecureAllowHTTP bool
}
FetchOptions configures the catalog fetch behavior.
type FetchResult ¶
type FetchResult struct {
Updated bool // true if catalog was updated, false if not modified
Status MetaStatus // ok, not_modified, or error
HTTPStatus int // HTTP status code
Error error // error if Status == error
}
FetchResult contains the outcome of a catalog fetch operation.
func FetchCatalog ¶
func FetchCatalog(ctx context.Context, opts FetchOptions) (*FetchResult, error)
FetchCatalog fetches the catalog from the specified URL using conditional requests. If the catalog hasn't changed (304 Not Modified), returns Updated=false. On success, writes catalog to cache and updates meta.
type LookupResult ¶
type LookupResult struct {
Name string // Component name (e.g., "ai")
RepoPath string // Repository path extracted from RepoURL (e.g., "locktivity/epack-tool-ai")
Source string // Full source string for config (e.g., "locktivity/epack-tool-ai@^1.0")
Publisher string // Publisher name from catalog
Description string // Component description
Latest string // Latest version hint from catalog
Dependencies []string // Install-time dependencies (component names)
}
LookupResult contains the result of looking up a component in the catalog.
func LookupComponent ¶
func LookupComponent(name string, kind ComponentKind, constraint string) (*LookupResult, error)
LookupComponent finds a component by exact name and kind in the cached catalog and constructs the source string for use in epack.yaml.
The kind parameter specifies which component type to search (tool, collector, etc.). The constraint parameter specifies the version constraint to use in the source string. If constraint is "latest" or empty, only the repo path is used (no @constraint suffix).
Returns ErrNoCatalog if no cached catalog exists. Returns ErrNotFound if the component is not in the catalog.
func LookupComponentInCatalog ¶
func LookupComponentInCatalog(catalog *Catalog, name string, kind ComponentKind, constraint string) (*LookupResult, error)
LookupComponentInCatalog finds a component in the provided catalog. This is useful when you already have the catalog loaded and want to avoid re-reading it.
type MetaStatus ¶
type MetaStatus = schema.MetaStatus
MetaStatus represents the outcome of the last catalog fetch attempt.
type SearchOptions ¶
type SearchOptions = schema.SearchOptions
SearchOptions configures search behavior.
type SearchResult ¶
type SearchResult = schema.SearchResult
SearchResult represents a component from a search with its match type.
func SearchComponents ¶
func SearchComponents(c *Catalog, query string) []SearchResult
SearchComponents finds components matching the query string. Results are ranked by relevance: exact > prefix > substring. This is a convenience wrapper that avoids callers needing to import the schema package.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package resolve provides dependency resolution for tool installation.
|
Package resolve provides dependency resolution for tool installation. |
|
Package schema provides the component catalog schema types and parsing.
|
Package schema provides the component catalog schema types and parsing. |