afero
afero copied to clipboard
zipfs cannot read some directories
Problem
As far as I can tell the zipfs.Fs
backend is intended to behave similarly to a BasePathFs
which references an OsFs
.
i.e. if your application supports providing input as a zip archive or as a directory - then the application should be able to use a BasePathFs
or a zipfs.Fs
without excessive consideration of which FS implementation has been used (based on the discussion in #146 and the source in the referenced spyre project repo).
However, there are cases where the filesystems behaviour differs:
Directory with no explicit entry in zip archive
Steps to reproduce
- Create a directory with the following structure at
/path/to/dir
:
subdir_a/
├─ a_file.yaml
- Create an archive of the same directory at
/path/to/dir.zip
usingcd /path/to/dir; zip ..dir.zip subdir_a/a_file.yaml
. This creates an archive with a single entry. Note that while there is no explicit entry forsubdir_a/
, if the archive is unzipped the resulting directory is identical to/path/to/dir
. - Run the following code
package main
import (
"archive/zip"
"fmt"
"github.com/spf13/afero"
"github.com/spf13/afero/zipfs"
)
func main() {
bpFS := afero.NewBasePathFs(afero.NewOsFs(), "/path/to/dir")
files, err := afero.ReadDir(bpFS, "/")
fmt.Printf("num_files: %v, err: %v\n", len(files), err)
zrc, err := zip.OpenReader("/path/to/dir.zip")
zipFS := zipfs.New(&zrc.Reader)
files, err = afero.ReadDir(zipFS, "/")
fmt.Printf("num_files: %v, err: %v\n", len(files), err)
}
Expected Output
num_files: 1, err: <nil>
num_files: 1, err: <nil>
Actual Output
num_files: 1, err: <nil>
num_files: 0, err: readdir /: no such file or directory
Empty zip file
Steps to reproduce
- Create an empty directory at
/path/to/empty
- Create an empty archive of the same directory at
/path/to/empty.zip
by creating an archive with a single file and then deleting the file:
zip empty.zip anyfile
zip -d empty.zip anyfile
- Run the following code
package main
import (
"archive/zip"
"fmt"
"github.com/spf13/afero"
"github.com/spf13/afero/zipfs"
)
func main() {
bpFS := afero.NewBasePathFs(afero.NewOsFs(), "/path/to/empty")
files, err := afero.ReadDir(bpFS, "/")
fmt.Printf("num_files: %v, err: %v\n", len(files), err)
zrc, err := zip.OpenReader("/path/to/empty.zip")
zipFS := zipfs.New(&zrc.Reader)
files, err = afero.ReadDir(zipFS, "/")
fmt.Printf("num_files: %v, err: %v\n", len(files), err)
}
Expected Output
num_files: 0, err: <nil>
num_files: 0, err: <nil>
Actual Output
num_files: 0, err: <nil>
num_files: 0, err: readdir /: no such file or directory