Build validation filter sets once per invocation

This commit is contained in:
2026-11-07 12:07:50 +00:00
parent 3223b5cb82
commit d72c9a788f
3 changed files with 59 additions and 7 deletions

View File

@@ -3,7 +3,6 @@ package ckconfig
import (
"errors"
"fmt"
"slices"
"text/template"
commandkit "go.maximumdirect.net/commandkit"
@@ -62,6 +61,14 @@ func runConfigValidation[I, S any](invocation commandkit.Invocation, plan *confi
reporter := invocation.Reporter()
report := validationReport{Scopes: make([]validationScope, 0, len(plan.scopes))}
outcome := commandkit.Success()
severities := make(map[configkit.Severity]bool, len(plan.severities))
for _, severity := range plan.severities {
severities[severity] = true
}
codes := make(map[string]bool, len(plan.codes))
for _, code := range plan.codes {
codes[code] = true
}
for _, selected := range plan.scopes {
if err := invocation.Context.Err(); err != nil {
outcome = configFailure("Configuration validation was canceled.", commandkit.Explanation{}, err)
@@ -71,7 +78,7 @@ func runConfigValidation[I, S any](invocation commandkit.Invocation, plan *confi
if selected.scope.scope.Acquire == nil {
entry := validationScope{Scope: name, Outcome: "failed"}
if plan.details {
entry.Details = projectValidationDetails(View{}, plan.severities, plan.codes)
entry.Details = projectValidationDetails(View{}, severities, codes)
}
report.Scopes = append(report.Scopes, entry)
outcome = commandkit.Failure(fmt.Sprintf("Configuration scope %q has no acquisition callback.", name))
@@ -84,7 +91,7 @@ func runConfigValidation[I, S any](invocation commandkit.Invocation, plan *confi
}
entry := validationScope{Scope: name, Outcome: "valid"}
if plan.details {
entry.Details = projectValidationDetails(acquired.Value, plan.severities, plan.codes)
entry.Details = projectValidationDetails(acquired.Value, severities, codes)
}
if canceled := invocation.Context.Err(); canceled != nil {
entry.Outcome = "canceled"
@@ -114,7 +121,7 @@ func runConfigValidation[I, S any](invocation commandkit.Invocation, plan *confi
return outcome
}
func projectValidationDetails(view View, severities []configkit.Severity, codes []string) *validationDetails {
func projectValidationDetails(view View, severities map[configkit.Severity]bool, codes map[string]bool) *validationDetails {
details := &validationDetails{State: "unavailable", Findings: []validationFinding{}, Sources: []validationSource{}}
if view.Findings == nil {
return details
@@ -126,10 +133,10 @@ func projectValidationDetails(view View, severities []configkit.Severity, codes
details.State = "filtered"
references := make(map[string]bool)
for _, record := range view.Findings.Records {
if len(severities) > 0 && !slices.Contains(severities, record.Severity) {
if len(severities) > 0 && !severities[record.Severity] {
continue
}
if len(codes) > 0 && !slices.Contains(codes, string(record.Code)) {
if len(codes) > 0 && !codes[string(record.Code)] {
continue
}
finding := validationFinding{Code: string(record.Code), Severity: string(record.Severity), Path: record.Path.String(), Message: record.Message, Related: locationReports(record.Related)}