mirror of https://github.com/spf13/afero.git
remove mem fs with descendants
This commit is contained in:
parent
ee6eef77ef
commit
ecbd067f5b
20
memmap.go
20
memmap.go
|
@ -285,10 +285,22 @@ func (m *MemMapFs) Remove(name string) error {
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
if _, ok := m.getData()[name]; ok {
|
if _, ok := m.getData()[name]; ok {
|
||||||
|
descendants := m.findDescendants(name)
|
||||||
|
for i := 1; i <= len(descendants); i++ {
|
||||||
|
descendant := descendants[len(descendants)-i]
|
||||||
|
descName := descendant.Name()
|
||||||
|
err := m.unRegisterWithParent(descName)
|
||||||
|
if err != nil {
|
||||||
|
return &os.PathError{Op: "descendant remove", Path: name, Err: err}
|
||||||
|
}
|
||||||
|
delete(m.getData(), descName)
|
||||||
|
}
|
||||||
|
|
||||||
err := m.unRegisterWithParent(name)
|
err := m.unRegisterWithParent(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &os.PathError{Op: "remove", Path: name, Err: err}
|
return &os.PathError{Op: "remove", Path: name, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(m.getData(), name)
|
delete(m.getData(), name)
|
||||||
} else {
|
} else {
|
||||||
return &os.PathError{Op: "remove", Path: name, Err: os.ErrNotExist}
|
return &os.PathError{Op: "remove", Path: name, Err: os.ErrNotExist}
|
||||||
|
@ -299,14 +311,18 @@ func (m *MemMapFs) Remove(name string) error {
|
||||||
func (m *MemMapFs) RemoveAll(path string) error {
|
func (m *MemMapFs) RemoveAll(path string) error {
|
||||||
path = normalizePath(path)
|
path = normalizePath(path)
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
m.unRegisterWithParent(path)
|
_ = m.unRegisterWithParent(path)
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
|
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
for p := range m.getData() {
|
for p := range m.getData() {
|
||||||
if p == path || strings.HasPrefix(p, path+FilePathSeparator) {
|
separator := FilePathSeparator
|
||||||
|
if path == FilePathSeparator {
|
||||||
|
separator = ""
|
||||||
|
}
|
||||||
|
if p == path || strings.HasPrefix(p, path+separator) {
|
||||||
m.mu.RUnlock()
|
m.mu.RUnlock()
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
delete(m.getData(), p)
|
delete(m.getData(), p)
|
||||||
|
|
|
@ -918,3 +918,70 @@ func TestMemMapFsRename(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMemMapFsRemove(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testData := map[string]struct {
|
||||||
|
dirsToCreate []string
|
||||||
|
dirsToRemove []string
|
||||||
|
expectedErrMsg string
|
||||||
|
}{
|
||||||
|
"Remove child before - success": {
|
||||||
|
dirsToCreate: []string{"/parent1/parent2/fileForDelete1.txt"},
|
||||||
|
dirsToRemove: []string{
|
||||||
|
"/parent1/parent2/fileForDelete1.txt",
|
||||||
|
"/parent1/parent2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Remove parent before - should return error": {
|
||||||
|
dirsToCreate: []string{"/parent1/parent2/fileForDelete1.txt"},
|
||||||
|
dirsToRemove: []string{
|
||||||
|
"/parent1/parent2",
|
||||||
|
"/parent1/parent2/fileForDelete1.txt",
|
||||||
|
},
|
||||||
|
expectedErrMsg: "remove /parent1/parent2/fileForDelete1.txt: file does not exist",
|
||||||
|
},
|
||||||
|
"Remove root and then parent1 - should return error": {
|
||||||
|
dirsToCreate: []string{"/root/parent1/parent2/fileForDelete1.txt"},
|
||||||
|
dirsToRemove: []string{
|
||||||
|
"/root",
|
||||||
|
"/root/parent1",
|
||||||
|
},
|
||||||
|
expectedErrMsg: "remove /root/parent1: file does not exist",
|
||||||
|
},
|
||||||
|
"Remove parent2 and then parent 1 - success": {
|
||||||
|
dirsToCreate: []string{"/parent1/parent2/fileForDelete1.txt"},
|
||||||
|
dirsToRemove: []string{
|
||||||
|
"/parent1/parent2",
|
||||||
|
"/parent1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fs := &MemMapFs{}
|
||||||
|
|
||||||
|
for caseName, td := range testData {
|
||||||
|
_, err := fs.Stat("/")
|
||||||
|
if err == nil {
|
||||||
|
err = fs.RemoveAll("/")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: RemoveAll %q failed: %v", fs.Name(), "/", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, toCreate := range td.dirsToCreate {
|
||||||
|
err = fs.MkdirAll(toCreate, os.FileMode(0775))
|
||||||
|
if err != nil && err.Error() != td.expectedErrMsg {
|
||||||
|
t.Fatalf("#CASE %v %s: Mkdir %q failed: %v", caseName, fs.Name(), toCreate, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, toRemove := range td.dirsToRemove {
|
||||||
|
err = fs.Remove(toRemove)
|
||||||
|
if err != nil && err.Error() != td.expectedErrMsg {
|
||||||
|
t.Fatalf("#CASE %v %s: Remove %q failed: %v", caseName, fs.Name(), toRemove, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue