diff --git a/patoolib/__init__.py b/patoolib/__init__.py index d0ad39e..01e2507 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -112,7 +112,7 @@ ArchivePrograms = { 'list': ('py_echo',), }, 'tar': { - None: ('tar', 'star', 'py_tarfile'), + None: ('tar', 'star', 'bsdtar', 'py_tarfile'), }, 'zip': { None: ('7z', '7za', 'py_zipfile'), @@ -283,7 +283,7 @@ def program_supports_compression (program, compression): @return: True iff the program supports the given compression format natively, else False. """ - if program in ('tar', 'star', 'py_tarfile'): + if program in ('tar', 'star', 'bsdtar', 'py_tarfile'): return compression in ('gzip', 'bzip2') return False diff --git a/patoolib/programs/bsdtar.py b/patoolib/programs/bsdtar.py new file mode 100644 index 0000000..9981ca4 --- /dev/null +++ b/patoolib/programs/bsdtar.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2012 Bastian Kleineidam +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +"""Archive commands for the BSD tar program.""" + +from .tar import extract_tar, list_tar, test_tar, create_tar diff --git a/patoolib/programs/tar.py b/patoolib/programs/tar.py index 997140e..3980059 100644 --- a/patoolib/programs/tar.py +++ b/patoolib/programs/tar.py @@ -14,6 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Archive commands for the GNU tar program.""" +import os + def extract_tar (archive, compression, cmd, **kwargs): """Extract a TAR archive.""" @@ -40,12 +42,15 @@ def create_tar (archive, compression, cmd, *args, **kwargs): return cmdlist def add_tar_opts (cmdlist, compression, verbose): + progname = os.path.basename(cmdlist[0]) if compression == 'gzip': cmdlist.append('-z') elif compression == 'compress': cmdlist.append('-Z') elif compression == 'bzip2': cmdlist.append('-j') + elif compression in ('lzma', 'xz') and progname == 'bsdtar': + cmdlist.append('--%s' % compression) elif compression in ('lzma', 'xz', 'lzip'): # use the compression name as program name since # tar is picky which programs it can use diff --git a/tests/test_archives.py b/tests/test_archives.py index 90fe6d6..c505b57 100644 --- a/tests/test_archives.py +++ b/tests/test_archives.py @@ -99,6 +99,48 @@ class TestArchives (ArchiveTest): self.program = 'star' self.archive_commands('t.tar.xz') + @needs_program('bsdtar') + def test_bsdtar (self): + self.program = 'bsdtar' + self.archive_commands('t.tar') + + @needs_codec('bsdtar', 'gzip') + def test_bsdtar_gz (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.gz') + self.archive_commands('t.tgz') + + @needs_program('bsdtar') + @needs_program('compress') + def test_bsdtar_z (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.Z') + self.archive_commands('t.taz') + + @needs_codec('bsdtar', 'bzip2') + def test_bsdtar_bz2 (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.bz2') + self.archive_commands('t.tbz2') + + @needs_codec('bsdtar', 'lzma') + def test_bsdtar_lzma (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.lzma') + + # even though clzip would support extracting .lz files, the + # file(1) --uncompress command does not use it for achive detection + @needs_program('bsdtar') + @needs_program('lzip') + def test_bsdtar_lzip (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.lz') + + @needs_codec('bsdtar', 'xz') + def test_bsdtar_xz (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.xz') + def test_py_tarfile (self): self.program = 'py_tarfile' self.archive_commands('t.tar') diff --git a/tests/test_foo_archives.py b/tests/test_foo_archives.py index 4a06f4b..2945553 100644 --- a/tests/test_foo_archives.py +++ b/tests/test_foo_archives.py @@ -66,6 +66,55 @@ class TestArchives (ArchiveTest): self.program = 'tar' self.archive_commands('t.tar.xz.foo', format="tar", compression="xz") + @needs_program('file') + @needs_program('bsdtar') + def test_bsdtar_file (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.foo', format="tar") + + @needs_program('file') + @needs_codec('bsdtar', 'gzip') + def test_bsdtar_gz_file (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.gz.foo', format="tar", compression="gzip") + self.archive_commands('t.tgz.foo', format="tar", compression="gzip") + + @needs_program('file') + @needs_codec('bsdtar', 'compress') + def test_bsdtar_z (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.Z.foo', format="tar", compression="compress") + self.archive_commands('t.taz.foo', format="tar", compression="compress") + + @needs_program('file') + @needs_codec('bsdtar', 'bzip2') + def test_bsdtar_bz2 (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.bz2.foo', format="tar", compression="bzip2") + self.archive_commands('t.tbz2.foo', format="tar", compression="bzip2") + + # file(1) does not recognize .lzma files (at least not with --uncompress) + #@needs_program('file') + #@needs_codec('bsdtar', 'lzma') + #def test_bsdtar_lzma (self): + # self.program = 'bsdtar' + # self.archive_commands('t.tar.lzma.foo', format="tar", compression="lzma") + + # even though clzip would support extracting .lz files, the + # file(1) --uncompress command does not use it for achive detection + @needs_program('lzip') + @needs_program('file') + @needs_codec('bsdtar', 'lzip') + def test_bsdtar_lzip (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.lz.foo', format="tar", compression="lzip") + + @needs_program('file') + @needs_codec('bsdtar', 'xz') + def test_bsdtar_xz (self): + self.program = 'bsdtar' + self.archive_commands('t.tar.xz.foo', format="tar", compression="xz") + @needs_program('file') @needs_program('star') def test_star (self):