Simplify dirArchive by using os.dirFS and have Archive.Open return fs.File

This commit is contained in:
Philipp Wolfer 2025-05-24 02:20:07 +02:00
parent 0231331209
commit 975e208254
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B
2 changed files with 20 additions and 22 deletions

View file

@ -30,6 +30,7 @@ import (
"archive/zip" "archive/zip"
"fmt" "fmt"
"io" "io"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
) )
@ -37,7 +38,7 @@ import (
// Generic archive interface. // Generic archive interface.
type Archive interface { type Archive interface {
Close() error Close() error
OpenFile(path string) (io.ReadCloser, error) Open(path string) (fs.File, error)
Glob(pattern string) ([]FileInfo, error) Glob(pattern string) ([]FileInfo, error)
} }
@ -53,14 +54,14 @@ func OpenArchive(path string) (Archive, error) {
switch mode := fi.Mode(); { switch mode := fi.Mode(); {
case mode.IsRegular(): case mode.IsRegular():
archive := &zipArchive{} archive := &zipArchive{}
err := archive.Open(path) err := archive.OpenArchive(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return archive, nil return archive, nil
case mode.IsDir(): case mode.IsDir():
archive := &dirArchive{} archive := &dirArchive{}
err := archive.Open(path) err := archive.OpenArchive(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -95,7 +96,7 @@ type zipArchive struct {
zip *zip.ReadCloser zip *zip.ReadCloser
} }
func (a *zipArchive) Open(path string) error { func (a *zipArchive) OpenArchive(path string) error {
zip, err := zip.OpenReader(path) zip, err := zip.OpenReader(path)
if err != nil { if err != nil {
return err return err
@ -129,7 +130,7 @@ func (a *zipArchive) Glob(pattern string) ([]FileInfo, error) {
return result, nil return result, nil
} }
func (a *zipArchive) OpenFile(path string) (io.ReadCloser, error) { func (a *zipArchive) Open(path string) (fs.File, error) {
file, err := a.zip.Open(path) file, err := a.zip.Open(path)
if err != nil { if err != nil {
return nil, err return nil, err
@ -139,11 +140,13 @@ func (a *zipArchive) OpenFile(path string) (io.ReadCloser, error) {
// An implementation of the archiveBackend interface for directories. // An implementation of the archiveBackend interface for directories.
type dirArchive struct { type dirArchive struct {
dir string path string
dirFS fs.FS
} }
func (a *dirArchive) Open(path string) error { func (a *dirArchive) OpenArchive(path string) error {
a.dir = filepath.Clean(path) a.path = filepath.Clean(path)
a.dirFS = os.DirFS(path)
return nil return nil
} }
@ -151,28 +154,23 @@ func (a *dirArchive) Close() error {
return nil return nil
} }
func (a *dirArchive) OpenFile(path string) (io.ReadCloser, error) { // Open opens the named file in the archive.
file, err := os.Open(filepath.Join(a.dir, path)) // [fs.File.Close] must be called to release any associated resources.
if err != nil { func (a *dirArchive) Open(path string) (fs.File, error) {
return nil, err return a.dirFS.Open(path)
}
return file, nil
} }
func (a *dirArchive) Glob(pattern string) ([]FileInfo, error) { func (a *dirArchive) Glob(pattern string) ([]FileInfo, error) {
files, err := filepath.Glob(filepath.Join(a.dir, pattern)) files, err := fs.Glob(a.dirFS, pattern)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := make([]FileInfo, 0) result := make([]FileInfo, 0)
for _, filename := range files { for _, name := range files {
name, err := filepath.Rel(a.dir, filename) fullPath := filepath.Join(a.path, name)
if err != nil {
return nil, err
}
info := FileInfo{ info := FileInfo{
Name: name, Name: name,
File: &filesystemFile{path: filename}, File: &filesystemFile{path: fullPath},
} }
result = append(result, info) result = append(result, info)
} }

View file

@ -63,7 +63,7 @@ func (a *ExportArchive) Close() error {
// Read the user information from the archive. // Read the user information from the archive.
func (a *ExportArchive) UserInfo() (UserInfo, error) { func (a *ExportArchive) UserInfo() (UserInfo, error) {
f, err := a.backend.OpenFile("user.json") f, err := a.backend.Open("user.json")
if err != nil { if err != nil {
return UserInfo{}, err return UserInfo{}, err
} }