11package pathlib
22
33import (
4+ "fmt"
45 "io"
56 "os"
67 "path/filepath"
78 "strings"
89 "time"
910
10- "github.com/pkg/errors"
1111 "github.com/spf13/afero"
1212)
1313
@@ -44,7 +44,7 @@ func NewPathAfero(path string, fs afero.Fs) *Path {
4444func Glob (fs afero.Fs , pattern string ) ([]* Path , error ) {
4545 matches , err := afero .Glob (fs , pattern )
4646 if err != nil {
47- return nil , errors . Wrapf ( err , "failed to glob" )
47+ return nil , fmt . Errorf ( "failed to glob: %w" , err )
4848 }
4949
5050 pathMatches := []* Path {}
@@ -75,7 +75,15 @@ func (p *Path) doesNotImplementErr(interfaceName string) error {
7575}
7676
7777func doesNotImplementErr (interfaceName string , fs afero.Fs ) error {
78- return errors .Wrapf (ErrDoesNotImplement , "Path's afero filesystem %s does not implement %s" , getFsName (fs ), interfaceName )
78+ return fmt .Errorf ("%w: Path's afero filesystem %s does not implement %s" , ErrDoesNotImplement , getFsName (fs ), interfaceName )
79+ }
80+
81+ func (p * Path ) lstatNotPossible () error {
82+ return lstatNotPossible (p .Fs ())
83+ }
84+
85+ func lstatNotPossible (fs afero.Fs ) error {
86+ return fmt .Errorf ("%w: Path's afero filesystem %s does not support lstat" , ErrLstatNotPossible , getFsName (fs ))
7987}
8088
8189// *******************************
@@ -387,7 +395,6 @@ func normalizePathParts(path []string) []string {
387395// if the object is /path/to/foo.txt and you provide /path/ as the argment, the
388396// returned Path object will represent to/foo.txt.
389397func (p * Path ) RelativeTo (other * Path ) (* Path , error ) {
390-
391398 thisPathNormalized := normalizePathString (p .Path ())
392399 otherPathNormalized := normalizePathString (other .Path ())
393400
@@ -398,7 +405,7 @@ func (p *Path) RelativeTo(other *Path) (*Path, error) {
398405 var relativeBase int
399406 for idx , part := range otherParts {
400407 if thisParts [idx ] != part {
401- return p , errors .Errorf ("%s does not start with %s" , thisPathNormalized , otherPathNormalized )
408+ return p , fmt .Errorf ("%s does not start with %s" , thisPathNormalized , otherPathNormalized )
402409 }
403410 relativeBase = idx
404411 }
@@ -413,17 +420,20 @@ func (p *Path) RelativeTo(other *Path) (*Path, error) {
413420}
414421
415422// Lstat lstat's the path if the underlying afero filesystem supports it. If
416- // the filesystem does not support afero.Lstater, an error will be returned.
417- // A nil os.FileInfo is returned on errors. Also returned is a boolean describing
418- // whether or not Lstat was called (in cases where the filesystem is an OS filesystem)
419- // or not called (in cases where only Stat is supported). See
420- // https://godoc.org/github.com/spf13/afero#Lstater for more info.
421- func (p * Path ) Lstat () (os.FileInfo , bool , error ) {
423+ // the filesystem does not support afero.Lstater, or if the filesystem implements
424+ // afero.Lstater but returns false for the "lstat called" return value
425+ //
426+ // A nil os.FileInfo is returned on errors.
427+ func (p * Path ) Lstat () (os.FileInfo , error ) {
422428 lStater , ok := p .Fs ().(afero.Lstater )
423429 if ! ok {
424- return nil , false , p .doesNotImplementErr ("afero.Lstater" )
430+ return nil , p .doesNotImplementErr ("afero.Lstater" )
431+ }
432+ stat , lstatCalled , err := lStater .LstatIfPossible (p .Path ())
433+ if ! lstatCalled && err == nil {
434+ return nil , p .lstatNotPossible ()
425435 }
426- return lStater . LstatIfPossible ( p . Path ())
436+ return stat , err
427437}
428438
429439// *********************************
@@ -468,7 +478,7 @@ func IsFile(fileInfo os.FileInfo) bool {
468478// IsSymlink returns true if the given path is a symlink.
469479// Fails if the filesystem doesn't implement afero.Lstater.
470480func (p * Path ) IsSymlink () (bool , error ) {
471- fileInfo , _ , err := p .Lstat ()
481+ fileInfo , err := p .Lstat ()
472482 if err != nil {
473483 return false , err
474484 }
0 commit comments