diff --git a/approvals/kir_test.TestCLI.StdinMultiDoc.exitcode.approved.txt b/approvals/kir_test.TestCLI.StdinMultiDoc.exitcode.approved.txt new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/approvals/kir_test.TestCLI.StdinMultiDoc.exitcode.approved.txt @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/approvals/kir_test.TestCLI.StdinMultiDoc.input.yaml b/approvals/kir_test.TestCLI.StdinMultiDoc.input.yaml new file mode 100644 index 0000000..2dd5ee5 --- /dev/null +++ b/approvals/kir_test.TestCLI.StdinMultiDoc.input.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web +spec: + template: + spec: + containers: + - image: nginx:1.27 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: backup +spec: + schedule: "0 0 * * *" + jobTemplate: + spec: + template: + spec: + containers: + - image: backup:2.1 diff --git a/approvals/kir_test.TestCLI.StdinMultiDoc.stderr.approved.txt b/approvals/kir_test.TestCLI.StdinMultiDoc.stderr.approved.txt new file mode 100644 index 0000000..e69de29 diff --git a/approvals/kir_test.TestCLI.StdinMultiDoc.stdout.approved.txt b/approvals/kir_test.TestCLI.StdinMultiDoc.stdout.approved.txt new file mode 100644 index 0000000..3412008 --- /dev/null +++ b/approvals/kir_test.TestCLI.StdinMultiDoc.stdout.approved.txt @@ -0,0 +1,2 @@ +nginx:1.27 +backup:2.1 diff --git a/approvals/kir_test.go b/approvals/kir_test.go index 4a14078..bc5cc5d 100644 --- a/approvals/kir_test.go +++ b/approvals/kir_test.go @@ -61,6 +61,18 @@ func TestCLI(t *testing.T) { verify(t, []string{"-"}, f) }) + // StdinMultiDoc pins the multi-document stdin contract: every document in a + // piped stream is processed, not just the first. Without this the single-doc + // Stdin case above passes regardless, so the regression would go unnoticed. + t.Run("StdinMultiDoc", func(t *testing.T) { + f, err := os.Open("kir_test.TestCLI.StdinMultiDoc.input.yaml") + if err != nil { + t.Fatal(err) + } + defer f.Close() + verify(t, []string{"-"}, f) + }) + t.Run("MissingFile", func(t *testing.T) { verify(t, []string{"does-not-exist.yaml"}, nil) }) 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 {