Documentation
¶
Overview ¶
Package compile's matching logic.
Match walks each consumer Module component, collects the resource and trait FQNs the component declares (component.#resources keys ∪ component.#traits keys), and looks each demanded FQN up in the materialized platform's #matchers.{resources, traits} reverse index. The index is filled by opm/materialize: matchers[FQN] yields the list of transformers that require that primitive FQN.
The algorithm is FQN-lookup → always-unify → predicate:
- Lookup. A demanded FQN whose #matchers bucket is empty is a hard miss — recorded as a structured oerrors.MissingFQN (per (instance, component, fqn)), accumulated in one pass with no fail-fast.
- Always-unify (D6). For each candidate transformer in the bucket, unify the component's primitive body against the transformer's required body for every FQN present in BOTH component.#resources and transformer.requiredResources (and the analogous traits intersection, per D1) — not only the triggering FQN. A conflict records an oerrors.UnifyError (verbatim CUE cause) and disqualifies the candidate.
- Predicate. Surviving candidates are paired iff their requiredLabels ∧ requiredResources ∧ requiredTraits predicate is satisfied by the component context. Multiple satisfied candidates are legitimate.
Located transformer bodies live in the composed map keyed by tfFQN; both the composed map and the #matchers reverse index are read off the MaterializedPlatform's native Transformers / Matchers fields (built in the owner context, not filled onto the closed platform).
Match is in Go (not CUE #PlatformMatch) per umbrella decision Q1: keeps the Go-native error/diagnostic shape, avoids one CUE evaluation per match, and reuses the existing #config / labels code paths unchanged.
Package compile executes matched transforms and emits compiled values.
The package is platform-neutral: its public output type is *core.Compiled, a CUE value plus provenance. Adapters wrap each Compiled with their platform-specific Resource implementation (see opm/core).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type CompileResult ¶
type CompileResult struct {
// Compiled is the ordered list of compiled values from the pipeline.
// Each entry carries Component and Transformer provenance for inventory
// tracking. Adapters wrap each Compiled with a platform-specific
// core.Resource implementation.
Compiled []*core.Compiled
// MatchPlan is the decoded result of matching components against transformers.
// Nil if matching was not performed (e.g. no components).
MatchPlan *MatchPlan
// Components is a per-component summary for verbose output, sorted by name.
Components []ComponentSummary
// Unmatched is the list of component FQNs that found no matching
// transformer.
Unmatched []string
// Warnings is a list of human-readable advisory messages (e.g. unhandled traits).
// A non-empty Warnings slice does NOT indicate failure.
Warnings []string
}
CompileResult holds the output of a successful Execute call.
type ComponentSummary ¶
type ComponentSummary struct {
// Name is the component name.
Name string
// Labels are the component's descriptive labels from metadata.labels,
// shown as-is for display. Matching does NOT read these — the matcher
// reads the component's derived matchLabels (0010 D36).
Labels map[string]string
// ResourceFQNs are the FQNs of resource types declared by the component.
// Sorted for deterministic output.
// Example: ["opmodel.dev/catalogs/opm/resources/container@v1"]
ResourceFQNs []string
// TraitFQNs are the FQNs of traits declared by the component.
// Sorted for deterministic output.
// Example: ["opmodel.dev/catalogs/opm/traits/expose@v1"]
TraitFQNs []string
}
ComponentSummary contains display-oriented summary data extracted from a component after the compile pipeline. It captures the key properties useful for verbose output without exposing cue.Value fields.
type MatchPlan ¶
type MatchPlan struct {
Matches map[string]map[string]MatchResult
Unmatched []string
UnhandledTraits map[string][]string
// Missing holds the hard "no transformer requires this FQN" diagnostics,
// one per (instance, component, fqn). Distinct from UnhandledTraits, which
// flags a component trait that no matched transformer consumes. Kept for
// compatibility and fed as before; the load-bearing diagnosis is
// Unresolved.
Missing []oerrors.MissingFQN
// Unify holds the always-unify-rung failures: a component primitive body
// that conflicts with a candidate transformer's required body at the same
// FQN. The conflicting candidate is not paired.
Unify []oerrors.UnifyError
// Unresolved holds every demand the platform failed to resolve (0010
// D28): a demanded resource with an empty bucket or with every candidate
// disqualified, and an unhandled trait whose effective optional posture
// is load-bearing (false, or fail-closed unstated). Plan-for-execution
// and Compile fail on a non-empty set; Match stays phase-only and
// returns the full diagnosis.
Unresolved []oerrors.UnresolvedDemand
}
MatchPlan is the full result of matching components against a platform's transformers.
func Match ¶
func Match(components cue.Value, mp *materialize.MaterializedPlatform, instanceName string) (*MatchPlan, error)
Match walks a consumer Module's components against a MaterializedPlatform's #matchers index and returns a MatchPlan describing matched pairs, unmatched components, structured missing-FQN diagnostics, and unify failures. instanceName populates MissingFQN.Instance; a blank value is tolerated when Match is called outside the kernel. The composed map comes from mp.Transformers and the reverse index from mp.Matchers.{resources,traits}.
func (*MatchPlan) MatchedPairs ¶
func (p *MatchPlan) MatchedPairs() []MatchedPair
MatchedPairs returns all matched component-transformer pairs, sorted by component name and then transformer FQN.
func (*MatchPlan) NonMatchedPairs ¶
func (p *MatchPlan) NonMatchedPairs() []NonMatchedPair
NonMatchedPairs returns all non-matched component-transformer pairs with missing labels. Sorted by component name then transformer FQN.
func (*MatchPlan) Warnings ¶
Warnings returns warnings for EFFECTIVELY-OPTIONAL traits not handled by any matched transformer (D28). Those trait values will be ignored in rendering. Load-bearing unhandled traits are not warnings — they sit in Unresolved and fail Plan/Compile.
UnhandledTraits is intentionally distinct from MatchPlan.Missing: a trait is "unhandled" when no matched transformer consumes it (the trait FQN may still have a transformer on the platform), whereas a MissingFQN means no transformer on the platform requires the FQN at all.
type MatchResult ¶
type MatchResult struct {
Matched bool `json:"matched"`
MissingLabels []string `json:"missingLabels"`
}
MatchResult is the per-(component, transformer) match outcome.
type MatchedPair ¶
MatchedPair is a single (component, transformer) pair that matched.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module drives the OPM compile pipeline for a single ModuleInstance.
A Module is constructed once per platform and reused across multiple Execute calls. It is not safe for concurrent use (CUE context is single-threaded).
func NewModule ¶
func NewModule(cueCtx *cue.Context, mp *materialize.MaterializedPlatform, runtimeName string) *Module
NewModule creates a Module for the given materialized platform and runtime identity. cueCtx is the caller Kernel's owned build context — Execute builds the finalized data, the transformer #context.* view, and the rendered output in it, consuming mp.Transformers / mp.Matchers as read-only input (the cross-read source) rather than borrowing their context. The Execute path reads #transforms off mp.Transformers — the native composed map — so callers must Materialize before compiling. runtimeName must be non-empty — the catalog requires #context.#runtimeName to be populated and CUE evaluation fails on empty values.
func (*Module) Execute ¶
func (r *Module) Execute( ctx context.Context, inst *module.Instance, schemaComponents cue.Value, dataComponents cue.Value, plan *MatchPlan, ) (*CompileResult, error)
Execute runs matched transformers against the provided component views and returns rendered values, component summaries, and warnings.
schemaComponents is the non-finalized components value (from inst.MatchComponents()) preserving CUE definition fields needed for metadata extraction. dataComponents is the finalized, constraint-free components value for FillPath injection.
type ModuleResult
deprecated
type ModuleResult = CompileResult
ModuleResult is an alias for CompileResult.
Deprecated: use CompileResult.
type NonMatchedPair ¶
NonMatchedPair is a single (component, transformer) pair that did not match, with the specific labels that were missing.
type UnmatchedComponentsError ¶
type UnmatchedComponentsError struct {
// Components is the list of component names with no matching transformer.
Components []string
// Matches is the full match result matrix, used to build per-component diagnostics.
Matches map[string]map[string]MatchResult
}
UnmatchedComponentsError is returned when one or more components have no matching transformer. It includes per-component diagnostics listing which transformers were evaluated and what was missing (labels, resources, traits).
Each unmatched component is surfaced as a *oerrors.TransformError via Unwrap(), enabling callers to use errors.As for typed handling of individual failures.
func (*UnmatchedComponentsError) Error ¶
func (e *UnmatchedComponentsError) Error() string
func (*UnmatchedComponentsError) Unwrap ¶
func (e *UnmatchedComponentsError) Unwrap() []error
Unwrap returns a slice of *oerrors.TransformError — one per unmatched component — so that callers can use errors.As to extract per-component failure details.
Each TransformError carries the component name and the first non-matching transformer FQN. Its Cause is a plain terminal error describing the failure, not a nested UnmatchedComponentsError, to prevent infinite recursion when errors.As traverses the chain.