feat: load zip bundle from io.ReaderAt
arcad/edge/pipeline/head This commit looks good Details

This commit is contained in:
wpetit 2024-05-02 09:43:22 +02:00
parent 0f673671b8
commit 1029cc8f0f
3 changed files with 32 additions and 30 deletions

View File

@ -16,7 +16,7 @@ func TestBundle(t *testing.T) {
bundles := []Bundle{ bundles := []Bundle{
NewDirectoryBundle("testdata/bundle"), NewDirectoryBundle("testdata/bundle"),
NewTarBundle("testdata/bundle.tar.gz"), NewTarBundle("testdata/bundle.tar.gz"),
NewZipBundle("testdata/bundle.zip"), Must(NewZipBundleFromPath("testdata/bundle.zip")),
} }
for _, b := range bundles { for _, b := range bundles {

View File

@ -54,7 +54,7 @@ func matchArchivePattern(archivePath string) (Bundle, error) {
} }
if matches { if matches {
return NewZipBundle(archivePath), nil return NewZipBundleFromPath(archivePath)
} }
matches, err = filepath.Match(fmt.Sprintf("*.%s", ExtZim), base) matches, err = filepath.Match(fmt.Sprintf("*.%s", ExtZim), base)

View File

@ -13,15 +13,10 @@ import (
) )
type ZipBundle struct { type ZipBundle struct {
archivePath string reader *zip.Reader
} }
func (b *ZipBundle) File(filename string) (io.ReadCloser, os.FileInfo, error) { 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( ctx := logger.With(
context.Background(), context.Background(),
logger.F("filename", filename), logger.F("filename", filename),
@ -29,7 +24,7 @@ func (b *ZipBundle) File(filename string) (io.ReadCloser, os.FileInfo, error) {
logger.Debug(ctx, "opening file") logger.Debug(ctx, "opening file")
f, err := reader.Open(filename) f, err := b.reader.Open(filename)
if err != nil { if err != nil {
return nil, nil, errors.WithStack(err) 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) { 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) files := make([]os.FileInfo, 0)
ctx := context.Background() ctx := context.Background()
for _, f := range reader.File { for _, f := range b.reader.File {
if !strings.HasPrefix(f.Name, dirname) { if !strings.HasPrefix(f.Name, dirname) {
continue continue
} }
@ -82,17 +66,35 @@ func (b *ZipBundle) Dir(dirname string) ([]os.FileInfo, error) {
return files, nil return files, nil
} }
func (b *ZipBundle) openArchive() (*zip.ReadCloser, error) { func NewZipBundleFromReader(reader io.ReaderAt, size int64) (*ZipBundle, error) {
zr, err := zip.OpenReader(b.archivePath) zipReader, err := zip.NewReader(reader, size)
if err != nil { 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{ 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
} }