From 2a788ed4c4ec1a88ac3cdc2cb6c1102a2b99338a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ozan=20=C3=87a=C4=9Flayan?= Date: Wed, 8 Jun 2011 11:54:25 +0000 Subject: [PATCH] archive: Add support for 7-Zip source archives Dynamically check the unpacker and gracefully inform the user about the missing utility. BUG:FIXED:3870 --- pisi-spec.rng | 1 + pisi/archive.py | 24 ++++++++++++++++++++++++ pisi/sourcearchive.py | 3 +++ 3 files changed, 28 insertions(+) diff --git a/pisi-spec.rng b/pisi-spec.rng index fa3f8ff9..aef76d28 100644 --- a/pisi-spec.rng +++ b/pisi-spec.rng @@ -1336,6 +1336,7 @@ bzip2 lzma xz + 7z binary diff --git a/pisi/archive.py b/pisi/archive.py index 25248600..26e325e2 100644 --- a/pisi/archive.py +++ b/pisi/archive.py @@ -32,6 +32,9 @@ import pisi.context as ctx class UnknownArchiveType(Exception): pass +class ArchiveHandlerNotInstalled(Exception): + pass + # Proxy class inspired from tarfile._BZ2Proxy class _LZMAProxy(object): @@ -461,6 +464,25 @@ class ArchiveTarZ(ArchiveBase): pass self.tar.close() +class Archive7Zip(ArchiveBase): + """ArchiveZip handles 7-Zip archives.""" + + def __init__(self, file_path, arch_type="7z"): + super(Archive7Zip, self).__init__(file_path, arch_type) + self.cmd = pisi.util.search_executable(arch_type) + if not self.cmd: + raise ArchiveHandlerNotInstalled + + def unpack(self, target_dir, clean_dir=False): + super(Archive7Zip, self).unpack(target_dir, clean_dir) + self.unpack_dir(target_dir) + + def unpack_dir(self, target_dir): + """Unpack 7z archive to a given target directory(target_dir).""" + + # e.g. 7z x -bd -o + pisi.util.run_batch("%s x -bd -o%s %s" % (self.cmd, target_dir, self.file_path)) + class ArchiveZip(ArchiveBase): """ArchiveZip handles zip archives. @@ -639,6 +661,7 @@ class Archive: 'bzip2': ArchiveBzip2, 'lzma': ArchiveLzma, 'xz': ArchiveLzma, + '7z': Archive7Zip, 'binary': ArchiveBinary} handler = handlers.get(arch_type) @@ -659,6 +682,7 @@ class Archive: ("bz2", (".bz2", ".bz")), ("lzma", (".lzma",)), ("xz", (".xz",)), + ("7z", (".7z",)), ("binary", (".bin", ".run", ".sh"))) for _type, extensions in types: diff --git a/pisi/sourcearchive.py b/pisi/sourcearchive.py index 09ddac59..400efb84 100644 --- a/pisi/sourcearchive.py +++ b/pisi/sourcearchive.py @@ -123,6 +123,9 @@ class SourceArchive: except pisi.archive.UnknownArchiveType: raise Error(_("Unknown archive type '%s' is given for '%s'.") % (self.archive.type, self.url.filename())) + except pisi.archive.ArchiveHandlerNotInstalled: + raise Error(_("Pisi needs %s to unpack this archive but it is not installed.") + % self.archive.type) target_dir = os.path.join(target_dir, self.archive.target or "") archive.unpack(target_dir, clean_dir)