115 lines
3.4 KiB
Go
115 lines
3.4 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/pathsafe"
|
|
)
|
|
|
|
// Validate checks resolved configuration for required fields and parseable durations.
|
|
func Validate(cfg *Config) error {
|
|
if cfg == nil {
|
|
return fmt.Errorf("config is nil")
|
|
}
|
|
if cfg.Pipeline == nil {
|
|
return fmt.Errorf("pipeline config is required")
|
|
}
|
|
if cfg.Campaign == nil {
|
|
return fmt.Errorf("campaign config is required")
|
|
}
|
|
if cfg.Session == nil {
|
|
return fmt.Errorf("session config is required")
|
|
}
|
|
|
|
if err := ValidatePipelineConfig(cfg.Pipeline); err != nil {
|
|
return fmt.Errorf("pipeline config %q invalid: %w", shortName(cfg.PipelinePath, "pipeline.yml"), err)
|
|
}
|
|
if err := ValidateCampaignConfig(cfg.Campaign); err != nil {
|
|
return fmt.Errorf("campaign config %q invalid: %w", shortName(cfg.CampaignPath, "campaign.yml"), err)
|
|
}
|
|
if err := validateSession(cfg.Session); err != nil {
|
|
return fmt.Errorf("session config %q invalid: %w", shortName(cfg.SessionPath, "session.yml"), err)
|
|
}
|
|
if err := validateResolvedPartyInputs(cfg); err != nil {
|
|
return fmt.Errorf("campaign/session config invalid: %w", err)
|
|
}
|
|
if err := validateCrossConfig(cfg.Pipeline, cfg.Session, cfg.StableInputs); err != nil {
|
|
return fmt.Errorf("pipeline/session config invalid: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ValidatePipelineConfig validates a loaded, defaulted pipeline without
|
|
// requiring session configuration. Callers that require party-driven artifact
|
|
// expansion must resolve a campaign first through LoadPipelineCampaign.
|
|
func ValidatePipelineConfig(cfg *PipelineConfig) error {
|
|
if cfg == nil {
|
|
return fmt.Errorf("pipeline config is required")
|
|
}
|
|
return validatePipeline(cfg)
|
|
}
|
|
|
|
// ValidateCampaignConfig validates a loaded campaign without requiring a
|
|
// session. Party parsing and canonical-party checks remain owned by
|
|
// LoadPipelineCampaign, which has the campaign source path available.
|
|
func ValidateCampaignConfig(cfg *CampaignConfig) error {
|
|
return validateCampaign(cfg)
|
|
}
|
|
|
|
func validatePipeline(cfg *PipelineConfig) error {
|
|
if strings.TrimSpace(cfg.Workspace.Root) == "" {
|
|
return fmt.Errorf("pipeline.workspace.root is required")
|
|
}
|
|
if campaignID := cfg.Campaigns.DefaultCampaignID; campaignID != "" {
|
|
if err := pathsafe.ValidateOpaqueSegment(campaignID); err != nil {
|
|
return fmt.Errorf("pipeline.campaigns.default_campaign_id: %w", err)
|
|
}
|
|
}
|
|
if err := validateStorage(cfg.Storage); err != nil {
|
|
return err
|
|
}
|
|
if err := validateSpool(cfg.Spool); err != nil {
|
|
return err
|
|
}
|
|
if err := validateCache(cfg.Cache); err != nil {
|
|
return err
|
|
}
|
|
if err := validateNotarius(cfg.Notarius, cfg.Scriptorium); err != nil {
|
|
return err
|
|
}
|
|
if err := validatePublish(cfg.Publish, cfg.Scriptorium, cfg.Notarius); err != nil {
|
|
return err
|
|
}
|
|
if err := validateCleanupPublishPolicy(cfg); err != nil {
|
|
return err
|
|
}
|
|
if err := validateWhisperX(cfg.WhisperX); err != nil {
|
|
return err
|
|
}
|
|
if err := validateSeriatim(cfg.Seriatim); err != nil {
|
|
return err
|
|
}
|
|
if err := validateAudita(cfg.Audita); err != nil {
|
|
return err
|
|
}
|
|
if err := validateNormalize(cfg.Normalize); err != nil {
|
|
return err
|
|
}
|
|
if err := validateTrim(cfg.Trim); err != nil {
|
|
return err
|
|
}
|
|
if err := validateRender(cfg.Render); err != nil {
|
|
return err
|
|
}
|
|
if err := validateScriptorium(cfg.Scriptorium, cfg.Notarius); err != nil {
|
|
return err
|
|
}
|
|
if err := validateNotification(cfg.Notification); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|