57 lines
1.5 KiB
Diff
57 lines
1.5 KiB
Diff
--- 9.0.3 2024-12-12 08:06:13.000000000 +0100
|
|
+++ aneksajo 2024-12-16 08:23:15.000000000 +0100
|
|
@@ -4,7 +4,9 @@
|
|
package util
|
|
|
|
import (
|
|
+ "io/fs"
|
|
"os"
|
|
+ "path/filepath"
|
|
"runtime"
|
|
"syscall"
|
|
"time"
|
|
@@ -41,10 +43,43 @@
|
|
return err
|
|
}
|
|
|
|
-// RemoveAll removes the named file or (empty) directory with at most 5 attempts.
|
|
+// RemoveAll removes the named file or directory with at most 5 attempts.
|
|
func RemoveAll(name string) error {
|
|
var err error
|
|
+
|
|
for i := 0; i < 5; i++ {
|
|
+ // Do chmod -R +w to help ensure the removal succeeds.
|
|
+ // In particular, in the git-annex case, this handles
|
|
+ // https://git-annex.branchable.com/internals/lockdown/ :
|
|
+ //
|
|
+ // > (The only bad consequence of this is that rm -rf .git
|
|
+ // > doesn't work unless you first run chmod -R +w .git)
|
|
+
|
|
+ err = filepath.WalkDir(name, func(path string, d fs.DirEntry, err error) error {
|
|
+ // NB: this is called WalkDir but it works on a single file too
|
|
+ if err == nil {
|
|
+ info, err := d.Info()
|
|
+ if err != nil {
|
|
+ return err
|
|
+ }
|
|
+
|
|
+ // Don't try chmod'ing symlinks (will fail with broken symlinks)
|
|
+ if info.Mode()&os.ModeSymlink != os.ModeSymlink {
|
|
+ // 0200 == u+w, in octal unix permission notation
|
|
+ err = os.Chmod(path, info.Mode()|0o200)
|
|
+ if err != nil {
|
|
+ return err
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return nil
|
|
+ })
|
|
+ if err != nil {
|
|
+ // try again
|
|
+ <-time.After(100 * time.Millisecond)
|
|
+ continue
|
|
+ }
|
|
+
|
|
err = os.RemoveAll(name)
|
|
if err == nil {
|
|
break
|