Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(678)

Side by Side Diff: scripts/common/chromium_utils.py

Issue 6015012: Use shutil.rmtree's 'onerror' error handling parameter to catch and handle th... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """ Set of basic operations/utilities that are used by the build. """ 5 """ Set of basic operations/utilities that are used by the build. """
6 6
7 import copy 7 import copy
8 import errno 8 import errno
9 import fnmatch 9 import fnmatch
10 import glob 10 import glob
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 try: 259 try:
260 win32api = __import__('win32api') 260 win32api = __import__('win32api')
261 win32con = __import__('win32con') 261 win32con = __import__('win32con')
262 win32_api_avail = True 262 win32_api_avail = True
263 except ImportError: 263 except ImportError:
264 pass 264 pass
265 remove_with_retry = RemoveWithRetry_win 265 remove_with_retry = RemoveWithRetry_win
266 else: 266 else:
267 remove_with_retry = RemoveWithRetry_non_win 267 remove_with_retry = RemoveWithRetry_non_win
268 268
269 def RmTreeOnError(function, path, excinfo):
270 """This works around a problem whereby python 2.x on Windows has no ability
271 to check for symbolic links. os.path.islink always returns False. But
272 shutil.rmtree will fail if invoked on a symbolic link whose target was
273 deleted before the link. E.g., reproduce like this:
274 > mkdir test
275 > mkdir test\1
276 > mklink /D test\current test\1
277 > python -c "import chromium_utils; chromium_utils.RemoveDirectory('test')"
278 To avoid this issue, we pass this error-handling function to rmtree. If
279 we see the exact sort of failure, we ignore it. All other failures we re-
280 raise.
281 """
282
283 exception_type = excinfo[0]
284 exception_value = excinfo[1]
285 # If shutil.rmtree encounters a symbolic link on Windows, os.listdir will
286 # fail with a WindowsError exception with an ENOENT errno (i.e., file not
287 # found). We'll ignore that error. Note that WindowsError is not defined
288 # for non-Windows platforms, so we use OSError (of which it is a subclass)
289 # to avoid lint complaints about an undefined global on non-Windows
290 # platforms.
291 if (function is os.listdir) and issubclass(exception_type, OSError):
292 if exception_value.errno == errno.ENOENT:
293 # File does not exist, and we're trying to delete, so we can ignore the
294 # failure.
295 print "WARNING: Failed to list %s during rmtree. Ignoring.\n" % path
296 else:
297 raise
298 else:
299 raise
300
269 for root, dirs, files in os.walk(file_path, topdown=False): 301 for root, dirs, files in os.walk(file_path, topdown=False):
270 # For POSIX: making the directory writable guarantees removability. 302 # For POSIX: making the directory writable guarantees removability.
271 # Windows will ignore the non-read-only bits in the chmod value. 303 # Windows will ignore the non-read-only bits in the chmod value.
272 os.chmod(root, 0770) 304 os.chmod(root, 0770)
273 for name in files: 305 for name in files:
274 remove_with_retry(os.remove, os.path.join(root, name)) 306 remove_with_retry(os.remove, os.path.join(root, name))
275 for name in dirs: 307 for name in dirs:
276 remove_with_retry(shutil.rmtree, os.path.join(root, name)) 308 remove_with_retry(lambda p: shutil.rmtree(p, onerror=RmTreeOnError),
309 os.path.join(root, name))
277 310
278 remove_with_retry(os.rmdir, file_path) 311 remove_with_retry(os.rmdir, file_path)
279 312
280 313
281 def CopyFileToDir(src_path, dest_dir): 314 def CopyFileToDir(src_path, dest_dir):
282 """Copies the file found at src_path to the same filename within the 315 """Copies the file found at src_path to the same filename within the
283 dest_dir directory. 316 dest_dir directory.
284 317
285 Raises PathNotFound if either the file or the directory is not found. 318 Raises PathNotFound if either the file or the directory is not found.
286 """ 319 """
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 749
717 def ListMasters(): 750 def ListMasters():
718 """Returns all the masters found.""" 751 """Returns all the masters found."""
719 # Look for "internal" masters first. 752 # Look for "internal" masters first.
720 path_internal = os.path.join(os.path.dirname(__file__), '..', '..', '..', 753 path_internal = os.path.join(os.path.dirname(__file__), '..', '..', '..',
721 'build_internal', 'masters/*/master.cfg') 754 'build_internal', 'masters/*/master.cfg')
722 path = os.path.join(os.path.dirname(__file__), '..', '..', 755 path = os.path.join(os.path.dirname(__file__), '..', '..',
723 'masters/*/master.cfg') 756 'masters/*/master.cfg')
724 filenames = glob.glob(path_internal) + glob.glob(path) 757 filenames = glob.glob(path_internal) + glob.glob(path)
725 return [os.path.abspath(os.path.dirname(f)) for f in filenames] 758 return [os.path.abspath(os.path.dirname(f)) for f in filenames]
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698