diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fs.go | 3 | ||||
-rw-r--r-- | fs/memory.go | 51 | ||||
-rw-r--r-- | fs/os.go | 26 |
3 files changed, 65 insertions, 15 deletions
@@ -29,10 +29,13 @@ type RegularFile interface { type Dir interface { File Readdir() ([]File, error) + GetChild(name string) (File, error) // Must return os.ErrNotExist, if child doesn't exist CreateChildFile(name string, exec bool) (RegularFile, error) CreateChildDir(name string) (Dir, error) CreateChildSymlink(name string, target string) (Symlink, error) + + RenameChild(oldname, newname string) error } type Symlink interface { diff --git a/fs/memory.go b/fs/memory.go index 5f5d327..221ff36 100644 --- a/fs/memory.go +++ b/fs/memory.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "io" + "os" "time" ) @@ -14,7 +15,13 @@ type memfsBase struct { mtime time.Time } +type memfsChild interface { + File + setName(string) +} + func (b memfsBase) Name() string { return b.name } +func (b *memfsBase) setName(n string) { b.name = n } func (b memfsBase) Executable() bool { return b.exec } func (b memfsBase) ModTime() time.Time { return b.mtime } @@ -45,13 +52,13 @@ func (f memfsFile) Write(p []byte) (int, error) { return f.content.Write(p) } -func (memfsBase) Close() error { +func (memfsFile) Close() error { return nil } type memfsDir struct { memfsBase - children map[string]File + children map[string]memfsChild } func (memfsDir) Type() FileType { return FDir } @@ -66,6 +73,14 @@ func (d memfsDir) Readdir() ([]File, error) { return l, nil } +func (d memfsDir) GetChild(name string) (File, error) { + c, ok := d.children[name] + if !ok { + return nil, os.ErrNotExist + } + return c, nil +} + func (d memfsDir) createChildBase(name string, exec bool) memfsBase { return memfsBase{ parent: &d, @@ -80,17 +95,17 @@ func (d memfsDir) CreateChildFile(name string, exec bool) (RegularFile, error) { memfsBase: d.createChildBase(name, exec), content: new(bytes.Buffer), } - d.children[name] = child - return child, nil + d.children[name] = &child + return &child, nil } func (d memfsDir) CreateChildDir(name string) (Dir, error) { child := memfsDir{ memfsBase: d.createChildBase(name, true), - children: make(map[string]File), + children: make(map[string]memfsChild), } - d.children[name] = child - return child, nil + d.children[name] = &child + return &child, nil } func (d memfsDir) CreateChildSymlink(name string, target string) (Symlink, error) { @@ -98,23 +113,37 @@ func (d memfsDir) CreateChildSymlink(name string, target string) (Symlink, error memfsBase: d.createChildBase(name, false), target: target, } - d.children[name] = child - return child, nil + d.children[name] = &child + return &child, nil } func (d *memfsDir) deleteChild(name string) { delete(d.children, name) } +func (d *memfsDir) RenameChild(oldname, newname string) error { + c, ok := d.children[oldname] + if !ok { + return os.ErrNotExist + } + + c.setName(newname) + + delete(d.children, oldname) + d.children[newname] = c + + return nil +} + func NewMemoryFSRoot(name string) Dir { - return memfsDir{ + return &memfsDir{ memfsBase: memfsBase{ parent: nil, name: name, exec: true, mtime: time.Now(), }, - children: make(map[string]File), + children: make(map[string]memfsChild), } } @@ -3,9 +3,14 @@ package fs import ( "io" "os" + "strings" "time" ) +func pathJoin(parts ...string) string { + return strings.Join(parts, string(os.PathSeparator)) +} + func openOSFile(path string) (osFile, error) { fi, err := os.Lstat(path) if err != nil { @@ -79,7 +84,7 @@ func (f osFile) Readdir() (list []File, err error) { } list = append(list, osFile{ - fullpath: f.fullpath + string(os.PathSeparator) + fi.Name(), + fullpath: pathJoin(f.fullpath, fi.Name()), fi: fi, }) } @@ -87,6 +92,15 @@ func (f osFile) Readdir() (list []File, err error) { return } +func (f osFile) GetChild(name string) (File, error) { + path := pathJoin(f.fullpath, name) + fi, err := os.Lstat(path) + if err != nil { + return nil, err + } + return osFile{path, fi}, nil +} + func perms(executable bool) os.FileMode { if executable { return 0755 @@ -96,7 +110,7 @@ func perms(executable bool) os.FileMode { } func (f osFile) CreateChildFile(name string, exec bool) (RegularFile, error) { - p := f.fullpath + string(os.PathSeparator) + name + p := pathJoin(f.fullpath, name) fh, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE, perms(exec)) if err != nil { @@ -108,7 +122,7 @@ func (f osFile) CreateChildFile(name string, exec bool) (RegularFile, error) { } func (f osFile) CreateChildDir(name string) (Dir, error) { - p := f.fullpath + string(os.PathSeparator) + name + p := pathJoin(f.fullpath, name) if err := os.Mkdir(p, perms(true)); err != nil { return nil, err @@ -118,7 +132,7 @@ func (f osFile) CreateChildDir(name string) (Dir, error) { } func (f osFile) CreateChildSymlink(name string, target string) (Symlink, error) { - p := f.fullpath + string(os.PathSeparator) + name + p := pathJoin(f.fullpath, name) err := os.Symlink(target, p) if err != nil { @@ -128,6 +142,10 @@ func (f osFile) CreateChildSymlink(name string, target string) (Symlink, error) return openOSFile(p) } +func (f osFile) RenameChild(oldname, newname string) error { + return os.Rename(pathJoin(f.fullpath, oldname), pathJoin(f.fullpath, newname)) +} + func (f osFile) Readlink() (string, error) { return os.Readlink(f.fullpath) } |