Implemented tests and added documentation for archive

This commit is contained in:
Philipp Wolfer 2025-05-25 12:46:44 +02:00
parent 4da5697435
commit 28c618ffce
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B
8 changed files with 221 additions and 6 deletions

View file

@ -35,10 +35,17 @@ import (
"path/filepath"
)
// Generic archive interface.
type Archive interface {
Close() error
// Generic interface to access files inside an archive.
type ArchiveReader interface {
io.Closer
// Open the file inside the archive identified by the given path.
// The path is relative to the archive's root.
// The caller must call [fs.File.Close] when finished using the file.
Open(path string) (fs.File, error)
// List files inside the archive which satisfy the given glob pattern.
// This method only returns files, not directories.
Glob(pattern string) ([]FileInfo, error)
}
@ -46,7 +53,7 @@ type Archive interface {
// The archive can be a ZIP file or a directory. The implementation
// will detect the type of archive and return the appropriate
// implementation of the Archive interface.
func OpenArchive(path string) (Archive, error) {
func OpenArchive(path string) (ArchiveReader, error) {
fi, err := os.Stat(path)
if err != nil {
return nil, err
@ -73,10 +80,14 @@ func OpenArchive(path string) (Archive, error) {
// Interface for a file that can be opened when needed.
type OpenableFile interface {
// Open the file for reading.
// The caller is responsible to call [io.ReadCloser.Close] when
// finished reading the file.
Open() (io.ReadCloser, error)
}
// Generic information about a file inside an archive.
// This provides the filename and allows opening the file for reading.
type FileInfo struct {
Name string
File OpenableFile
@ -115,6 +126,10 @@ func (a *zipArchive) Close() error {
func (a *zipArchive) Glob(pattern string) ([]FileInfo, error) {
result := make([]FileInfo, 0)
for _, file := range a.zip.File {
if file.FileInfo().IsDir() {
continue
}
if matched, err := filepath.Match(pattern, file.Name); matched {
if err != nil {
return nil, err
@ -167,6 +182,14 @@ func (a *dirArchive) Glob(pattern string) ([]FileInfo, error) {
}
result := make([]FileInfo, 0)
for _, name := range files {
stat, err := fs.Stat(a.dirFS, name)
if err != nil {
return nil, err
}
if stat.IsDir() {
continue
}
fullPath := filepath.Join(a.path, name)
info := FileInfo{
Name: name,