blob: ff13f907f96dddc28d3d7d12d4522a34a0dbc44d [file] [log] [blame]
# Copyright 2015 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.
import glob
import os
import shutil
from dependency_manager import exceptions
from dependency_manager import dependency_manager_util
class ArchiveInfo(object):
def __init__(self, archive_file, unzip_path, path_within_archive,
stale_unzip_path_glob=None):
""" Container for the information needed to unzip a downloaded archive.
Args:
archive_path: Path to the archive file.
unzip_path: Path to unzip the archive into. Assumes that this path
is unique for the archive.
path_within_archive: Specify if and how to handle zip archives
downloaded from cloud_storage. Expected values:
None: Do not unzip the file downloaded from cloud_storage.
'.': Unzip the file downloaded from cloud_storage. The
unzipped file/folder is the expected dependency.
file_path: Unzip the file downloaded from cloud_storage.
|file_path| is the path to the expected dependency,
relative to the unzipped archive path.
stale_unzip_path_glob: Optional argument specifying a glob matching
string which matches directories that should be removed before this
archive is extracted (if it is extracted at all).
"""
self._archive_file = archive_file
self._unzip_path = unzip_path
self._path_within_archive = path_within_archive
self._dependency_path = os.path.join(
self._unzip_path, self._path_within_archive)
self._stale_unzip_path_glob = stale_unzip_path_glob
if not self._has_minimum_data:
raise ValueError(
'Not enough information specified to initialize an archive info.'
' %s' % self)
def GetUnzippedPath(self):
if self.ShouldUnzipArchive():
# Remove stale unzip results
if self._stale_unzip_path_glob:
for path in glob.glob(self._stale_unzip_path_glob):
shutil.rmtree(path)
# TODO(aiolos): Replace UnzipFile with zipfile.extractall once python
# version 2.7.4 or later can safely be assumed.
dependency_manager_util.UnzipArchive(
self._archive_file, self._unzip_path)
if self.ShouldUnzipArchive():
raise exceptions.ArchiveError(
"Expected path '%s' was not extracted from archive '%s'." %
(self._dependency_path, self._archive_file))
return self._dependency_path
def ShouldUnzipArchive(self):
if not self._has_minimum_data:
raise exceptions.ArchiveError(
'Missing needed info to unzip archive. Known data: %s',
self.data_string)
return not os.path.exists(self._dependency_path)
@property
def _has_minimum_data(self):
return all([self._archive_file, self._unzip_path,
self._dependency_path])
def __repr__(self):
return (
'ArchiveInfo(archive_file=%s, unzip_path=%s, path_within_archive=%s, '
'dependency_path =%s)' % (
self._archive_file, self._unzip_path, self._path_within_archive,
self._dependency_path))