Repository: ko-build/ko (language: go)

Issue:
Using --image-refs in ko build results in dirty git
Run `ko build` with `--image-refs=refs.txt`
See:
```
2024/08/22 11:18:46 git is in a dirty state
Please check in your pipeline what can be changing the following files:
?? refs.txt
```
It would be nice if this didn't create the file until after the check.


Discussion / hints:

Fix patch:
diff --git a/pkg/commands/resolver.go b/pkg/commands/resolver.go
index c55b961c0d..2e1ce881cc 100644
--- a/pkg/commands/resolver.go
+++ b/pkg/commands/resolver.go
@@ -266,11 +266,7 @@ func makePublisher(po *options.PublishOptions) (publish.Interface, error) {
 	}
 
 	if po.ImageRefsFile != "" {
-		f, err := os.OpenFile(po.ImageRefsFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
-		if err != nil {
-			return nil, err
-		}
-		innerPublisher, err = publish.NewRecorder(innerPublisher, f)
+		innerPublisher, err = publish.NewRecorder(innerPublisher, po.ImageRefsFile)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/publish/recorder.go b/pkg/publish/recorder.go
index c886b5c909..e2915d08c9 100644
--- a/pkg/publish/recorder.go
+++ b/pkg/publish/recorder.go
@@ -17,6 +17,7 @@ package publish
 import (
 	"context"
 	"io"
+	"os"
 	"strings"
 
 	"github.com/google/go-containerregistry/pkg/name"
@@ -27,21 +28,22 @@ import (
 )
 
 // recorder wraps a publisher implementation in a layer that recordes the published
-// references to an io.Writer.
+// references to a file.
 type recorder struct {
-	inner Interface
-	wc    io.Writer
+	inner    Interface
+	fileName string
+	wc       io.Writer
 }
 
 // recorder implements Interface
 var _ Interface = (*recorder)(nil)
 
 // NewRecorder wraps the provided publish.Interface in an implementation that
-// records publish results to an io.Writer.
-func NewRecorder(inner Interface, wc io.Writer) (Interface, error) {
+// records publish results to a file.
+func NewRecorder(inner Interface, name string) (Interface, error) {
 	return &recorder{
-		inner: inner,
-		wc:    wc,
+		inner:    inner,
+		fileName: name,
 	}, nil
 }
 
@@ -70,6 +72,14 @@ func (r *recorder) Publish(ctx context.Context, br build.Result, ref string) (na
 		references = append(references, result.String())
 	}
 
+	if r.wc == nil {
+		f, err := os.OpenFile(r.fileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
+		if err != nil {
+			return nil, err
+		}
+		r.wc = f
+	}
+
 	if _, err := r.wc.Write([]byte(strings.Join(references, "\n") + "\n")); err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/pkg/publish/recorder_test.go b/pkg/publish/recorder_test.go
index 06079c3aeb..3f737b4586 100644
--- a/pkg/publish/recorder_test.go
+++ b/pkg/publish/recorder_test.go
@@ -15,8 +15,9 @@
 package publish
 
 import (
-	"bytes"
 	"context"
+	"os"
+	"path"
 	"strings"
 	"testing"
 
@@ -50,9 +51,10 @@ func TestRecorder(t *testing.T) {
 		return repo.Context().Digest(h.String()), nil
 	}}
 
-	buf := bytes.NewBuffer(nil)
+	dir := t.TempDir()
+	file := path.Join(dir, "testfile")
 
-	recorder, err := NewRecorder(inner, buf)
+	recorder, err := NewRecorder(inner, file)
 	if err != nil {
 		t.Fatalf("NewRecorder() = %v", err)
 	}
@@ -82,7 +84,11 @@ func TestRecorder(t *testing.T) {
 		t.Errorf("recorder.Close() = %v", err)
 	}
 
-	refs := strings.Split(strings.TrimSpace(buf.String()), "\n")
+	buf, err := os.ReadFile(file)
+	if err != nil {
+		t.Fatalf("os.ReadFile() = %v", err)
+	}
+	refs := strings.Split(strings.TrimSpace(string(buf)), "\n")
 
 	if want, got := len(refs), 5; got != want {
 		t.Errorf("len(refs) = %d, wanted %d", got, want)