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 }