99 lines
1.7 KiB
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,
|
|
}
|
|
}
|