diff --git a/pkg/action/install.go b/pkg/action/install.go index d73eca619..3d9c12ebf 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -732,7 +732,7 @@ func writeToFile(outputDir string, name string, data string, appendData bool) er defer f.Close() - _, err = fmt.Fprintf(f, "---\n# Source: %s\n%s\n", name, data) + _, err = fmt.Fprintf(f, "---\n# Source: %s\n%s\n", name, strings.TrimSuffix(data, "\n")) if err != nil { return err diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 0d0e58e4a..d31817941 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -1316,3 +1316,32 @@ func TestInstallRelease_WaitOptionsPassedDownstream(t *testing.T) { // Verify that WaitOptions were passed to GetWaiter is.NotEmpty(failer.RecordedWaitOptions, "WaitOptions should be passed to GetWaiter") } + +func TestWriteToFileNoTrailingNewline(t *testing.T) { + // Use a template whose output already ends with \n to expose the regression. + // Without the fix, writeToFile appends another \n producing double newline at EOF. + templates := []*common.File{ + {Name: "templates/test.yaml", Data: []byte("key: value\n")}, + } + chart := buildChartWithTemplates(templates) + instAction := installAction(t) + vals := map[string]any{} + dir := t.TempDir() + instAction.OutputDir = dir + _, err := instAction.Run(chart, vals) + if err != nil { + t.Fatalf("Failed install: %s", err) + } + path := filepath.Join(dir, "hello/templates/test.yaml") + data, err := os.ReadFile(path) + if err != nil { + t.Fatalf("Failed to read output file: %s", err) + } + c := string(data) + if strings.HasSuffix(c, "\n\n") { + t.Errorf("output file ends with double newline (regression): got %q", c) + } + if !strings.HasSuffix(c, "\n") { + t.Errorf("output file does not end with newline: got %q", c) + } +} diff --git a/pkg/cmd/template.go b/pkg/cmd/template.go index ccc1db719..7aa402252 100644 --- a/pkg/cmd/template.go +++ b/pkg/cmd/template.go @@ -253,7 +253,7 @@ func writeToFile(outputDir string, name string, data string, appendData bool) er defer f.Close() - _, err = fmt.Fprintf(f, "---\n# Source: %s\n%s\n", name, data) + _, err = fmt.Fprintf(f, "---\n# Source: %s\n%s\n", name, strings.TrimSuffix(data, "\n")) if err != nil { return err