diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-05-18 18:55:33 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2017-05-21 21:47:24 +0300 |
commit | effe4fb13416279eecad52504e5ce1e0b4c7e5e3 (patch) | |
tree | e1c9d7469ee295e63919743ae1fef03e1014bcd4 | |
parent | 189784b47404a7ab8b9443e4604721df2941a042 (diff) | |
download | meson-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.py | 17 | ||||
-rw-r--r-- | mesonbuild/scripts/dist.py | 3 | ||||
-rwxr-xr-x | run_project_tests.py | 23 |
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 |