package config import ( "fmt" "strings" "gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline" ) type ResolveInput struct { PipelineID string Only []string Catalog pipeline.ModuleCatalog LLMProfileOverride string ReferenceOverrides []pipeline.ReferenceBinding ReferenceUnbinds []pipeline.ReferenceUnbind } type EffectiveConfig struct { Config Config PipelineID string Only []string ReferenceOverrides []pipeline.ReferenceBinding ReferenceUnbinds []pipeline.ReferenceUnbind ResolvedPipeline pipeline.ResolvedPipeline } func (c Config) Resolve(input ResolveInput) (EffectiveConfig, error) { c.Concurrency.recomputeStageWorkerDefaults() if err := c.Validate(); err != nil { return EffectiveConfig{}, err } pipelineID := strings.TrimSpace(input.PipelineID) if pipelineID == "" { return EffectiveConfig{}, fmt.Errorf("pipeline id must not be empty") } profile, ok := lookupPipelineProfile(c.Pipelines, pipelineID) if !ok { return EffectiveConfig{}, fmt.Errorf("pipeline %q is not configured", pipelineID) } profile = clonePipelineProfile(profile) profile.ID = pipelineID resolved, err := pipeline.ResolvePipeline(profile, pipeline.ResolveOptions{ Only: input.Only, LLMProfileOverride: input.LLMProfileOverride, ReferenceOverrides: append([]pipeline.ReferenceBinding(nil), input.ReferenceOverrides...), ReferenceUnbinds: append([]pipeline.ReferenceUnbind(nil), input.ReferenceUnbinds...), }, input.Catalog) if err != nil { return EffectiveConfig{}, fmt.Errorf("resolve pipeline %q: %w", pipelineID, err) } return EffectiveConfig{ Config: cloneConfig(c), PipelineID: pipelineID, Only: append([]string(nil), input.Only...), ReferenceOverrides: append([]pipeline.ReferenceBinding(nil), input.ReferenceOverrides...), ReferenceUnbinds: append([]pipeline.ReferenceUnbind(nil), input.ReferenceUnbinds...), ResolvedPipeline: resolved, }, nil } func lookupPipelineProfile(profiles map[string]pipeline.PipelineProfile, pipelineID string) (pipeline.PipelineProfile, bool) { pipelineID = strings.TrimSpace(pipelineID) for rawID, profile := range profiles { if strings.TrimSpace(rawID) == pipelineID { return profile, true } } return pipeline.PipelineProfile{}, false }