| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import logging |
| 6 import os |
| 7 import sys |
| 8 import tempfile |
| 9 |
| 10 # Install Infra build environment. |
| 11 BUILD_ROOT = os.path.dirname(os.path.dirname(os.path.dirname( |
| 12 os.path.abspath(__file__)))) |
| 13 sys.path.insert(0, os.path.join(BUILD_ROOT, 'scripts')) |
| 14 |
| 15 from common import chromium_utils |
| 16 |
| 17 |
| 18 LOGGER = logging.getLogger('robust_tempdir') |
| 19 |
| 20 |
| 21 def _ensure_directory(*path): |
| 22 path = os.path.join(*path) |
| 23 if not os.path.isdir(path): |
| 24 os.makedirs(path) |
| 25 return path |
| 26 |
| 27 |
| 28 class RobustTempdir(object): |
| 29 """RobustTempdir is a ContextManager that tracks generated files and cleans |
| 30 them up at exit. |
| 31 """ |
| 32 |
| 33 def __init__(self, prefix, leak=False): |
| 34 """Creates a RobustTempdir. |
| 35 |
| 36 Args: |
| 37 prefix (str): prefix to use for the temporary directories |
| 38 leak (bool): if True, do not remove temporary directories |
| 39 on exit |
| 40 """ |
| 41 |
| 42 self._tempdirs = [] |
| 43 self._prefix = prefix |
| 44 self._leak = leak |
| 45 |
| 46 def cleanup(self, path): |
| 47 self._tempdirs.append(path) |
| 48 |
| 49 def tempdir(self, base=None): |
| 50 """Creates a temporary working directory and yields it. |
| 51 |
| 52 This creates two levels of directory: |
| 53 <base>/<prefix> |
| 54 <base>/<prefix>/tmpFOO |
| 55 |
| 56 On termination, the entire "<base>/<prefix>" directory is deleted, |
| 57 removing the subdirectory created by this instance as well as cleaning up |
| 58 any other temporary subdirectories leaked by previous executions. |
| 59 |
| 60 Args: |
| 61 base (str/None): The directory under which the tempdir should be created. |
| 62 If None, the default temporary directory root will be used. |
| 63 """ |
| 64 base = base or tempfile.gettempdir() |
| 65 # TODO(phajdan.jr): Clean up leaked directories at the beginning. |
| 66 # Doing so should automatically prevent more out-of-disk-space scenarios. |
| 67 basedir = _ensure_directory(base, self._prefix) |
| 68 self.cleanup(basedir) |
| 69 tdir = tempfile.mkdtemp(dir=basedir) |
| 70 return tdir |
| 71 |
| 72 def __enter__(self): |
| 73 return self |
| 74 |
| 75 def __exit__(self, _et, _ev, _tb): |
| 76 self.close() |
| 77 |
| 78 def close(self): |
| 79 if self._leak: |
| 80 LOGGER.warning('Leaking temporary paths: %s', self._tempdirs) |
| 81 else: |
| 82 for path in reversed(self._tempdirs): |
| 83 try: |
| 84 if os.path.isdir(path): |
| 85 LOGGER.debug('Cleaning up temporary directory [%s].', path) |
| 86 chromium_utils.RemoveDirectory(path) |
| 87 except BaseException: |
| 88 LOGGER.exception('Failed to clean up temporary directory [%s].', |
| 89 path) |
| 90 del(self._tempdirs[:]) |
| OLD | NEW |