Create helper function for a rmtree that works reliably on Windows.

pull/1809/merge
Jussi Pakkanen 8 years ago
parent 189784b474
commit effe4fb134
  1. 17
      mesonbuild/mesonlib.py
  2. 3
      mesonbuild/scripts/dist.py
  3. 23
      run_project_tests.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.

@ -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)

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

Loading…
Cancel
Save