edge/pkg/bundle/zip_bundle.go

99 lines
1.7 KiB
Go

package bundle
import (
"archive/zip"
"context"
"io"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
type ZipBundle struct {
archivePath string
}
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),
)
logger.Debug(ctx, "opening file")
f, err := reader.Open(filename)
if err != nil {
return nil, nil, errors.WithStack(err)
}
stat, err := f.Stat()
if err != nil {
return nil, nil, errors.WithStack(err)
}
return f, stat, nil
}
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 {
if !strings.HasPrefix(f.Name, dirname) {
continue
}
relPath, err := filepath.Rel(dirname, f.Name)
if err != nil {
return nil, errors.Wrap(err, "could not get relative path")
}
logger.Debug(
ctx, "checking file prefix",
logger.F("dirname", dirname),
logger.F("filename", f.Name),
logger.F("relpath", relPath),
)
if relPath == filepath.Base(f.Name) {
files = append(files, f.FileInfo())
}
}
return files, nil
}
func (b *ZipBundle) openArchive() (*zip.ReadCloser, error) {
zr, err := zip.OpenReader(b.archivePath)
if err != nil {
return nil, errors.Wrapf(err, "could not decompress '%v'", b.archivePath)
}
return zr, nil
}
func NewZipBundle(archivePath string) *ZipBundle {
return &ZipBundle{
archivePath: archivePath,
}
}