Commit f531cd71 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki Committed by Xavier Thompson

[fix] Make buildout.rmtree working with symlink as a path argument

https://bugs.launchpad.net/zc.buildout/+bug/144228
parent 747ac833
......@@ -16,7 +16,6 @@
import shutil
import os
import doctest
import time
def rmtree (path):
"""
......@@ -26,6 +25,8 @@ def rmtree (path):
process (e.g. antivirus scanner). This tries to chmod the
file to writeable and retries 10 times before giving up.
Also it tries to remove symlink itself if a symlink as passed as
path argument.
>>> from tempfile import mkdtemp
Let's make a directory ...
......@@ -41,6 +42,8 @@ def rmtree (path):
>>> foo = os.path.join (d, 'foo')
>>> with open (foo, 'w') as f: _ = f.write ('huhu')
>>> bar = os.path.join (d, 'bar')
>>> os.symlink(bar, bar)
and make it unwriteable
......@@ -52,21 +55,51 @@ def rmtree (path):
and now the directory is gone
>>> os.path.isdir (d)
0
Let's make a directory ...
>>> d = mkdtemp()
and make sure it is actually there
>>> os.path.isdir (d)
1
Now create a broken symlink ...
>>> foo = os.path.join (d, 'foo')
>>> os.symlink(foo + '.not_exist', foo)
rmtree should be able to remove it:
>>> rmtree (foo)
and now the directory is gone
>>> os.path.isdir (foo)
0
cleanup directory
>>> rmtree (d)
and now the directory is gone
>>> os.path.isdir (d)
0
"""
def retry_writeable (func, path, exc):
os.chmod (path, 384) # 0600
for i in range(10):
try:
func (path)
break
except OSError:
time.sleep(0.1)
else:
# tried 10 times without success, thus
# finally rethrow the last exception
if func is os.path.islink:
os.unlink(path)
elif func is os.lstat or func is os.open:
if not os.path.islink(path):
raise
os.unlink(path)
else:
os.chmod(path, 0o600)
func(path)
shutil.rmtree (path, onerror = retry_writeable)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment