cli/command/inspect: minor cleanup and improvements

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2025-05-16 13:36:14 +02:00
parent cacd86c3f3
commit 43e496b396
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C

View File

@ -26,23 +26,29 @@ type Inspector interface {
// TemplateInspector uses a text template to inspect elements. // TemplateInspector uses a text template to inspect elements.
type TemplateInspector struct { type TemplateInspector struct {
outputStream io.Writer out io.Writer
buffer *bytes.Buffer buffer *bytes.Buffer
tmpl *template.Template tmpl *template.Template
} }
// NewTemplateInspector creates a new inspector with a template. // NewTemplateInspector creates a new inspector with a template.
func NewTemplateInspector(outputStream io.Writer, tmpl *template.Template) Inspector { func NewTemplateInspector(out io.Writer, tmpl *template.Template) *TemplateInspector {
if out == nil {
out = io.Discard
}
return &TemplateInspector{ return &TemplateInspector{
outputStream: outputStream, out: out,
buffer: new(bytes.Buffer), buffer: new(bytes.Buffer),
tmpl: tmpl, tmpl: tmpl,
} }
} }
// NewTemplateInspectorFromString creates a new TemplateInspector from a string // NewTemplateInspectorFromString creates a new TemplateInspector from a string
// which is compiled into a template. // which is compiled into a template.
func NewTemplateInspectorFromString(out io.Writer, tmplStr string) (Inspector, error) { func NewTemplateInspectorFromString(out io.Writer, tmplStr string) (Inspector, error) {
if out == nil {
return nil, errors.New("no output stream")
}
if tmplStr == "" { if tmplStr == "" {
return NewIndentedInspector(out), nil return NewIndentedInspector(out), nil
} }
@ -65,6 +71,9 @@ type GetRefFunc func(ref string) (any, []byte, error)
// Inspect fetches objects by reference using GetRefFunc and writes the json // Inspect fetches objects by reference using GetRefFunc and writes the json
// representation to the output writer. // representation to the output writer.
func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFunc) error { func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFunc) error {
if out == nil {
return errors.New("no output stream")
}
inspector, err := NewTemplateInspectorFromString(out, tmplStr) inspector, err := NewTemplateInspectorFromString(out, tmplStr)
if err != nil { if err != nil {
return cli.StatusError{StatusCode: 64, Status: err.Error()} return cli.StatusError{StatusCode: 64, Status: err.Error()}
@ -138,18 +147,21 @@ func (i *TemplateInspector) tryRawInspectFallback(rawElement []byte) error {
// Flush writes the result of inspecting all elements into the output stream. // Flush writes the result of inspecting all elements into the output stream.
func (i *TemplateInspector) Flush() error { func (i *TemplateInspector) Flush() error {
if i.buffer.Len() == 0 { if i.buffer.Len() == 0 {
_, err := io.WriteString(i.outputStream, "\n") _, err := io.WriteString(i.out, "\n")
return err return err
} }
_, err := io.Copy(i.outputStream, i.buffer) _, err := io.Copy(i.out, i.buffer)
return err return err
} }
// NewIndentedInspector generates a new inspector with an indented representation // NewIndentedInspector generates a new inspector with an indented representation
// of elements. // of elements.
func NewIndentedInspector(outputStream io.Writer) Inspector { func NewIndentedInspector(out io.Writer) Inspector {
return &elementsInspector{ if out == nil {
outputStream: outputStream, out = io.Discard
}
return &jsonInspector{
out: out,
raw: func(dst *bytes.Buffer, src []byte) error { raw: func(dst *bytes.Buffer, src []byte) error {
return json.Indent(dst, src, "", " ") return json.Indent(dst, src, "", " ")
}, },
@ -161,23 +173,26 @@ func NewIndentedInspector(outputStream io.Writer) Inspector {
// NewJSONInspector generates a new inspector with a compact representation // NewJSONInspector generates a new inspector with a compact representation
// of elements. // of elements.
func NewJSONInspector(outputStream io.Writer) Inspector { func NewJSONInspector(out io.Writer) Inspector {
return &elementsInspector{ if out == nil {
outputStream: outputStream, out = io.Discard
raw: json.Compact, }
el: json.Marshal, return &jsonInspector{
out: out,
raw: json.Compact,
el: json.Marshal,
} }
} }
type elementsInspector struct { type jsonInspector struct {
outputStream io.Writer out io.Writer
elements []any elements []any
rawElements [][]byte rawElements [][]byte
raw func(dst *bytes.Buffer, src []byte) error raw func(dst *bytes.Buffer, src []byte) error
el func(v any) ([]byte, error) el func(v any) ([]byte, error)
} }
func (e *elementsInspector) Inspect(typedElement any, rawElement []byte) error { func (e *jsonInspector) Inspect(typedElement any, rawElement []byte) error {
if rawElement != nil { if rawElement != nil {
e.rawElements = append(e.rawElements, rawElement) e.rawElements = append(e.rawElements, rawElement)
} else { } else {
@ -186,9 +201,9 @@ func (e *elementsInspector) Inspect(typedElement any, rawElement []byte) error {
return nil return nil
} }
func (e *elementsInspector) Flush() error { func (e *jsonInspector) Flush() error {
if len(e.elements) == 0 && len(e.rawElements) == 0 { if len(e.elements) == 0 && len(e.rawElements) == 0 {
_, err := io.WriteString(e.outputStream, "[]\n") _, err := io.WriteString(e.out, "[]\n")
return err return err
} }
@ -216,9 +231,9 @@ func (e *elementsInspector) Flush() error {
buffer = bytes.NewReader(b) buffer = bytes.NewReader(b)
} }
if _, err := io.Copy(e.outputStream, buffer); err != nil { if _, err := io.Copy(e.out, buffer); err != nil {
return err return err
} }
_, err := io.WriteString(e.outputStream, "\n") _, err := io.WriteString(e.out, "\n")
return err return err
} }