Files
commandkit/integrations/ckconfig/validate.go

77 lines
2.3 KiB
Go

package ckconfig
import (
"bytes"
"fmt"
"strings"
commandkit "gitea.maximumdirect.net/eric/CommandKit"
"go.yaml.in/yaml/v4"
)
func runConfigValidation[I, S any](invocation commandkit.Invocation, plan *configOperationPlan[I, S], state S) commandkit.Outcome {
diagnostics := make([]commandkit.Diagnostic, 0)
writtenRecord := false
for _, selected := range plan.scopes {
if err := invocation.Context.Err(); err != nil {
return configOperationFailure(err, diagnostics, writtenRecord)
}
if selected.scope.scope.Acquire == nil {
return configOperationFailure(fmt.Errorf("configuration scope %q has no acquisition callback", selected.scope.scope.Name), diagnostics, writtenRecord)
}
acquired, acquireErr := selected.scope.scope.Acquire(invocation.Context, Request{
Operation: Validate,
Selection: plan.selection,
}, selected.input, state)
diagnostics = append(diagnostics, acquired.Diagnostics...)
if acquireErr != nil {
return configOperationFailure(acquireErr, diagnostics, writtenRecord)
}
if err := invocation.Context.Err(); err != nil {
return configOperationFailure(err, diagnostics, writtenRecord)
}
record, err := validationSuccessRecord(selected.scope.scope.Name, plan.format)
if err != nil {
return configOperationFailure(err, diagnostics, writtenRecord)
}
if plan.format == "yaml" && !writtenRecord {
if err := writeConfigReport(invocation.Streams.Out, []byte("scopes:\n")); err != nil {
return configDeliveryFailure(err, diagnostics, true)
}
}
if err := writeConfigReport(invocation.Streams.Out, record); err != nil {
return configDeliveryFailure(err, diagnostics, true)
}
writtenRecord = true
}
outcome := commandkit.Success()
outcome.Diagnostics = diagnostics
return outcome
}
func validationSuccessRecord(scope, format string) ([]byte, error) {
if format == "text" {
return []byte(scope + ": valid\n"), nil
}
encoded, err := yaml.Marshal(struct {
Name string `yaml:"name"`
Valid bool `yaml:"valid"`
}{Name: scope, Valid: true})
if err != nil {
return nil, err
}
lines := strings.Split(strings.TrimSuffix(string(encoded), "\n"), "\n")
var record bytes.Buffer
for index, line := range lines {
if index == 0 {
record.WriteString(" - ")
} else {
record.WriteString(" ")
}
record.WriteString(line)
record.WriteByte('\n')
}
return record.Bytes(), nil
}