Unify report module config traversal
This commit is contained in:
@@ -12,116 +12,92 @@ import (
|
||||
)
|
||||
|
||||
func (cfg Config) ReportModuleOverrides() (map[report.ID][]module.ConfigItem, error) {
|
||||
overrides := map[report.ID][]module.ConfigItem{}
|
||||
seenReports := map[report.ID]string{}
|
||||
for key, reportCfg := range cfg.Reports {
|
||||
id, err := report.IDForConfigKey(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reports.%s: %w", key, err)
|
||||
}
|
||||
if previous, ok := seenReports[id]; ok {
|
||||
return nil, fmt.Errorf("reports.%s duplicates report override %q", key, previous)
|
||||
}
|
||||
seenReports[id] = key
|
||||
if !reportCfg.deterministicModulesSet {
|
||||
continue
|
||||
}
|
||||
overrides[id] = moduleItemsFromConfig(reportCfg.DeterministicModules)
|
||||
}
|
||||
return overrides, nil
|
||||
return traverseReportModules(&cfg, reportModuleTraversalOptions{
|
||||
normalizeOptions: true,
|
||||
})
|
||||
}
|
||||
|
||||
func normalizeReportModules(cfg *Config) error {
|
||||
if cfg.Reports == nil {
|
||||
cfg.Reports = map[string]ReportConfig{}
|
||||
}
|
||||
moduleRegistry, err := briefing.DefaultModuleRegistry()
|
||||
if err != nil {
|
||||
return fmt.Errorf("initialize module registry: %w", err)
|
||||
}
|
||||
reportRegistry := report.DefaultRegistry()
|
||||
seenReports := map[report.ID]string{}
|
||||
for key, reportCfg := range cfg.Reports {
|
||||
reportID, err := report.IDForConfigKey(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reports.%s: %w", key, err)
|
||||
}
|
||||
if previous, ok := seenReports[reportID]; ok {
|
||||
return fmt.Errorf("reports.%s duplicates report override %q", key, previous)
|
||||
}
|
||||
seenReports[reportID] = key
|
||||
if _, err := reportRegistry.Lookup(reportID); err != nil {
|
||||
return fmt.Errorf("reports.%s: %w", key, err)
|
||||
}
|
||||
if !reportCfg.deterministicModulesSet {
|
||||
continue
|
||||
}
|
||||
for i, rawItem := range reportCfg.DeterministicModules {
|
||||
options, err := normalizeModuleOptions(moduleRegistry, rawItem.ID, rawItem.Options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reports.%s.deterministic_modules[%d]: %w", key, i, err)
|
||||
}
|
||||
reportCfg.DeterministicModules[i].Options = options
|
||||
}
|
||||
items := moduleItemsFromConfig(reportCfg.DeterministicModules)
|
||||
if err := moduleRegistry.ValidateComposition(reportID, items); err != nil {
|
||||
return fmt.Errorf("reports.%s.deterministic_modules: %w", key, err)
|
||||
}
|
||||
cfg.Reports[key] = reportCfg
|
||||
}
|
||||
return nil
|
||||
_, err := traverseReportModules(cfg, reportModuleTraversalOptions{
|
||||
normalizeOptions: true,
|
||||
updateConfig: true,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func validateReportModules(cfg Config) error {
|
||||
_, err := traverseReportModules(&cfg, reportModuleTraversalOptions{
|
||||
normalizeOptions: true,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
type reportModuleTraversalOptions struct {
|
||||
normalizeOptions bool
|
||||
updateConfig bool
|
||||
}
|
||||
|
||||
func traverseReportModules(cfg *Config, opts reportModuleTraversalOptions) (map[report.ID][]module.ConfigItem, error) {
|
||||
overrides := map[report.ID][]module.ConfigItem{}
|
||||
if cfg.Reports == nil {
|
||||
return nil
|
||||
return overrides, nil
|
||||
}
|
||||
moduleRegistry, err := briefing.DefaultModuleRegistry()
|
||||
if err != nil {
|
||||
return fmt.Errorf("initialize module registry: %w", err)
|
||||
return nil, fmt.Errorf("initialize module registry: %w", err)
|
||||
}
|
||||
reportRegistry := report.DefaultRegistry()
|
||||
seenReports := map[report.ID]string{}
|
||||
for key, reportCfg := range cfg.Reports {
|
||||
reportID, err := report.IDForConfigKey(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reports.%s: %w", key, err)
|
||||
return nil, fmt.Errorf("reports.%s: %w", key, err)
|
||||
}
|
||||
if previous, ok := seenReports[reportID]; ok {
|
||||
return fmt.Errorf("reports.%s duplicates report override %q", key, previous)
|
||||
return nil, fmt.Errorf("reports.%s duplicates report override %q", key, previous)
|
||||
}
|
||||
seenReports[reportID] = key
|
||||
if _, err := reportRegistry.Lookup(reportID); err != nil {
|
||||
return fmt.Errorf("reports.%s: %w", key, err)
|
||||
return nil, fmt.Errorf("reports.%s: %w", key, err)
|
||||
}
|
||||
if !reportCfg.deterministicModulesSet {
|
||||
continue
|
||||
}
|
||||
items := make([]module.ConfigItem, 0, len(reportCfg.DeterministicModules))
|
||||
for i, rawItem := range reportCfg.DeterministicModules {
|
||||
options := rawItem.Options
|
||||
if options != nil {
|
||||
normalized, err := normalizeModuleOptions(moduleRegistry, rawItem.ID, options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reports.%s.deterministic_modules[%d]: %w", key, i, err)
|
||||
}
|
||||
options = normalized
|
||||
}
|
||||
items = append(items, module.ConfigItem{ID: rawItem.ID, Options: options})
|
||||
items, normalized, err := moduleItemsFromConfig(moduleRegistry, key, reportCfg.DeterministicModules, opts.normalizeOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := moduleRegistry.ValidateComposition(reportID, items); err != nil {
|
||||
return fmt.Errorf("reports.%s.deterministic_modules: %w", key, err)
|
||||
return nil, fmt.Errorf("reports.%s.deterministic_modules: %w", key, err)
|
||||
}
|
||||
overrides[reportID] = items
|
||||
if opts.updateConfig {
|
||||
reportCfg.DeterministicModules = normalized
|
||||
cfg.Reports[key] = reportCfg
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return overrides, nil
|
||||
}
|
||||
|
||||
func moduleItemsFromConfig(items []ModuleConfigItem) []module.ConfigItem {
|
||||
func moduleItemsFromConfig(registry briefing.ModuleRegistry, reportKey string, items []ModuleConfigItem, normalizeOptions bool) ([]module.ConfigItem, []ModuleConfigItem, error) {
|
||||
out := make([]module.ConfigItem, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, module.ConfigItem{ID: item.ID, Options: item.Options})
|
||||
normalizedItems := append([]ModuleConfigItem(nil), items...)
|
||||
for i, item := range items {
|
||||
options := item.Options
|
||||
if normalizeOptions {
|
||||
var err error
|
||||
options, err = normalizeModuleOptions(registry, item.ID, item.Options)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("reports.%s.deterministic_modules[%d]: %w", reportKey, i, err)
|
||||
}
|
||||
normalizedItems[i].Options = options
|
||||
}
|
||||
out = append(out, module.ConfigItem{ID: item.ID, Options: options})
|
||||
}
|
||||
return out
|
||||
return out, normalizedItems, nil
|
||||
}
|
||||
|
||||
func normalizeModuleOptions(registry briefing.ModuleRegistry, id module.ID, raw any) (any, error) {
|
||||
|
||||
Reference in New Issue
Block a user