forked from mirror/afero
adding support for Linker and LinkReader
This commit is contained in:
parent
819f7ad35d
commit
b4b149f834
26
basepath.go
26
basepath.go
|
@ -177,4 +177,30 @@ func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
|
||||||
return fi, false, err
|
return fi, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BasePathFs) SymlinkIfPossible(oldname, newname string) error {
|
||||||
|
oldname, err := b.RealPath(oldname)
|
||||||
|
if err != nil {
|
||||||
|
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: err}
|
||||||
|
}
|
||||||
|
newname, err = b.RealPath(newname)
|
||||||
|
if err != nil {
|
||||||
|
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: err}
|
||||||
|
}
|
||||||
|
if linker, ok := b.source.(Linker); ok {
|
||||||
|
return linker.SymlinkIfPossible(oldname, newname)
|
||||||
|
}
|
||||||
|
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: ErrNoSymlink}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BasePathFs) ReadlinkIfPossible(name string) (string, error) {
|
||||||
|
name, err := b.RealPath(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", &os.PathError{Op: "readlink", Path: name, Err: err}
|
||||||
|
}
|
||||||
|
if reader, ok := b.source.(LinkReader); ok {
|
||||||
|
return reader.ReadlinkIfPossible(name)
|
||||||
|
}
|
||||||
|
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
|
||||||
|
}
|
||||||
|
|
||||||
// vim: ts=4 sw=4 noexpandtab nolist syn=go
|
// vim: ts=4 sw=4 noexpandtab nolist syn=go
|
||||||
|
|
|
@ -117,6 +117,26 @@ func (u *CopyOnWriteFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
|
||||||
return fi, false, err
|
return fi, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *CopyOnWriteFs) SymlinkIfPossible(oldname, newname string) error {
|
||||||
|
if slayer, ok := u.layer.(Linker); ok {
|
||||||
|
return slayer.SymlinkIfPossible(oldname, newname)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: ErrNoSymlink}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *CopyOnWriteFs) ReadlinkIfPossible(name string) (string, error) {
|
||||||
|
if rlayer, ok := u.layer.(LinkReader); ok {
|
||||||
|
return rlayer.ReadlinkIfPossible(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rbase, ok := u.base.(LinkReader); ok {
|
||||||
|
return rbase.ReadlinkIfPossible(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
|
||||||
|
}
|
||||||
|
|
||||||
func (u *CopyOnWriteFs) isNotExist(err error) bool {
|
func (u *CopyOnWriteFs) isNotExist(err error) bool {
|
||||||
if e, ok := err.(*os.PathError); ok {
|
if e, ok := err.(*os.PathError); ok {
|
||||||
err = e.Err
|
err = e.Err
|
||||||
|
|
8
os.go
8
os.go
|
@ -99,3 +99,11 @@ func (OsFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
|
||||||
fi, err := os.Lstat(name)
|
fi, err := os.Lstat(name)
|
||||||
return fi, true, err
|
return fi, true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (OsFs) SymlinkIfPossible(oldname, newname string) error {
|
||||||
|
return os.Symlink(oldname, newname)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (OsFs) ReadlinkIfPossible(name string) (string, error) {
|
||||||
|
return os.Readlink(name)
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,18 @@ func (r *ReadOnlyFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
|
||||||
return fi, false, err
|
return fi, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ReadOnlyFs) SymlinkIfPossible(oldname, newname string) error {
|
||||||
|
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: ErrNoSymlink}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReadOnlyFs) ReadlinkIfPossible(name string) (string, error) {
|
||||||
|
if srdr, ok := r.source.(LinkReader); ok {
|
||||||
|
return srdr.ReadlinkIfPossible(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ReadOnlyFs) Rename(o, n string) error {
|
func (r *ReadOnlyFs) Rename(o, n string) error {
|
||||||
return syscall.EPERM
|
return syscall.EPERM
|
||||||
}
|
}
|
||||||
|
|
14
symlink.go
14
symlink.go
|
@ -13,6 +13,10 @@
|
||||||
|
|
||||||
package afero
|
package afero
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
// Symlinker is an optional interface in Afero. It is only implemented by the
|
// Symlinker is an optional interface in Afero. It is only implemented by the
|
||||||
// filesystems saying so.
|
// filesystems saying so.
|
||||||
// It indicates support for 3 symlink related interfaces that implement the
|
// It indicates support for 3 symlink related interfaces that implement the
|
||||||
|
@ -34,8 +38,18 @@ type Linker interface {
|
||||||
SymlinkIfPossible(oldname, newname string) error
|
SymlinkIfPossible(oldname, newname string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrNoSymlink is the error that will be wrapped in an os.LinkError if a file system
|
||||||
|
// does not support Symlink's either directly or through its delegated filesystem.
|
||||||
|
// As expressed by support for the Linker interface.
|
||||||
|
var ErrNoSymlink = errors.New("symlink not supported")
|
||||||
|
|
||||||
// LinkReader is an optional interface in Afero. It is only implemented by the
|
// LinkReader is an optional interface in Afero. It is only implemented by the
|
||||||
// filesystems saying so.
|
// filesystems saying so.
|
||||||
type LinkReader interface {
|
type LinkReader interface {
|
||||||
ReadlinkIfPossible(name string) (string, error)
|
ReadlinkIfPossible(name string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrNoReadlink is the error that will be wrapped in an os.Path if a file system
|
||||||
|
// does not support the readlink operation either directly or through its delegated filesystem.
|
||||||
|
// As expressed by support for the LinkReader interface.
|
||||||
|
var ErrNoReadlink = errors.New("readlink not supported")
|
||||||
|
|
Loading…
Reference in New Issue