From b19278d316e927439c86e6943865ce56fdd46375 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Aug 2026 08:00:01 +0000 Subject: [PATCH] Process all documents from stdin, not just the first ProcessStdin passed the whole stdin buffer to yamlparser.ProcessData, whose decoder only reads the first YAML document, so a multi-document stream piped in (e.g. `kubectl get ... -o yaml | kir -`) silently dropped every document after the first. Route stdin through the same document-splitting path already used for files (extracted as processDocuments) so both handle multi-document input identically. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Pc6NAURAqjU4LYJx93tgSC --- processor/processdocuments_test.go | 43 ++++++++++++++++++++++++++++++ processor/processor.go | 8 +++++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 processor/processdocuments_test.go diff --git a/processor/processdocuments_test.go b/processor/processdocuments_test.go new file mode 100644 index 0000000..c92a0da --- /dev/null +++ b/processor/processdocuments_test.go @@ -0,0 +1,43 @@ +package processor + +import "testing" + +// processDocuments backs both ProcessFile and ProcessStdin. Previously stdin +// only ever processed the first document; this verifies the shared path +// collects images from every document in a multi-document stream. +func TestProcessDocumentsMultiple(t *testing.T) { + data := []byte(` +apiVersion: v1 +kind: Pod +metadata: + name: first +spec: + containers: + - name: c + image: image-one +--- +apiVersion: v1 +kind: Pod +metadata: + name: second +spec: + containers: + - name: c + image: image-two +`) + + images, err := processDocuments(data) + if err != nil { + t.Fatalf("processDocuments() error = %v", err) + } + + expected := []string{"image-one", "image-two"} + if len(images) != len(expected) { + t.Fatalf("expected %d images, got %d: %v", len(expected), len(images), images) + } + for i, img := range images { + if img != expected[i] { + t.Errorf("expected image %q, got %q", expected[i], img) + } + } +} diff --git a/processor/processor.go b/processor/processor.go index 1015cbb..5d83e95 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -17,7 +17,7 @@ func ProcessStdin(r io.Reader) ([]string, error) { if err != nil { return nil, fmt.Errorf("error reading stdin: %v", err) } - return yamlparser.ProcessData(data) + return processDocuments(data) } func ProcessFile(filePath string) ([]string, error) { @@ -25,7 +25,13 @@ func ProcessFile(filePath string) ([]string, error) { if err != nil { return nil, fmt.Errorf("error reading file: %v", err) } + return processDocuments(data) +} +// processDocuments splits a (possibly multi-document) YAML stream and collects +// the images from every document. Both the file and stdin paths go through it +// so they handle multi-document input identically. +func processDocuments(data []byte) ([]string, error) { var images []string docs := bytes.Split(data, []byte("\n---\n")) for _, doc := range docs {