OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 |
| 3 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. |
| 6 |
| 7 """Utilities for PyAuto.""" |
| 8 |
| 9 import logging |
| 10 import os |
| 11 import shutil |
| 12 import tempfile |
| 13 |
| 14 |
| 15 class ExistingPathReplacer(object): |
| 16 """Facilitates backing up a given path (file or dir).. |
| 17 |
| 18 Often you want to manipulate a directory or file for testing but don't want to |
| 19 meddle with the existing contents. This class lets you make a backup, and |
| 20 reinstate the backup when done. A backup is made in an adjacent directory, |
| 21 so you need to make sure you have write permissions to the parent directory. |
| 22 |
| 23 Works seemlessly in cases where the requested path already exists, or not. |
| 24 |
| 25 Automatically reinstates the backed up path (if any) when object is deleted. |
| 26 """ |
| 27 _path = '' |
| 28 _backup_dir = None # dir to which existing content is backed up |
| 29 _backup_basename = '' |
| 30 |
| 31 def __init__(self, path, path_type='dir'): |
| 32 """Initialize the object, making backups if necessary. |
| 33 |
| 34 Args: |
| 35 path: the requested path to file or directory |
| 36 path_type: path type. Options: 'file', 'dir'. Default: 'dir' |
| 37 """ |
| 38 assert path_type in ('file', 'dir'), 'Invalid path_type: %s' % path_type |
| 39 self._path_type = path_type |
| 40 self._path = path |
| 41 if os.path.exists(self._path): |
| 42 if 'dir' == self._path_type: |
| 43 assert os.path.isdir(self._path), '%s is not a directory' % self._path |
| 44 else: |
| 45 assert os.path.isfile(self._path), '%s is not a file' % self._path |
| 46 # take a backup |
| 47 self._backup_basename = os.path.basename(self._path) |
| 48 self._backup_dir = tempfile.mkdtemp(dir=os.path.dirname(self._path), |
| 49 prefix='bkp-' + self._backup_basename) |
| 50 logging.info('Backing up %s in %s' % (self._path, self._backup_dir)) |
| 51 shutil.move(self._path, |
| 52 os.path.join(self._backup_dir, self._backup_basename)) |
| 53 self._CreateRequestedPath() |
| 54 |
| 55 def __del__(self): |
| 56 """Cleanup. Reinstate backup.""" |
| 57 self._CleanupRequestedPath() |
| 58 if self._backup_dir: # Reinstate, if backed up. |
| 59 from_path = os.path.join(self._backup_dir, self._backup_basename) |
| 60 logging.info('Reinstating backup from %s to %s' % (from_path, self._path)) |
| 61 shutil.move(from_path, self._path) |
| 62 self._RemoveBackupDir() |
| 63 |
| 64 def _CreateRequestedPath(self): |
| 65 if 'dir' == self._path_type: |
| 66 os.mkdir(self._path) |
| 67 else: |
| 68 open(self._path, 'w').close() |
| 69 |
| 70 def _CleanupRequestedPath(self): |
| 71 if os.path.exists(self._path): |
| 72 if os.path.isdir(self._path): |
| 73 shutil.rmtree(self._path, ignore_errors=True) |
| 74 else: |
| 75 os.remove(self._path) |
| 76 |
| 77 def _RemoveBackupDir(self): |
| 78 if self._backup_dir and os.path.isdir(self._backup_dir): |
| 79 shutil.rmtree(self._backup_dir, ignore_errors=True) |
OLD | NEW |