Documentation
¶
Overview ¶
Package materialize realizes a #Platform's path-keyed catalog subscriptions into a sealed MaterializedPlatform.
A #Platform authored against opmodel.dev/core@v0.3.0 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 whose Package answers the exact LookupPath calls the matcher already makes (schema.ComposedTransformers, schema.MatchersResources, schema.MatchersTraits), so the downstream match rewrite consumes it with a minimal diff.
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 filled #composedTransformers / #matchers share one context with the platform (cross-context values cannot be filled together — see design.md D2 spike outcome).
type MaterializedPlatform ¶
type MaterializedPlatform struct {
// Source is the *platform.Platform this view was realized from. Held for
// diagnostics (a MaterializeError can name the originating platform) and
// for the later MissingFQN.alternatives lookups.
Source *platform.Platform
// Package is Source.Package with #composedTransformers and #matchers
// filled by Materialize. It is built with the owner's *cue.Context.
//
// WARNING: do NOT read a transformer's #transform out of Package to render
// its output. Package is a *closed* c.#Platform value, and FillPath-ing the
// composed map into a closed, independently-built value corrupts the lazy
// in-expression resolution of output-local hidden fields in the transformers
// (a CUE Go-API closedness bug — see
// docs/design/transformer-output-hidden-field-scope-bug.md §12). The matcher
// reads only FQNs/labels off Package, which are unaffected; the executor MUST
// read transforms from Composed instead.
Package cue.Value
// Composed is the open #composedTransformers map (FQN → #ComponentTransformer)
// as produced by indexCatalogs, BEFORE it is filled onto the closed Package.
// Reading a transform from this open value renders output-local hidden fields
// correctly; reading it from Package does not (see Package's warning). The
// executor sources every #transform from here.
Composed 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 (in the follow-up match rewrite) by the matcher. Once returned it is treated as immutable.
Package answers the same LookupPath calls the matcher already makes against a platform value — schema.ComposedTransformers, schema.MatchersResources, schema.MatchersTraits — with the kernel-filled index present. That keeps the match-signature swap a minimal diff: the matcher reads the same paths, now populated.
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. The index is filled onto a copy of p.Package at #composedTransformers / #matchers.
owner supplies the *cue.Context used for both the platform value and every catalog build (the filled values share one context — design.md D2). 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: FillPath is non-mutating and p.Package is read-only. 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).