@@ -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
9494func 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