# 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, ignore_errors=True)
|
# 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. Know data: %s' % self)
|
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))
|