package ckconfig import ( "bytes" "errors" "fmt" "io" "strconv" "unicode" commandkit "gitea.maximumdirect.net/eric/CommandKit" ) type effectiveDocument struct { name string view View } 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 configOperationFailure(err, diagnostics, false) } 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 configOperationFailure(acquireErr, diagnostics, false) } if err := invocation.Context.Err(); err != nil { return configOperationFailure(err, diagnostics, false) } if acquired.Value.Effective == nil { 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: selected.scope.scope.Name, view: acquired.Value}) } if err := invocation.Context.Err(); err != nil { return configOperationFailure(err, diagnostics, false) } if len(documents) == 1 && plan.scopeName != "all" { checked := &checkedWriter{writer: invocation.Streams.Out} renderErr := documents[0].view.Effective.WriteEffective(checked) if checked.failure != nil { if renderErr == nil { renderErr = checked.failure } else { renderErr = errors.Join(renderErr, checked.failure) } } if renderErr != nil { outcome := configOperationFailure(renderErr, diagnostics, true) outcome.DeliveryError = checked.failure return outcome } outcome := commandkit.Success() outcome.Diagnostics = diagnostics return outcome } written := false for index, document := range documents { if err := invocation.Context.Err(); err != nil { return configOperationFailure(err, diagnostics, written) } var native bytes.Buffer if err := document.view.Effective.WriteEffective(&native); err != nil { return configOperationFailure(err, diagnostics, written) } if err := invocation.Context.Err(); err != nil { return configOperationFailure(err, diagnostics, written) } framed, hasDirective := frameEffectiveYAML(document.name, native.Bytes()) if index > 0 && hasDirective { 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 := writeConfigReport(invocation.Streams.Out, framed); err != nil { return configDeliveryFailure(err, diagnostics, true) } written = true } 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 markerFound bool inlineMarker bool preambleEnd int hasDirective bool } func analyzeYAMLPreamble(native []byte) yamlPreamble { var analysis yamlPreamble for start := 0; start < len(native); { end := len(native) if newline := bytes.IndexByte(native[start:], '\n'); newline >= 0 { end = start + newline + 1 } lineEnd := end if lineEnd > start && native[lineEnd-1] == '\n' { lineEnd-- } trimmed := bytes.TrimSpace(native[start:lineEnd]) if isYAMLDocumentStart(trimmed) { content := bytes.TrimSpace(trimmed[3:]) analysis.markerStart = start analysis.markerEnd = end analysis.markerFound = true analysis.inlineMarker = len(content) > 0 && content[0] != '#' return analysis } if bytes.HasPrefix(trimmed, []byte("%YAML ")) || bytes.HasPrefix(trimmed, []byte("%TAG ")) { analysis.hasDirective = true } if len(trimmed) == 0 || trimmed[0] == '#' || bytes.HasPrefix(trimmed, []byte("%YAML ")) || bytes.HasPrefix(trimmed, []byte("%TAG ")) { analysis.preambleEnd = end } else { return analysis } start = end } return analysis } func frameEffectiveYAML(scope string, native []byte) ([]byte, bool) { analysis := analyzeYAMLPreamble(native) label := scope for _, character := range scope { if unicode.IsControl(character) { label = strconv.Quote(scope) break } } comment := []byte("# scope: " + label + "\n") if analysis.markerFound { out := make([]byte, 0, len(native)+len(comment)) if analysis.inlineMarker { out = append(out, native[:analysis.markerStart]...) out = append(out, comment...) out = append(out, native[analysis.markerStart:]...) return out, analysis.hasDirective } out = append(out, native[:analysis.markerEnd]...) if analysis.markerEnd > analysis.markerStart && native[analysis.markerEnd-1] != '\n' { out = append(out, '\n') } out = append(out, comment...) out = append(out, native[analysis.markerEnd:]...) return out, analysis.hasDirective } result := make([]byte, 0, len(native)+len(comment)+5) if analysis.hasDirective { result = append(result, native[:analysis.preambleEnd]...) } result = append(result, []byte("---\n")...) result = append(result, comment...) if analysis.hasDirective { result = append(result, native[analysis.preambleEnd:]...) } else { result = append(result, native...) } return result, analysis.hasDirective } func isYAMLDocumentStart(line []byte) bool { return bytes.HasPrefix(line, []byte("---")) && (len(line) == 3 || line[3] == ' ' || line[3] == '\t') }