aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-05-18 18:55:33 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2017-05-21 21:47:24 +0300
commiteffe4fb13416279eecad52504e5ce1e0b4c7e5e3 (patch)
treee1c9d7469ee295e63919743ae1fef03e1014bcd4
parent189784b47404a7ab8b9443e4604721df2941a042 (diff)
downloadmeson-effe4fb13416279eecad52504e5ce1e0b4c7e5e3.zip
meson-effe4fb13416279eecad52504e5ce1e0b4c7e5e3.tar.gz
meson-effe4fb13416279eecad52504e5ce1e0b4c7e5e3.tar.bz2
Create helper function for a rmtree that works reliably on Windows.
-rw-r--r--mesonbuild/mesonlib.py17
-rw-r--r--mesonbuild/scripts/dist.py3
-rwxr-xr-xrun_project_tests.py23
3 files changed, 24 insertions, 19 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 6937502..415bc50 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -15,6 +15,7 @@
"""A library of random helper functionality."""
import stat
+import time
import platform, subprocess, operator, os, shutil, re
import collections
@@ -687,6 +688,22 @@ def get_filenames_templates_dict(inputs, outputs):
values['@OUTDIR@'] = '.'
return values
+
+def windows_proof_rmtree(f):
+ # On Windows if anyone is holding a file open you can't
+ # delete it. As an example an anti virus scanner might
+ # be scanning files you are trying to delete. The only
+ # way to fix this is to try again and again.
+ delays = [0.1, 0.1, 0.2, 0.2, 0.2, 0.5, 0.5, 1, 1, 1, 1, 2]
+ for d in delays:
+ try:
+ shutil.rmtree(f)
+ return
+ except (OSError, PermissionError):
+ time.sleep(d)
+ # Try one last time and throw if it fails.
+ shutil.rmtree(f)
+
class OrderedSet(collections.MutableSet):
"""A set that preserves the order in which items are added, by first
insertion.
diff --git a/mesonbuild/scripts/dist.py b/mesonbuild/scripts/dist.py
index f17b296..064708e 100644
--- a/mesonbuild/scripts/dist.py
+++ b/mesonbuild/scripts/dist.py
@@ -22,6 +22,7 @@ import tarfile, zipfile
import tempfile
from glob import glob
from mesonbuild.environment import detect_ninja
+from mesonbuild.mesonlib import windows_proof_rmtree
def create_hash(fname):
hashname = fname + '.sha256sum'
@@ -49,7 +50,7 @@ def create_zip(zipfilename, packaging_dir):
def del_gitfiles(dirname):
for f in glob(os.path.join(dirname, '.git*')):
if os.path.isdir(f) and not os.path.islink(f):
- shutil.rmtree(f)
+ windows_proof_rmtree(f)
else:
os.unlink(f)
diff --git a/run_project_tests.py b/run_project_tests.py
index 7f7cfdc..822286b 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -114,24 +114,11 @@ class AutoDeletedDir:
return self.dir
def __exit__(self, _type, value, traceback):
- # On Windows, shutil.rmtree fails sometimes, because 'the directory is not empty'.
- # Retrying fixes this.
- # That's why we don't use tempfile.TemporaryDirectory, but wrap the deletion in the AutoDeletedDir class.
- retries = 5
- for i in range(0, retries):
- try:
- shutil.rmtree(self.dir)
- return
- # Sometimes we get: ValueError: I/O operation on closed file.
- except ValueError:
- return
- # Deleting can raise OSError or PermissionError on Windows
- # (most likely because of anti-virus locking the file)
- except (OSError, PermissionError):
- if i == retries - 1:
- mlog.warning('Could not delete temporary directory.')
- return
- time.sleep(0.1 * (2**i))
+ # We don't use tempfile.TemporaryDirectory, but wrap the
+ # deletion in the AutoDeletedDir class because
+ # it fails on Windows due antivirus programs
+ # holding files open.
+ mesonlib.windows_proof_rmtree(self.dir)
failing_logs = []
print_debug = 'MESON_PRINT_TEST_OUTPUT' in os.environ