diff --git a/pkg/bundle/bundle_test.go b/pkg/bundle/bundle_test.go index 694e6b3..1dad14a 100644 --- a/pkg/bundle/bundle_test.go +++ b/pkg/bundle/bundle_test.go @@ -16,7 +16,7 @@ func TestBundle(t *testing.T) { bundles := []Bundle{ NewDirectoryBundle("testdata/bundle"), NewTarBundle("testdata/bundle.tar.gz"), - NewZipBundle("testdata/bundle.zip"), + Must(NewZipBundleFromPath("testdata/bundle.zip")), } for _, b := range bundles { diff --git a/pkg/bundle/from_path.go b/pkg/bundle/from_path.go index 2b2f6ed..0532c00 100644 --- a/pkg/bundle/from_path.go +++ b/pkg/bundle/from_path.go @@ -54,7 +54,7 @@ func matchArchivePattern(archivePath string) (Bundle, error) { } if matches { - return NewZipBundle(archivePath), nil + return NewZipBundleFromPath(archivePath) } matches, err = filepath.Match(fmt.Sprintf("*.%s", ExtZim), base) diff --git a/pkg/bundle/zip_bundle.go b/pkg/bundle/zip_bundle.go index 76d8ea0..3553683 100644 --- a/pkg/bundle/zip_bundle.go +++ b/pkg/bundle/zip_bundle.go @@ -13,15 +13,10 @@ import ( ) type ZipBundle struct { - archivePath string + reader *zip.Reader } func (b *ZipBundle) File(filename string) (io.ReadCloser, os.FileInfo, error) { - reader, err := b.openArchive() - if err != nil { - return nil, nil, err - } - ctx := logger.With( context.Background(), logger.F("filename", filename), @@ -29,7 +24,7 @@ func (b *ZipBundle) File(filename string) (io.ReadCloser, os.FileInfo, error) { logger.Debug(ctx, "opening file") - f, err := reader.Open(filename) + f, err := b.reader.Open(filename) if err != nil { return nil, nil, errors.WithStack(err) } @@ -43,21 +38,10 @@ func (b *ZipBundle) File(filename string) (io.ReadCloser, os.FileInfo, error) { } func (b *ZipBundle) Dir(dirname string) ([]os.FileInfo, error) { - reader, err := b.openArchive() - if err != nil { - return nil, err - } - - defer func() { - if err := reader.Close(); err != nil { - panic(errors.WithStack(err)) - } - }() - files := make([]os.FileInfo, 0) ctx := context.Background() - for _, f := range reader.File { + for _, f := range b.reader.File { if !strings.HasPrefix(f.Name, dirname) { continue } @@ -82,17 +66,35 @@ func (b *ZipBundle) Dir(dirname string) ([]os.FileInfo, error) { return files, nil } -func (b *ZipBundle) openArchive() (*zip.ReadCloser, error) { - zr, err := zip.OpenReader(b.archivePath) +func NewZipBundleFromReader(reader io.ReaderAt, size int64) (*ZipBundle, error) { + zipReader, err := zip.NewReader(reader, size) if err != nil { - return nil, errors.Wrapf(err, "could not decompress '%v'", b.archivePath) + return nil, errors.WithStack(err) } - return zr, nil -} - -func NewZipBundle(archivePath string) *ZipBundle { return &ZipBundle{ - archivePath: archivePath, - } + reader: zipReader, + }, nil +} + +func NewZipBundleFromPath(filename string) (*ZipBundle, error) { + file, err := os.Open(filename) + if err != nil { + return nil, errors.WithStack(err) + } + + stat, err := file.Stat() + if err != nil { + return nil, errors.WithStack(err) + } + + return NewZipBundleFromReader(file, stat.Size()) +} + +func Must(bundle Bundle, err error) Bundle { + if err != nil { + panic(errors.WithStack(err)) + } + + return bundle }