Unify application configuration loading

This commit is contained in:
2026-08-30 13:32:45 +00:00
parent f302488075
commit f86b17045d
9 changed files with 163 additions and 56 deletions

View File

@@ -167,42 +167,81 @@ func LoadWithSessionOptions(pipelinePath, campaignPath, sessionPath string, sess
if err != nil {
return nil, err
}
return LoadSessionWithPipelineCampaignOptions(LoadedPipelineCampaign{
PipelinePath: pipelinePath,
Pipeline: pipelineCfg,
CampaignPath: campaignPath,
Campaign: campaignCfg,
}, sessionPath, sessionOpts)
}
// LoadedPipelineCampaign retains one already loaded pipeline and campaign for
// subsequent local or remote session resolution. It prevents a command from
// reloading the root pipeline after campaign selection.
type LoadedPipelineCampaign struct {
PipelinePath string
Pipeline *PipelineConfig
CampaignPath string
Campaign *CampaignConfig
}
// LoadSessionWithPipelineCampaignOptions loads one local session and combines
// it with an already loaded pipeline and campaign.
func LoadSessionWithPipelineCampaignOptions(loaded LoadedPipelineCampaign, sessionPath string, sessionOpts SessionLoadOptions) (*Config, error) {
sessionCfg, err := LoadSessionWithOptions(sessionPath, sessionOpts)
if err != nil {
return nil, err
}
return Resolve(pipelinePath, pipelineCfg, campaignPath, campaignCfg, sessionPath, sessionCfg, SessionSource{
return ResolveLoadedPipelineCampaign(loaded, sessionPath, sessionCfg, SessionSource{
Source: "session_config",
LocalPath: sessionPath,
})
}
// Resolve builds final stage-facing configuration from already loaded
// pipeline, campaign, and session documents.
func Resolve(pipelinePath string, pipelineCfg *PipelineConfig, campaignPath string, campaignCfg *CampaignConfig, sessionPath string, sessionCfg *SessionConfig, sessionSource SessionSource) (*Config, error) {
stableInputs, err := mergeCampaignSession(campaignCfg, sessionCfg, campaignPath, sessionPath)
// ResolveLoadedPipelineCampaign combines an already loaded pipeline and
// campaign with optional already loaded session data. A nil session preserves
// the resolved pipeline/campaign context for callers that need to locate or
// retrieve a session without rereading the root pipeline.
func ResolveLoadedPipelineCampaign(loaded LoadedPipelineCampaign, sessionPath string, sessionCfg *SessionConfig, sessionSource SessionSource) (*Config, error) {
cfg := &Config{
Pipeline: loaded.Pipeline,
Campaign: loaded.Campaign,
Session: sessionCfg,
PipelinePath: loaded.PipelinePath,
CampaignPath: loaded.CampaignPath,
SessionPath: sessionPath,
SessionSource: sessionSource,
}
if sessionCfg == nil {
return cfg, nil
}
stableInputs, err := mergeCampaignSession(loaded.Campaign, sessionCfg, loaded.CampaignPath, sessionPath)
if err != nil {
return nil, err
}
if strings.TrimSpace(sessionSource.Source) == "" {
sessionSource.Source = "session_config"
if strings.TrimSpace(cfg.SessionSource.Source) == "" {
cfg.SessionSource.Source = "session_config"
}
if strings.TrimSpace(sessionSource.LocalPath) == "" {
sessionSource.LocalPath = sessionPath
if strings.TrimSpace(cfg.SessionSource.LocalPath) == "" {
cfg.SessionSource.LocalPath = sessionPath
}
cfg.StableInputs = stableInputs
return cfg, nil
}
return &Config{
Pipeline: pipelineCfg,
Campaign: campaignCfg,
Session: sessionCfg,
PipelinePath: pipelinePath,
CampaignPath: campaignPath,
SessionPath: sessionPath,
StableInputs: stableInputs,
SessionSource: sessionSource,
}, nil
// Resolve builds final stage-facing configuration from already loaded
// pipeline, campaign, and session documents.
func Resolve(pipelinePath string, pipelineCfg *PipelineConfig, campaignPath string, campaignCfg *CampaignConfig, sessionPath string, sessionCfg *SessionConfig, sessionSource SessionSource) (*Config, error) {
if sessionCfg == nil {
return nil, fmt.Errorf("session config is required")
}
return ResolveLoadedPipelineCampaign(LoadedPipelineCampaign{
PipelinePath: pipelinePath,
Pipeline: pipelineCfg,
CampaignPath: campaignPath,
Campaign: campaignCfg,
}, sessionPath, sessionCfg, sessionSource)
}
func campaignSessionPaths(paths ...string) (campaignPath, sessionPath string, err error) {