Port native configuration reports

This commit is contained in:
2026-10-11 01:39:23 +00:00
parent 809a36bc46
commit c0f3a21fc7
12 changed files with 671 additions and 288 deletions

View File

@@ -4,69 +4,48 @@ import (
"bytes"
"errors"
"fmt"
"io"
"strconv"
"unicode"
)
func newConfigShowCommand[C any](prepared *preparedConfigSuite[C]) (Command, error) {
spec := CommandSpec[configInput[C]]{
Name: string(ConfigShow),
Summary: "Show effective configuration as YAML.",
Flags: configInputFlags(prepared.suite, "yaml"),
CheckInput: func(input configInput[C]) error {
_, err := preflightConfig(prepared, input, ConfigShow)
return err
},
Run: func(invocation Invocation, input configInput[C]) Outcome {
return runConfigShow(invocation, prepared, input)
},
}
return NewCommand(spec)
}
commandkit "gitea.maximumdirect.net/eric/CommandKit"
)
type effectiveDocument struct {
name string
view ConfigView
view View
}
func runConfigShow[C any](invocation Invocation, prepared *preparedConfigSuite[C], input configInput[C]) Outcome {
if err := invocation.Context.Err(); err != nil {
return Failure(err)
}
scopeNames, err := selectConfigScopes(prepared, input, ConfigShow)
if err != nil {
return Failure(err)
}
contexts := contextsForScopes(prepared, input, scopeNames)
documents := make([]effectiveDocument, 0, len(scopeNames))
diagnostics := make([]Diagnostic, 0)
for _, name := range scopeNames {
scope, ok := findConfigScope(prepared, name)
if !ok || scope.Acquire == nil {
return showFailure(fmt.Errorf("configuration scope %q has no acquisition callback", name), diagnostics, false)
}
func runConfigShow[I, S any](invocation commandkit.Invocation, plan *configOperationPlan[I, S], state S) commandkit.Outcome {
documents := make([]effectiveDocument, 0, len(plan.scopes))
diagnostics := make([]commandkit.Diagnostic, 0)
for _, selected := range plan.scopes {
if err := invocation.Context.Err(); err != nil {
return showFailure(err, diagnostics, false)
return configOperationFailure(err, diagnostics, false)
}
acquired, acquireErr := scope.Acquire(invocation.Context, ConfigRequest{Operation: ConfigShow, Selection: input.Selection}, contexts[name])
if selected.scope.scope.Acquire == nil {
return configOperationFailure(fmt.Errorf("configuration scope %q has no acquisition callback", selected.scope.scope.Name), diagnostics, false)
}
acquired, acquireErr := selected.scope.scope.Acquire(invocation.Context, Request{
Operation: Show,
Selection: plan.selection,
}, selected.input, state)
diagnostics = append(diagnostics, acquired.Diagnostics...)
if acquireErr != nil {
return showFailure(acquireErr, diagnostics, false)
return configOperationFailure(acquireErr, diagnostics, false)
}
if err := invocation.Context.Err(); err != nil {
return showFailure(err, diagnostics, false)
return configOperationFailure(err, diagnostics, false)
}
if acquired.Value.Effective == nil {
return showFailure(fmt.Errorf("configuration scope %q did not provide an effective configuration writer", name), diagnostics, false)
return configOperationFailure(fmt.Errorf("configuration scope %q did not provide an effective configuration writer", selected.scope.scope.Name), diagnostics, false)
}
documents = append(documents, effectiveDocument{name: name, view: acquired.Value})
documents = append(documents, effectiveDocument{name: selected.scope.scope.Name, view: acquired.Value})
}
if err := invocation.Context.Err(); err != nil {
return showFailure(err, diagnostics, false)
return configOperationFailure(err, diagnostics, false)
}
if len(documents) == 1 && input.Scope != "all" {
if len(documents) == 1 && plan.scopeName != "all" {
checked := &checkedWriter{writer: invocation.Streams.Out}
renderErr := documents[0].view.Effective.WriteEffective(checked)
if checked.failure != nil {
@@ -77,11 +56,11 @@ func runConfigShow[C any](invocation Invocation, prepared *preparedConfigSuite[C
}
}
if renderErr != nil {
outcome := showFailure(renderErr, diagnostics, true)
outcome := configOperationFailure(renderErr, diagnostics, true)
outcome.DeliveryError = checked.failure
return outcome
}
outcome := Success()
outcome := commandkit.Success()
outcome.Diagnostics = diagnostics
return outcome
}
@@ -89,38 +68,53 @@ func runConfigShow[C any](invocation Invocation, prepared *preparedConfigSuite[C
written := false
for index, document := range documents {
if err := invocation.Context.Err(); err != nil {
return showFailure(err, diagnostics, written)
return configOperationFailure(err, diagnostics, written)
}
var native bytes.Buffer
if err := document.view.Effective.WriteEffective(&native); err != nil {
return showFailure(err, diagnostics, written)
return configOperationFailure(err, diagnostics, written)
}
if err := invocation.Context.Err(); err != nil {
return showFailure(err, diagnostics, written)
return configOperationFailure(err, diagnostics, written)
}
framed, hasDirective := frameEffectiveYAML(document.name, native.Bytes())
if index > 0 && hasDirective {
if err := writeReport(invocation.Streams.Out, []byte("...\n")); err != nil {
outcome := showFailure(err, diagnostics, true)
outcome.DeliveryError = err
return outcome
if err := writeConfigReport(invocation.Streams.Out, []byte("...\n")); err != nil {
return configDeliveryFailure(err, diagnostics, true)
}
}
if index < len(documents)-1 && len(framed) > 0 && framed[len(framed)-1] != '\n' {
framed = append(framed, '\n')
}
if err := writeReport(invocation.Streams.Out, framed); err != nil {
outcome := showFailure(err, diagnostics, true)
outcome.DeliveryError = err
return outcome
if err := writeConfigReport(invocation.Streams.Out, framed); err != nil {
return configDeliveryFailure(err, diagnostics, true)
}
written = true
}
outcome := Success()
outcome := commandkit.Success()
outcome.Diagnostics = diagnostics
return outcome
}
type checkedWriter struct {
writer io.Writer
failure error
}
func (writer *checkedWriter) Write(content []byte) (int, error) {
if writer.failure != nil {
return 0, writer.failure
}
written, err := writer.writer.Write(content)
if err == nil && written != len(content) {
err = io.ErrShortWrite
}
if err != nil {
writer.failure = err
}
return written, err
}
type yamlPreamble struct {
markerStart int
markerEnd int
@@ -166,8 +160,8 @@ func analyzeYAMLPreamble(native []byte) yamlPreamble {
func frameEffectiveYAML(scope string, native []byte) ([]byte, bool) {
analysis := analyzeYAMLPreamble(native)
label := scope
for _, r := range scope {
if unicode.IsControl(r) {
for _, character := range scope {
if unicode.IsControl(character) {
label = strconv.Quote(scope)
break
}
@@ -175,8 +169,6 @@ func frameEffectiveYAML(scope string, native []byte) ([]byte, bool) {
comment := []byte("# scope: " + label + "\n")
if analysis.markerFound {
out := make([]byte, 0, len(native)+len(comment))
// Inline content may be a block scalar; place the label before
// its marker rather than interrupting the native value.
if analysis.inlineMarker {
out = append(out, native[:analysis.markerStart]...)
out = append(out, comment...)
@@ -205,13 +197,6 @@ func frameEffectiveYAML(scope string, native []byte) ([]byte, bool) {
return result, analysis.hasDirective
}
func showFailure(cause error, diagnostics []Diagnostic, reportStarted bool) Outcome {
outcome := Failure(cause)
outcome.Diagnostics = diagnostics
outcome.ReportIncomplete = reportStarted
return outcome
}
func isYAMLDocumentStart(line []byte) bool {
return bytes.HasPrefix(line, []byte("---")) && (len(line) == 3 || line[3] == ' ' || line[3] == '\t')
}