Documentation
¶
Overview ¶
Package materialize realizes a #Platform's path-keyed catalog subscriptions into a sealed MaterializedPlatform.
A #Platform authored against opmodel.dev/core@v2 carries only a #registry of subscriptions; its #composedTransformers / #matchers slots are empty (the schema marks them optional, kernel-filled).
Materialize is the kernel step that fills those slots. For each enabled subscription it:
- enumerates the published versions of the subscribed catalog path;
- narrows them Go-side by the subscription filter — range ∧ allow ∧ deny, parsed as SemVer constraints because CUE cannot evaluate range syntax;
- pulls each surviving version through cue/load against the configured OCI registry;
- reads each build's #Catalog.#transformers map; and
- indexes every transformer by its stamped FQN into a composed transformer map, plus a #matchers reverse index over the primitive FQNs those transformers reference.
The result is a MaterializedPlatform that exposes the composed transformer map and the #matchers reverse index as native first-class fields — Transformers (FQN → #ComponentTransformer) and Matchers ({resources, traits}) — built in the owner *cue.Context by indexCatalogs. They are NOT filled onto the closed c.#Platform (ADR-003): the matcher and executor read them off the native fields, and a #transform read off Transformers renders concrete because no closed twin is ever constructed. The closed platform spec stays reachable as Source.Package for #registry / metadata / diagnostics.
Materialize performs I/O (registry enumeration + OCI pulls) and is explicit and caller-driven: the kernel holds no cache (Principle I). Consumers that want memoization wire their own via opm/materialize/cache.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CueContextOwner ¶
CueContextOwner is the minimal context-owner interface Materialize accepts. *kernel.Kernel satisfies it; tests may pass any value exposing a *cue.Context. Keeping the interface here frees the materialize package from importing opm/kernel.
The owner's *cue.Context is used to build every pulled catalog AND to read the platform value, so the native Transformers / Matchers surfaces share one context with the platform (cross-context values cannot be unified or filled together).
type MaterializedPlatform ¶
type MaterializedPlatform struct {
// Source is the *platform.Platform this view was realized from. Its
// Source.Package is the closed c.#Platform spec, reachable for #registry,
// metadata, and diagnostics (a MaterializeError can name the originating
// platform; MissingFQN.alternatives may inspect it). It is NOT filled with
// the composed map or matcher index.
Source *platform.Platform
// Transformers is the open #composedTransformers map (FQN →
// #ComponentTransformer) produced by indexCatalogs in the owner context.
// It is the canonical surface for reading a transformer's #transform:
// because it is built natively (never filled into a closed value), reading
// a #transform off it — including output-local hidden fields — renders
// concrete. Multi-version composition is preserved: each selected version's
// transformers are indexed under their distinct version-bearing FQNs.
Transformers cue.Value
// Matchers is the open #matchers reverse index ({resources, traits}:
// primitive FQN → [transformers]) produced by indexCatalogs in the owner
// context. The matcher looks up demanded FQNs in Matchers.resources /
// Matchers.traits to find candidate transformers.
Matchers cue.Value
// Resolved maps each enabled subscription path to the bare SemVer that
// Materialize recorded for it. When a filter selects several versions
// (all of which are pulled and indexed), this is the highest survivor.
// Diagnostic-only: callers SHOULD log it but MUST NOT branch behavior on it.
Resolved map[string]string
}
MaterializedPlatform is the sealed, post-realization view of a #Platform. It is produced by Materialize and consumed by the matcher and executor. Once returned it is treated as immutable and is safe for concurrent read-only consumption.
The composed transformer map and the matcher reverse index are exposed as first-class fields built natively in the owner *cue.Context. They are NOT filled onto the closed c.#Platform value: doing so corrupts the lazy in-expression resolution of output-local hidden fields in transformer #transforms (a CUE Go-API closedness bug — see ADR-003 and docs/design/transformer-output-hidden-field-scope-bug.md §12). Federating the native surfaces instead of collapsing them into the closed platform removes that footgun by construction: there is no closed twin to misread.
func Materialize ¶
func Materialize(ctx context.Context, owner CueContextOwner, registry string, p *platform.Platform) (*MaterializedPlatform, error)
Materialize realizes a #Platform's path-keyed catalog subscriptions into a sealed MaterializedPlatform. It walks p's #registry; for each enabled subscription it enumerates published versions, narrows them by the subscription filter (range ∧ allow ∧ deny), pulls each survivor against the supplied registry, and indexes the selected catalogs' #transformers into a composed transformer map plus a #matchers reverse index. Both are exposed as native first-class fields (MaterializedPlatform.Transformers / MaterializedPlatform.Matchers) — they are NOT filled onto the closed c.#Platform (ADR-003: doing so corrupts output-local hidden fields).
owner supplies the *cue.Context used for both the platform value and every catalog build (the native surfaces share one context with the platform). registry is the CUE_REGISTRY mapping for catalog (and schema) resolution; an empty string inherits the process CUE_REGISTRY. The process environment is never mutated.
Inputs are not mutated: p.Package is read-only and never filled. Failures surface as oerrors.MaterializeError (Kind "catalog") naming the offending subscription path and version. Materialize fails fast on the first failing subscription (design.md Q3).