diff --git a/deb/deb.go b/deb/deb.go index 60ae6912..c9f5d9fa 100644 --- a/deb/deb.go +++ b/deb/deb.go @@ -324,8 +324,10 @@ func addArFile(w *ar.Writer, name string, body []byte, date time.Time) error { if err := w.WriteHeader(&header); err != nil { return fmt.Errorf("cannot write file header: %w", err) } - _, err := w.Write(body) - return err + if _, err := w.Write(body); err != nil { + return fmt.Errorf("cannot write %s body to deb: %w", name, err) + } + return nil } type nopCloser struct { @@ -715,7 +717,7 @@ func newFileInsideTar(out *tar.Writer, name string, content []byte, modtime time func newFilePathInsideTar(out *tar.Writer, path, dest string, mode int64, modtime time.Time) error { content, err := os.ReadFile(path) if err != nil { - return err + return fmt.Errorf("cannot read %s: %w", path, err) } return newItemInsideTar(out, content, &tar.Header{ Name: files.AsExplicitRelativePath(dest), diff --git a/deb/deb_test.go b/deb/deb_test.go index 7e650b87..f6098a60 100644 --- a/deb/deb_test.go +++ b/deb/deb_test.go @@ -1660,3 +1660,55 @@ func verifyDpkgSigFileHashes(arFiles map[string][]byte, msg string) error { } return nil } + +type failAfterNWriter struct { + n int + err error +} + +func (w *failAfterNWriter) Write(p []byte) (int, error) { + if w.n <= 0 { + return 0, w.err + } + if len(p) > w.n { + p = p[:w.n] + } + w.n -= len(p) + return len(p), nil +} + +func TestWriterPathErrorsAreWrapped(t *testing.T) { + tests := []struct { + name string + fn func() error + want error + }{ + { + name: "addArFile write error", + fn: func() error { + fw := &failAfterNWriter{n: 68, err: os.ErrClosed} + w := ar.NewWriter(fw) + if err := w.WriteGlobalHeader(); err != nil { + return err + } + return addArFile(w, "test", []byte("body"), time.Now()) + }, + want: os.ErrClosed, + }, + { + name: "newFilePathInsideTar read error", + fn: func() error { + tw := tar.NewWriter(io.Discard) + return newFilePathInsideTar(tw, "/nonexistent/path", "dest", 0o644, time.Now()) + }, + want: os.ErrNotExist, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.fn() + require.ErrorIs(t, err, tt.want) + }) + } +} diff --git a/rpm/rpm.go b/rpm/rpm.go index 1df627df..3682134f 100644 --- a/rpm/rpm.go +++ b/rpm/rpm.go @@ -331,14 +331,14 @@ func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error { if info.RPM.Scripts.PreTrans != "" { data, err := os.ReadFile(info.RPM.Scripts.PreTrans) if err != nil { - return err + return fmt.Errorf("cannot read pretrans script %s: %w", info.RPM.Scripts.PreTrans, err) } rpm.AddPretrans(string(data)) } if info.Scripts.PreInstall != "" { data, err := os.ReadFile(info.Scripts.PreInstall) if err != nil { - return err + return fmt.Errorf("cannot read preinstall script %s: %w", info.Scripts.PreInstall, err) } rpm.AddPrein(string(data)) } @@ -346,7 +346,7 @@ func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error { if info.Scripts.PreRemove != "" { data, err := os.ReadFile(info.Scripts.PreRemove) if err != nil { - return err + return fmt.Errorf("cannot read preremove script %s: %w", info.Scripts.PreRemove, err) } rpm.AddPreun(string(data)) } @@ -354,7 +354,7 @@ func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error { if info.Scripts.PostInstall != "" { data, err := os.ReadFile(info.Scripts.PostInstall) if err != nil { - return err + return fmt.Errorf("cannot read postinstall script %s: %w", info.Scripts.PostInstall, err) } rpm.AddPostin(string(data)) } @@ -362,7 +362,7 @@ func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error { if info.Scripts.PostRemove != "" { data, err := os.ReadFile(info.Scripts.PostRemove) if err != nil { - return err + return fmt.Errorf("cannot read postremove script %s: %w", info.Scripts.PostRemove, err) } rpm.AddPostun(string(data)) } @@ -370,7 +370,7 @@ func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error { if info.RPM.Scripts.PostTrans != "" { data, err := os.ReadFile(info.RPM.Scripts.PostTrans) if err != nil { - return err + return fmt.Errorf("cannot read posttrans script %s: %w", info.RPM.Scripts.PostTrans, err) } rpm.AddPosttrans(string(data)) } @@ -378,7 +378,7 @@ func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error { if info.RPM.Scripts.Verify != "" { data, err := os.ReadFile(info.RPM.Scripts.Verify) if err != nil { - return err + return fmt.Errorf("cannot read verify script %s: %w", info.RPM.Scripts.Verify, err) } rpm.AddVerifyScript(string(data)) } @@ -463,7 +463,7 @@ func asRPMSymlink(content *files.Content) *rpmpack.RPMFile { func asRPMFile(content *files.Content, fileType rpmpack.FileType) (*rpmpack.RPMFile, error) { data, err := os.ReadFile(content.Source) if err != nil && content.Type != files.TypeRPMGhost { - return nil, err + return nil, fmt.Errorf("cannot read %s: %w", content.Source, err) } return &rpmpack.RPMFile{ diff --git a/rpm/rpm_test.go b/rpm/rpm_test.go index c62f6a8c..49345906 100644 --- a/rpm/rpm_test.go +++ b/rpm/rpm_test.go @@ -17,6 +17,7 @@ import ( "github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2/files" "github.com/goreleaser/nfpm/v2/internal/sign" + "github.com/google/rpmpack" "github.com/sassoftware/go-rpmutils" "github.com/sassoftware/go-rpmutils/cpio" "github.com/stretchr/testify/require" @@ -1308,3 +1309,46 @@ func extractFileHeaderFromRpm(rpm []byte, filename string) (*cpio.Cpio_newc_head return nil, os.ErrNotExist } + +func TestWriterPathErrorsAreWrapped(t *testing.T) { + tests := []struct { + name string + fn func() error + want error + }{ + { + name: "asRPMFile read error", + fn: func() error { + content := &files.Content{Source: "/nonexistent/path", Destination: "/dest"} + _, err := asRPMFile(content, rpmpack.GenericFile) + return err + }, + want: os.ErrNotExist, + }, + { + name: "addScriptFiles read error", + fn: func() error { + info := &nfpm.Info{ + Overridables: nfpm.Overridables{ + Scripts: nfpm.Scripts{ + PreInstall: "/nonexistent/path", + }, + }, + } + rpmPkg, err := rpmpack.NewRPM(rpmpack.RPMMetaData{Name: "test"}) + if err != nil { + return err + } + return addScriptFiles(info, rpmPkg) + }, + want: os.ErrNotExist, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.fn() + require.ErrorIs(t, err, tt.want) + }) + } +}