@@ -92,14 +92,23 @@ func WriteFileAtomic(filename string, produce func(io.Writer) error, options ...
92
92
// - ensures a file with given name only appears on the filesystem if all its file operations succeed
93
93
// - tries to clean up temp file on failure of *operations* or the atomic rename
94
94
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 {
95
104
pathTemp := path + ".part"
96
105
97
106
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 ) {
99
108
// IsNotExist is acceptable from remove, the *operations* didn't manage to start creating
100
109
// the temp file (or was not authorized so)
101
110
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 )
103
112
} else {
104
113
return err
105
114
}
0 commit comments