Skip to content

Commit 0acfdd5

Browse files
committed
osutil: add DirectoryAtomicOperationByRename()
1 parent 12a0300 commit 0acfdd5

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

os/osutil/writefileatomic.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,23 @@ func WriteFileAtomic(filename string, produce func(io.Writer) error, options ...
9292
// - ensures a file with given name only appears on the filesystem if all its file operations succeed
9393
// - tries to clean up temp file on failure of *operations* or the atomic rename
9494
func FileAtomicOperationByRename(path string, operations func(pathTemp string) error) error {
95+
return atomicOperationByRename(path, operations, os.Remove)
96+
}
97+
98+
func DirectoryAtomicOperationByRename(path string, operations func(pathTemp string) error) error {
99+
return atomicOperationByRename(path, operations, os.RemoveAll)
100+
}
101+
102+
// `removeFileOrDirectory` gets either `os.Remove` or `os.RemoveAll` as argument
103+
func atomicOperationByRename(path string, operations func(pathTemp string) error, removeFileOrDirectory func(string) error) error {
95104
pathTemp := path + ".part"
96105

97106
retErrorWithCleanup := func(err error) error { // err is non-nil here
98-
if errCleanup := os.Remove(pathTemp); errCleanup != nil && !os.IsNotExist(errCleanup) {
107+
if errCleanup := removeFileOrDirectory(pathTemp); errCleanup != nil && !os.IsNotExist(errCleanup) {
99108
// IsNotExist is acceptable from remove, the *operations* didn't manage to start creating
100109
// the temp file (or was not authorized so)
101110

102-
return fmt.Errorf("%w; additionally FileAtomicOperationByRename failed cleaning up: %v", err, errCleanup)
111+
return fmt.Errorf("%w; additionally atomicOperationByRename failed cleaning up: %v", err, errCleanup)
103112
} else {
104113
return err
105114
}

0 commit comments

Comments
 (0)