mirror of https://github.com/spf13/afero.git
Fix BasePathFs symlink
1. Support related path 2. Make ReadlinkIfPossible return path under basepath Fixes #282
This commit is contained in:
parent
32b5faae5b
commit
e597de429b
18
basepath.go
18
basepath.go
|
@ -185,9 +185,12 @@ func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BasePathFs) SymlinkIfPossible(oldname, newname string) error {
|
func (b *BasePathFs) SymlinkIfPossible(oldname, newname string) error {
|
||||||
oldname, err := b.RealPath(oldname)
|
var err error
|
||||||
if err != nil {
|
if filepath.IsAbs(oldname) {
|
||||||
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: err}
|
oldname, err = b.RealPath(oldname)
|
||||||
|
if err != nil {
|
||||||
|
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: err}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
newname, err = b.RealPath(newname)
|
newname, err = b.RealPath(newname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -205,7 +208,14 @@ func (b *BasePathFs) ReadlinkIfPossible(name string) (string, error) {
|
||||||
return "", &os.PathError{Op: "readlink", Path: name, Err: err}
|
return "", &os.PathError{Op: "readlink", Path: name, Err: err}
|
||||||
}
|
}
|
||||||
if reader, ok := b.source.(LinkReader); ok {
|
if reader, ok := b.source.(LinkReader); ok {
|
||||||
return reader.ReadlinkIfPossible(name)
|
linkpath, err := reader.ReadlinkIfPossible(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if filepath.IsAbs(linkpath) {
|
||||||
|
linkpath = strings.TrimPrefix(filepath.Clean(linkpath), filepath.Clean(b.path))
|
||||||
|
}
|
||||||
|
return linkpath, nil
|
||||||
}
|
}
|
||||||
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
|
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,3 +188,44 @@ func TestBasePathTempFile(t *testing.T) {
|
||||||
t.Fatalf("TempFile realpath leaked: expected %s, got %s", expected, actual)
|
t.Fatalf("TempFile realpath leaked: expected %s, got %s", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBasePathSymlink(t *testing.T) {
|
||||||
|
type SymlinkTest struct {
|
||||||
|
Testcase, Link, Target string
|
||||||
|
}
|
||||||
|
symlinkTests := []SymlinkTest{
|
||||||
|
{Testcase: "Absolute path", Link: "/foo/baz/abs_link", Target: "/foo/file"},
|
||||||
|
{Testcase: "Relative path", Link: "/foo/baz/ref_link", Target: "../file"},
|
||||||
|
}
|
||||||
|
|
||||||
|
fs := NewOsFs()
|
||||||
|
baseDir, err := TempDir(fs, "", "base")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("error creating tempDir", err)
|
||||||
|
}
|
||||||
|
defer fs.RemoveAll(baseDir)
|
||||||
|
|
||||||
|
var bp Fs = NewBasePathFs(fs, baseDir).(*BasePathFs)
|
||||||
|
bp.MkdirAll("/foo/baz", 0777)
|
||||||
|
bp.Create("/foo/file")
|
||||||
|
linker, _ := bp.(Linker)
|
||||||
|
lreader, _ := bp.(LinkReader)
|
||||||
|
|
||||||
|
for _, test := range symlinkTests {
|
||||||
|
err = linker.SymlinkIfPossible(test.Target, test.Link)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: error creating symlink %s", test.Testcase, err.Error())
|
||||||
|
}
|
||||||
|
linkpath, err := lreader.ReadlinkIfPossible(test.Link)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: error read symlink %s", test.Testcase, err.Error())
|
||||||
|
}
|
||||||
|
if linkpath != test.Target {
|
||||||
|
t.Errorf("%s: link not match %s != %s", test.Testcase, linkpath, test.Target)
|
||||||
|
}
|
||||||
|
_, err = bp.Stat(test.Link)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: error stat symlink %s", test.Testcase, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue