Move integration code into optional modules
This commit is contained in:
141
integrations/ckconfig/sources.go
Normal file
141
integrations/ckconfig/sources.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package ckconfig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func newConfigSourcesCommand[C any](prepared *preparedConfigSuite[C]) (Command, error) {
|
||||
spec := CommandSpec[configInput[C]]{
|
||||
Name: string(ConfigSources),
|
||||
Summary: "List configuration sources used by a scope.",
|
||||
Flags: configInputFlags(prepared.suite, "text"),
|
||||
CheckInput: func(input configInput[C]) error {
|
||||
_, err := preflightConfig(prepared, input, ConfigSources)
|
||||
return err
|
||||
},
|
||||
Run: func(invocation Invocation, input configInput[C]) Outcome {
|
||||
return runConfigSources(invocation, prepared, input)
|
||||
},
|
||||
}
|
||||
return NewCommand(spec)
|
||||
}
|
||||
|
||||
type sourceReport struct {
|
||||
Scope string `yaml:"scope"`
|
||||
Sources []sourceDTO `yaml:"sources"`
|
||||
}
|
||||
|
||||
type sourceDTO struct {
|
||||
ID string `yaml:"id"`
|
||||
Label string `yaml:"label"`
|
||||
Path string `yaml:"path"`
|
||||
Layer string `yaml:"layer"`
|
||||
Kind string `yaml:"kind"`
|
||||
UnderlayIndex int `yaml:"underlay_index"`
|
||||
ImportedFrom *locationDTO `yaml:"imported_from"`
|
||||
}
|
||||
|
||||
type locationDTO struct {
|
||||
SourceID string `yaml:"source_id"`
|
||||
Line int `yaml:"line"`
|
||||
Column int `yaml:"column"`
|
||||
}
|
||||
|
||||
func runConfigSources[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, ConfigSources)
|
||||
if err != nil {
|
||||
return Failure(err)
|
||||
}
|
||||
contexts := contextsForScopes(prepared, input, scopeNames)
|
||||
name := scopeNames[0]
|
||||
scope, ok := findConfigScope(prepared, name)
|
||||
if !ok || scope.Acquire == nil {
|
||||
return sourceReportFailure(fmt.Errorf("configuration scope %q has no acquisition callback", name), nil, false)
|
||||
}
|
||||
if err := invocation.Context.Err(); err != nil {
|
||||
return sourceReportFailure(err, nil, false)
|
||||
}
|
||||
acquired, acquireErr := scope.Acquire(invocation.Context, ConfigRequest{Operation: ConfigSources, Selection: input.Selection}, contexts[name])
|
||||
diagnostics := append([]Diagnostic(nil), acquired.Diagnostics...)
|
||||
if acquireErr != nil {
|
||||
return sourceReportFailure(acquireErr, diagnostics, false)
|
||||
}
|
||||
if err := invocation.Context.Err(); err != nil {
|
||||
return sourceReportFailure(err, diagnostics, false)
|
||||
}
|
||||
|
||||
if acquired.Value.Sources == nil {
|
||||
return sourceReportFailure(fmt.Errorf("configuration scope %q did not provide a source reader", name), diagnostics, false)
|
||||
}
|
||||
sources := acquired.Value.Sources.Sources()
|
||||
document := sourceReport{Scope: name, Sources: make([]sourceDTO, 0, len(sources))}
|
||||
for _, source := range sources {
|
||||
item := sourceDTO{
|
||||
ID: source.ID,
|
||||
Label: source.Label,
|
||||
Path: source.Path,
|
||||
Layer: string(source.Layer),
|
||||
Kind: string(source.Kind),
|
||||
UnderlayIndex: source.UnderlayIndex,
|
||||
}
|
||||
if source.ImportedFrom != nil {
|
||||
item.ImportedFrom = &locationDTO{SourceID: source.ImportedFrom.SourceID, Line: source.ImportedFrom.Line, Column: source.ImportedFrom.Column}
|
||||
}
|
||||
document.Sources = append(document.Sources, item)
|
||||
}
|
||||
|
||||
var report bytes.Buffer
|
||||
if input.Format == "yaml" {
|
||||
if err := encodeYAML(&report, document); err != nil {
|
||||
return sourceReportFailure(err, diagnostics, false)
|
||||
}
|
||||
} else {
|
||||
writeSourceReportText(&report, document)
|
||||
}
|
||||
if err := invocation.Context.Err(); err != nil {
|
||||
return sourceReportFailure(err, diagnostics, false)
|
||||
}
|
||||
if err := writeReport(invocation.Streams.Out, report.Bytes()); err != nil {
|
||||
outcome := sourceReportFailure(err, diagnostics, true)
|
||||
outcome.DeliveryError = err
|
||||
return outcome
|
||||
}
|
||||
outcome := Success()
|
||||
outcome.Diagnostics = diagnostics
|
||||
return outcome
|
||||
}
|
||||
|
||||
func writeSourceReportText(writer *bytes.Buffer, document sourceReport) {
|
||||
_, _ = fmt.Fprintf(writer, "Scope: %s\n", strconv.Quote(document.Scope))
|
||||
if len(document.Sources) == 0 {
|
||||
_, _ = writer.WriteString("Sources: []\n")
|
||||
return
|
||||
}
|
||||
_, _ = writer.WriteString("Sources:\n")
|
||||
for _, source := range document.Sources {
|
||||
_, _ = fmt.Fprintf(writer, " - id: %s\n", strconv.Quote(source.ID))
|
||||
_, _ = fmt.Fprintf(writer, " label: %s\n", strconv.Quote(source.Label))
|
||||
_, _ = fmt.Fprintf(writer, " path: %s\n", strconv.Quote(source.Path))
|
||||
_, _ = fmt.Fprintf(writer, " layer: %s\n", strconv.Quote(source.Layer))
|
||||
_, _ = fmt.Fprintf(writer, " kind: %s\n", strconv.Quote(source.Kind))
|
||||
_, _ = fmt.Fprintf(writer, " underlay_index: %d\n", source.UnderlayIndex)
|
||||
if source.ImportedFrom == nil {
|
||||
_, _ = writer.WriteString(" imported_from: null\n")
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(writer, " imported_from: {source_id: %s, line: %d, column: %d}\n",
|
||||
strconv.Quote(source.ImportedFrom.SourceID), source.ImportedFrom.Line, source.ImportedFrom.Column)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sourceReportFailure(cause error, diagnostics []Diagnostic, reportStarted bool) Outcome {
|
||||
outcome := Failure(cause)
|
||||
outcome.Diagnostics = diagnostics
|
||||
outcome.ReportIncomplete = reportStarted
|
||||
return outcome
|
||||
}
|
||||
Reference in New Issue
Block a user