@@ -71,7 +71,11 @@ func (p *Path) Fs() afero.Fs {
7171}
7272
7373func (p * Path ) doesNotImplementErr (interfaceName string ) error {
74- return errors .Wrapf (ErrDoesNotImplement , "Path's afero filesystem %s does not implement %s" , getFsName (p .fs ), interfaceName )
74+ return doesNotImplementErr (interfaceName , p .Fs ())
75+ }
76+
77+ func doesNotImplementErr (interfaceName string , fs afero.Fs ) error {
78+ return errors .Wrapf (ErrDoesNotImplement , "Path's afero filesystem %s does not implement %s" , getFsName (fs ), interfaceName )
7579}
7680
7781// *******************************
@@ -184,6 +188,12 @@ func (p *Path) IsDir() (bool, error) {
184188 return afero .IsDir (p .Fs (), p .Path ())
185189}
186190
191+ // IsDir returns whether or not the os.FileInfo object represents a
192+ // directory.
193+ func IsDir (fileInfo os.FileInfo ) bool {
194+ return fileInfo .IsDir ()
195+ }
196+
187197// IsEmpty checks if a given file or directory is empty.
188198func (p * Path ) IsEmpty () (bool , error ) {
189199 return afero .IsEmpty (p .Fs (), p .Path ())
@@ -396,6 +406,20 @@ func (p *Path) RelativeTo(other *Path) (*Path, error) {
396406 return NewPathAfero (strings .Join (relativePath , "/" ), p .Fs ()), nil
397407}
398408
409+ // Lstat lstat's the path if the underlying afero filesystem supports it. If
410+ // the filesystem does not support afero.Lstater, an error will be returned.
411+ // A nil os.FileInfo is returned on errors. Also returned is a boolean describing
412+ // whether or not Lstat was called (in cases where the filesystem is an OS filesystem)
413+ // or not called (in cases where only Stat is supported). See
414+ // https://godoc.org/github.com/spf13/afero#Lstater for more info.
415+ func (p * Path ) Lstat () (os.FileInfo , bool , error ) {
416+ lStater , ok := p .Fs ().(afero.Lstater )
417+ if ! ok {
418+ return nil , false , p .doesNotImplementErr ("afero.Lstater" )
419+ }
420+ return lStater .LstatIfPossible (p .Path ())
421+ }
422+
399423// *********************************
400424// * filesystem-specific functions *
401425// *********************************
@@ -422,32 +446,36 @@ func (p *Path) String() string {
422446
423447// IsFile returns true if the given path is a file.
424448func (p * Path ) IsFile () (bool , error ) {
425- fileInfo , err := p .Fs (). Stat (p . Path () )
449+ fileInfo , err := p .Stat ()
426450 if err != nil {
427451 return false , err
428452 }
453+ return IsFile (fileInfo )
454+ }
455+
456+ // IsFile returns whether or not the file described by the given
457+ // os.FileInfo is a regular file.
458+ func IsFile (fileInfo os.FileInfo ) (bool , error ) {
429459 return fileInfo .Mode ().IsRegular (), nil
430460}
431461
432462// IsSymlink returns true if the given path is a symlink.
433463// Fails if the filesystem doesn't implement afero.Lstater.
434464func (p * Path ) IsSymlink () (bool , error ) {
435- lStater , ok := p .Fs ().(afero.Lstater )
436- if ! ok {
437- return false , p .doesNotImplementErr ("afero.Lstater" )
438- }
439- fileInfo , lstatCalled , err := lStater .LstatIfPossible (p .Path ())
440- if err != nil || ! lstatCalled {
441- // If lstat wasn't called then the filesystem doesn't implement it.
442- // Thus, it isn't a symlink
465+ fileInfo , _ , err := p .Lstat ()
466+ if err != nil {
443467 return false , err
444468 }
469+ return IsSymlink (fileInfo )
470+ }
445471
446- isSymlink := false
472+ // IsSymlink returns true if the file described by the given
473+ // os.FileInfo describes a symlink.
474+ func IsSymlink (fileInfo os.FileInfo ) (bool , error ) {
447475 if fileInfo .Mode ()& os .ModeSymlink != 0 {
448- isSymlink = true
476+ return true , nil
449477 }
450- return isSymlink , nil
478+ return false , nil
451479}
452480
453481// Path returns the string representation of the path
@@ -516,5 +544,26 @@ func (p *Path) Mtime() (time.Time, error) {
516544 if err != nil {
517545 return time.Time {}, err
518546 }
519- return stat .ModTime (), nil
547+ return Mtime (stat )
548+ }
549+
550+ // Mtime returns the mtime described in the given os.FileInfo object
551+ func Mtime (fileInfo os.FileInfo ) (time.Time , error ) {
552+ return fileInfo .ModTime (), nil
553+ }
554+
555+ // Size returns the size of the object. Fails if the object doesn't exist.
556+ func (p * Path ) Size () (int64 , error ) {
557+ stat , err := p .Stat ()
558+ if err != nil {
559+ return 0 , err
560+ }
561+ return Size (stat ), nil
562+ }
563+
564+ // Size returns the size described by the os.FileInfo. Before you say anything,
565+ // yes... you could just do fileInfo.Size(). This is purely a convenience function
566+ // to create API consistency.
567+ func Size (fileInfo os.FileInfo ) int64 {
568+ return fileInfo .Size ()
520569}
0 commit comments