Use rd on Windows in rmdir

This is needed because the current implementation commonly fails on Windows due to "directory not empty" errors.  Using rd is more reliable.

Review URL: https://chromiumcodereview.appspot.com/13581005

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@194932 0039d316-1c4b-4281-b951-d872f2087c98
experimental/szager/collated-output
borenet@google.com 12 years ago
parent 104b2db2a0
commit 6b4a2ab6ad

@ -5,12 +5,12 @@
"""Generic utils.""" """Generic utils."""
import codecs import codecs
import errno
import logging import logging
import os import os
import Queue import Queue
import re import re
import stat import stat
import subprocess
import sys import sys
import tempfile import tempfile
import threading import threading
@ -125,33 +125,23 @@ def rmtree(path):
raise Error('Called rmtree(%s) in non-directory' % path) raise Error('Called rmtree(%s) in non-directory' % path)
if sys.platform == 'win32': if sys.platform == 'win32':
# Some people don't have the APIs installed. In that case we'll do without. # Give up and use cmd.exe's rd command.
win32api = None path = os.path.normcase(path)
win32con = None for _ in xrange(3):
try: exitcode = subprocess.call(['cmd.exe', '/c', 'rd', '/q', '/s', path])
# Unable to import 'XX' if exitcode == 0:
# pylint: disable=F0401 return
import win32api, win32con
except ImportError:
pass
else: else:
print >> sys.stderr, 'rd exited with code %d' % exitcode
time.sleep(3)
raise Exception('Failed to remove path %s' % path)
# On POSIX systems, we need the x-bit set on the directory to access it, # On POSIX systems, we need the x-bit set on the directory to access it,
# the r-bit to see its contents, and the w-bit to remove files from it. # the r-bit to see its contents, and the w-bit to remove files from it.
# The actual modes of the files within the directory is irrelevant. # The actual modes of the files within the directory is irrelevant.
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
def remove(func, subpath): def remove(func, subpath):
if sys.platform == 'win32':
os.chmod(subpath, stat.S_IWRITE)
if win32api and win32con:
win32api.SetFileAttributes(subpath, win32con.FILE_ATTRIBUTE_NORMAL)
try:
func(subpath)
except OSError, e:
if e.errno != errno.EACCES or sys.platform != 'win32':
raise
# Failed to delete, try again after a 100ms sleep.
time.sleep(0.1)
func(subpath) func(subpath)
for fn in os.listdir(path): for fn in os.listdir(path):

@ -35,11 +35,10 @@ class GclientUtilsUnittest(GclientUtilBase):
'MakeDateRevision', 'MakeFileAutoFlush', 'MakeFileAnnotated', 'MakeDateRevision', 'MakeFileAutoFlush', 'MakeFileAnnotated',
'PathDifference', 'ParseCodereviewSettingsContent', 'NumLocalCpus', 'PathDifference', 'ParseCodereviewSettingsContent', 'NumLocalCpus',
'PrintableObject', 'RemoveDirectory', 'RunEditor', 'PrintableObject', 'RemoveDirectory', 'RunEditor',
'SplitUrlRevision', 'SyntaxErrorToError', 'SplitUrlRevision', 'SyntaxErrorToError', 'UpgradeToHttps', 'Wrapper',
'UpgradeToHttps', 'Wrapper', 'WorkItem', 'WorkItem', 'codecs', 'lockedmethod', 'logging', 'os', 'Queue', 're',
'codecs', 'errno', 'lockedmethod', 'logging', 'os', 'Queue', 're', 'rmtree', 'safe_makedirs', 'stat', 'subprocess', 'subprocess2', 'sys',
'rmtree', 'safe_makedirs', 'stat', 'subprocess2', 'sys', 'tempfile', 'tempfile', 'threading', 'time', 'urlparse',
'threading', 'time', 'urlparse',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
self.compareMembers(gclient_utils, members) self.compareMembers(gclient_utils, members)

Loading…
Cancel
Save