Skip to content

Commit e2b1f0d

Browse files
committed
Lstat method
1 parent 98a5a28 commit e2b1f0d

File tree

6 files changed

+78
-7
lines changed

6 files changed

+78
-7
lines changed

fs.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ type Filesystem interface {
3131
Create(filename string) (File, error)
3232
Open(filename string) (File, error)
3333
OpenFile(filename string, flag int, perm os.FileMode) (File, error)
34+
// Stat returns a FileInfo describing the named file.
3435
Stat(filename string) (FileInfo, error)
36+
// Lstat returns a FileInfo describing the named file. If the file is a
37+
// symbolic link, the returned FileInfo describes the symbolic link. Lstat
38+
// makes no attempt to follow the link.
39+
Lstat(filename string) (FileInfo, error)
3540
ReadDir(path string) ([]FileInfo, error)
3641
TempFile(dir, prefix string) (File, error)
3742
Rename(from, to string) error

memfs/memory.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,19 @@ func (fs *Memory) Stat(filename string) (billy.FileInfo, error) {
114114
return fi, nil
115115
}
116116

117+
func (fs *Memory) Lstat(filename string) (billy.FileInfo, error) {
118+
fullpath := clean(fs.Join(fs.base, filename))
119+
l, ok := fs.links[fullpath]
120+
if !ok {
121+
return fs.Stat(filename)
122+
}
123+
124+
return &fileInfo{
125+
name: filepath.Base(l.Name),
126+
mode: 0777 | os.ModeSymlink,
127+
}, nil
128+
}
129+
117130
// ReadDir returns a list of billy.FileInfo in the given directory.
118131
func (fs *Memory) ReadDir(path string) ([]billy.FileInfo, error) {
119132
path = fs.resolvePath(path)

osfs/os.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ func (fs *OS) RemoveAll(path string) error {
164164
return os.RemoveAll(fullpath)
165165
}
166166

167+
func (fs *OS) Lstat(filename string) (billy.FileInfo, error) {
168+
fullpath := fs.Join(fs.base, filename)
169+
return os.Lstat(fullpath)
170+
}
171+
167172
// Symlink imlements billy.Symlinker.Symlink.
168173
func (fs *OS) Symlink(target, link string) error {
169174
target = filepath.FromSlash(target)

subdirfs/subdir.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ func (s *subdirFs) Stat(filename string) (billy.FileInfo, error) {
9393
return newFileInfo(filepath.Base(fullpath), fi), nil
9494
}
9595

96+
func (s *subdirFs) Lstat(filename string) (billy.FileInfo, error) {
97+
fullpath := s.underlyingPath(filename)
98+
fi, err := s.underlying.Lstat(fullpath)
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
return newFileInfo(filepath.Base(fullpath), fi), nil
104+
}
105+
96106
func (s *subdirFs) ReadDir(path string) ([]billy.FileInfo, error) {
97107
prefix := s.underlyingPath(path)
98108
fis, err := s.underlying.ReadDir(prefix)

test/fs_suite.go

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,19 @@ func (s *FilesystemSuite) TestStat(c *C) {
459459
c.Assert(fi.IsDir(), Equals, false)
460460
}
461461

462+
func (s *FilesystemSuite) TestStatLink(c *C) {
463+
WriteFile(s.FS, "foo/bar", []byte("foo"), customMode)
464+
s.FS.Symlink("bar", "foo/qux")
465+
466+
fi, err := s.FS.Stat("foo/qux")
467+
c.Assert(err, IsNil)
468+
c.Assert(fi.Name(), Equals, "qux")
469+
c.Assert(fi.Size(), Equals, int64(3))
470+
c.Assert(fi.Mode(), Equals, customMode)
471+
c.Assert(fi.ModTime().IsZero(), Equals, false)
472+
c.Assert(fi.IsDir(), Equals, false)
473+
}
474+
462475
func (s *FilesystemSuite) TestStatDir(c *C) {
463476
s.FS.MkdirAll("foo/bar", 0644)
464477

@@ -477,6 +490,30 @@ func (s *FilesystemSuite) TestStatNonExistent(c *C) {
477490
c.Assert(fi, IsNil)
478491
}
479492

493+
func (s *FilesystemSuite) TestLstat(c *C) {
494+
WriteFile(s.FS, "foo/bar", []byte("foo"), customMode)
495+
496+
fi, err := s.FS.Lstat("foo/bar")
497+
c.Assert(err, IsNil)
498+
c.Assert(fi.Name(), Equals, "bar")
499+
c.Assert(fi.Size(), Equals, int64(3))
500+
c.Assert(fi.Mode()&os.ModeSymlink != 0, Equals, false)
501+
c.Assert(fi.ModTime().IsZero(), Equals, false)
502+
c.Assert(fi.IsDir(), Equals, false)
503+
}
504+
505+
func (s *FilesystemSuite) TestLstatLink(c *C) {
506+
WriteFile(s.FS, "foo/bar", []byte("fosddddaaao"), customMode)
507+
s.FS.Symlink("bar", "foo/qux")
508+
509+
fi, err := s.FS.Lstat("foo/qux")
510+
c.Assert(err, IsNil)
511+
c.Assert(fi.Name(), Equals, "qux")
512+
c.Assert(fi.Mode()&os.ModeSymlink != 0, Equals, true)
513+
c.Assert(fi.ModTime().IsZero(), Equals, false)
514+
c.Assert(fi.IsDir(), Equals, false)
515+
}
516+
480517
func (s *FilesystemSuite) TestDirStat(c *C) {
481518
files := []string{"foo", "bar", "qux/baz", "qux/qux"}
482519
for _, name := range files {
@@ -938,8 +975,6 @@ func (s *FilesystemSuite) TestSymlinkBasic(c *C) {
938975
fi, err := s.FS.Stat("link")
939976
c.Assert(err, IsNil)
940977
c.Assert(fi.Name(), Equals, "link")
941-
c.Assert(fi.Mode()&os.ModeSymlink, Not(Equals), 0)
942-
c.Assert(fi.Size(), Equals, int64(0))
943978
}
944979

945980
func (s *FilesystemSuite) TestSymlinkCrossDirs(c *C) {
@@ -952,8 +987,6 @@ func (s *FilesystemSuite) TestSymlinkCrossDirs(c *C) {
952987
fi, err := s.FS.Stat("bar/link")
953988
c.Assert(err, IsNil)
954989
c.Assert(fi.Name(), Equals, "link")
955-
c.Assert(fi.Mode()&os.ModeSymlink, Not(Equals), 0)
956-
c.Assert(fi.Size(), Equals, int64(0))
957990
}
958991

959992
func (s *FilesystemSuite) TestSymlinkLinkToLink(c *C) {
@@ -969,8 +1002,6 @@ func (s *FilesystemSuite) TestSymlinkLinkToLink(c *C) {
9691002
fi, err := s.FS.Stat("linkB")
9701003
c.Assert(err, IsNil)
9711004
c.Assert(fi.Name(), Equals, "linkB")
972-
c.Assert(fi.Mode()&os.ModeSymlink, Not(Equals), 0)
973-
c.Assert(fi.Size(), Equals, int64(0))
9741005
}
9751006

9761007
func (s *FilesystemSuite) TestSymlinkToDir(c *C) {
@@ -983,7 +1014,6 @@ func (s *FilesystemSuite) TestSymlinkToDir(c *C) {
9831014
fi, err := s.FS.Stat("link")
9841015
c.Assert(err, IsNil)
9851016
c.Assert(fi.Name(), Equals, "link")
986-
c.Assert(fi.Mode()&os.ModeSymlink, Not(Equals), 0)
9871017
c.Assert(fi.IsDir(), Equals, true)
9881018
}
9891019

tmpoverlayfs/tmpfs.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ func (t *tmpFs) Stat(path string) (billy.FileInfo, error) {
152152
return t.fs.Stat(path)
153153
}
154154

155+
func (t *tmpFs) Lstat(path string) (billy.FileInfo, error) {
156+
if t.isTmpFile(path) {
157+
return t.tmp.Lstat(path)
158+
}
159+
160+
return t.fs.Lstat(path)
161+
}
162+
155163
func (t *tmpFs) isTmpFile(p string) bool {
156164
p = path.Clean(p)
157165
_, ok := t.tempFiles[p]

0 commit comments

Comments
 (0)