package ckconfig import ( "bytes" "fmt" "io" "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 { reporter := invocation.Reporter() writtenRecord := false for _, selected := range plan.scopes { if err := invocation.Context.Err(); err != nil { return configFailure("Configuration validation was canceled.", commandkit.Explanation{}, err) } if selected.scope.scope.Acquire == nil { message := fmt.Sprintf("Configuration scope %q has no acquisition callback.", selected.scope.scope.Name) return commandkit.Failure(message) } acquired, acquireErr := selected.scope.scope.Acquire(invocation.Context, Request{ Operation: Validate, Selection: plan.selection, }, selected.input, state) if acquireErr != nil { return configAcquisitionFailure(reporter, "validate", selected.scope.scope.Name, acquired, acquireErr) } queueConfigDiagnostics(reporter, acquired.Diagnostics) if err := invocation.Context.Err(); err != nil { return configFailure("Configuration validation was canceled.", acquired.Explanation, err) } err := reporter.RenderOutput(func(writer io.Writer) error { record, err := validationSuccessRecord(selected.scope.scope.Name, plan.format) if err != nil { return err } if plan.format == "yaml" && !writtenRecord { if _, err := io.WriteString(writer, "scopes:\n"); err != nil { return err } } _, err = writer.Write(record) return err }) if err != nil { if ctxErr := invocation.Context.Err(); ctxErr != nil { return configFailure("Configuration validation was canceled.", acquired.Explanation, ctxErr) } return commandkit.Success() } writtenRecord = true } return commandkit.Success() } 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 }