def test_basic(self, mock_chdir, mock_getcwd): with utils.workdir('/test/path') as cwd: self.assertEqual(cwd, '/c/w/d') mock_getcwd.assert_called_once_with() mock_chdir.assert_has_calls([ mock.call('/test/path'), mock.call('/c/w/d'), ])
def test_exception(self, mock_chdir, mock_getcwd): try: with utils.workdir('/test/path') as cwd: self.assertEqual(cwd, '/c/w/d') raise tests.TestException('test') except tests.TestException: pass else: self.fail("Failed to bubble up raised exception") mock_getcwd.assert_called_once_with() mock_chdir.assert_has_calls([ mock.call('/test/path'), mock.call('/c/w/d'), ])
def tar(self, filename, start=os.curdir, compression=utils.unset, hasher=None): """ Create a tar file with the given filename. :param filename: The filename of the tar file to create. If ``compression`` is not given, it will be inferred from the filename. The appropriate extensions will be added to the filename, if necessary. If a compression extension on the filename does not match the specified compression, a ``ValueError`` will be raised. :param start: The directory from which to start the tar process. If not given, starts from the current directory and includes all files in the directory. If it is a parent of the current directory, only the current directory will be included in the tarball. A ``ValueError`` will be raised if the tar process cannot start from the given location. :param compression: If given, specifies the compression to use. The ``filename`` will be modified to include the appropriate extension. A ``ValueError`` will be raised if the given compression is not supported or if a compression was inferred from the filename. :param hasher: If given, requests that a hash of the resulting tar file be computed. May be a ``True`` value to use the default hasher; a string to specify a hasher; or a tuple of hashers. :returns: The final filename that was created. If ``hasher`` was specified, a tuple will be returned, with the second element consisting of the hex digest of the tar file. """ # If the filename is a FSEntry, use its path if isinstance(filename, FSEntry): filename = filename.path # Parse the file name and set the compression filename = tarname.TarFileName(utils.abspath(filename, cwd=self.path)) if compression is not utils.unset: filename.compression = compression # Determine the starting location and file list start = self._rel(start, False) filelist = None rel_path = utils.RelPath(start, self.name) if rel_path.parents and rel_path.remainder: raise ValueError("cannot start tar-ing from '%s'" % rel_path) elif not rel_path.parents and not rel_path.remainder: start = self.path elif rel_path.parents: start = os.path.normpath( os.path.join(self.path, [os.pardir] * rel_path.parents)) filelist = [os.path.join(*rel_path.path_list[-rel_path.parents:])] start = self.tree._full(start) if filelist is None: filelist = os.listdir(start) # OK, let's build the tarball tar = tarfile.open(str(filename), 'w:%s' % filename.compression or '') try: with utils.workdir(start): for fname in filelist: try: tar.add(fname) except Exception: pass finally: tar.close() # Begin building the result result = str(filename) # If a hash was requested, generate it if hasher: # Select the hasher(s) if hasher is True: hasher = (utils.get_hasher(utils.DEFAULT_HASHER)(),) elif isinstance(hasher, six.string_types): hasher = (utils.get_hasher(hasher)(),) elif not isinstance(hasher, tuple): hasher = (hasher,) # Open the file with open(result) as f: result = (result, utils.digest(f, hasher)) return result