| # Copyright 2014 The Chromium Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| from recipe_engine import recipe_api | |
| class ZipApi(recipe_api.RecipeApi): | |
| """Provides steps to zip and unzip files.""" | |
| def make_package(self, root, output): | |
| """Returns ZipPackage object that can be used to compress a set of files. | |
| Usage: | |
| pkg = api.zip.make_package(root, output) | |
| pkg.add_file(root.join('file')) | |
| pkg.add_directory(root.join('directory')) | |
| yield pkg.zip('zipping step') | |
| Args: | |
| root: a directory that would become root of a package, all files added to | |
| an archive will have archive paths relative to this directory. | |
| output: path to a zip file to create. | |
| Returns: | |
| ZipPackage object. | |
| """ | |
| return ZipPackage(self, root, output) | |
| def directory(self, step_name, directory, output): | |
| """Step to compress a single directory. | |
| Args: | |
| step_name: display name of the step. | |
| directory: path to a directory to compress, it would become the root of | |
| an archive, i.e. |directory|/file.txt would be named 'file.txt' in | |
| the archive. | |
| output: path to a zip file to create. | |
| """ | |
| pkg = self.make_package(directory, output) | |
| pkg.add_directory(directory) | |
| pkg.zip(step_name) | |
| def unzip(self, step_name, zip_file, output, quiet=False): | |
| """Step to uncompress |zip_file| into |output| directory. | |
| Zip package will be unpacked to |output| so that root of an archive is in | |
| |output|, i.e. archive.zip/file.txt will become |output|/file.txt. | |
| Step will FAIL if |output| already exists. | |
| Args: | |
| step_name: display name of a step. | |
| zip_file: path to a zip file to uncompress, should exist. | |
| output: path to a directory to unpack to, it should NOT exist. | |
| quiet (bool): If True, print terse output instead of the name | |
| of each unzipped file. | |
| """ | |
| # TODO(vadimsh): Use 7zip on Windows if available? | |
| script_input = { | |
| 'output': str(output), | |
| 'zip_file': str(zip_file), | |
| 'quiet': quiet, | |
| } | |
| self.m.python( | |
| name=step_name, | |
| script=self.resource('unzip.py'), | |
| stdin=self.m.json.input(script_input)) | |
| class ZipPackage(object): | |
| """Used to gather a list of files to zip.""" | |
| def __init__(self, module, root, output): | |
| self._module = module | |
| self._root = root | |
| self._output = output | |
| self._entries = [] | |
| @property | |
| def root(self): | |
| return self._root | |
| @property | |
| def output(self): | |
| return self._output | |
| def add_file(self, path, archive_name=None): | |
| """Stages single file to be added to the package. | |
| Args: | |
| path: absolute path to a file, should be in |root| subdirectory. | |
| archive_name: name of the file in the archive, if non-None | |
| """ | |
| assert self._root.is_parent_of(path), path | |
| self._entries.append({ | |
| 'type': 'file', | |
| 'path': str(path), | |
| 'archive_name': archive_name | |
| }) | |
| def add_directory(self, path): | |
| """Stages a directory with all its content to be added to the package. | |
| Args: | |
| path: absolute path to a directory, should be in |root| subdirectory. | |
| """ | |
| # TODO(vadimsh): Implement 'exclude' filter. | |
| assert self._root.is_parent_of(path) or path == self._root, path | |
| self._entries.append({ | |
| 'type': 'dir', | |
| 'path': str(path), | |
| }) | |
| def zip(self, step_name): | |
| """Step to zip all staged files.""" | |
| script_input = { | |
| 'entries': self._entries, | |
| 'output': str(self._output), | |
| 'root': str(self._root), | |
| } | |
| step_result = self._module.m.python( | |
| name=step_name, | |
| script=self._module.resource('zip.py'), | |
| stdin=self._module.m.json.input(script_input)) | |
| self._module.m.path.mock_add_paths(self._output) | |
| return step_result |