Skip to content

Commit

Permalink
fs: Improve Open and Stat on ArchiveFS for streams (#335)
Browse files Browse the repository at this point in the history
Fixes #334
  • Loading branch information
mholt authored Apr 21, 2022
1 parent f7aa48e commit 8a97d87
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,9 @@ func (f ArchiveFS) Open(name string) (fs.File, error) {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
}

var archiveFile *os.File
var archiveFile fs.File
var err error
if f.Stream == nil {
if f.Path != "" {
archiveFile, err = os.Open(f.Path)
if err != nil {
return nil, err
Expand All @@ -265,6 +265,8 @@ func (f ArchiveFS) Open(name string) (fs.File, error) {
archiveFile.Close()
}
}()
} else if f.Stream != nil {
archiveFile = fakeArchiveFile{}
}

// apply prefix if fs is rooted in a subtree
Expand Down Expand Up @@ -364,12 +366,16 @@ func (f ArchiveFS) Stat(name string) (fs.FileInfo, error) {
// apply prefix if fs is rooted in a subtree
name = path.Join(f.Prefix, name)

if name == "." && f.Path != "" {
fileInfo, err := os.Stat(f.Path)
if err != nil {
return nil, err
if name == "." {
if f.Path != "" {
fileInfo, err := os.Stat(f.Path)
if err != nil {
return nil, err
}
return dirFileInfo{fileInfo}, nil
} else if f.Stream != nil {
return implicitDirInfo{implicitDirEntry{name}}, nil
}
return dirFileInfo{fileInfo}, nil
}

var archiveFile *os.File
Expand All @@ -389,7 +395,7 @@ func (f ArchiveFS) Stat(name string) (fs.FileInfo, error) {
// created depth-first (i.e. directory contents added before the
// directory itself), in which case we have to iterate through the
// contents first; hence the check for exact filename match (issue #310)
if file.NameInArchive == name {
if strings.TrimRight(file.NameInArchive, "/") == strings.TrimRight(name, "/") {
result = file
return errStopWalk
}
Expand Down Expand Up @@ -587,6 +593,16 @@ func pathWithoutTopDir(fpath string) string {
// traversed during the walk.
var errStopWalk = fmt.Errorf("stop walk")

type fakeArchiveFile struct{}

func (f fakeArchiveFile) Stat() (fs.FileInfo, error) {
return implicitDirInfo{
implicitDirEntry{name: "."},
}, nil
}
func (f fakeArchiveFile) Read([]byte) (int, error) { return 0, io.EOF }
func (f fakeArchiveFile) Close() error { return nil }

// dirFile implements the fs.ReadDirFile interface.
type dirFile struct {
extractedFile
Expand Down

0 comments on commit 8a97d87

Please sign in to comment.