diff --git a/doc/changelog.txt b/doc/changelog.txt index b076e0f..48e1ea2 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -5,6 +5,8 @@ * Fix parsing of the "-v" short option. * Added new command "patool diff" to show differences between two archives. + * Added new command "patool repack" to repackage archives in another + format. 0.7 "3000 Miles to Graceland" (released 8.3.2010) diff --git a/doc/patool.1 b/doc/patool.1 index 8383a6e..9dbd2bc 100644 --- a/doc/patool.1 +++ b/doc/patool.1 @@ -17,7 +17,8 @@ patool - simple manager for file archives of various types .SH SYNOPSIS \fBpatool\fP (\fBextract\fP|\fBlist\fP|\fBtest\fP) [\fIoptions\fP] <\fIarchive-file\fP>... \fBpatool\fP \fBcreate\fP [\fIoptions\fP] <\fIarchive-file\fP> [\fIfiles\fP...] - \fBpatool\fP \fBdiff\fP [\fIoptions\fP] <\fIarchive1\fP> <\fIarchive2\fP> + \fBpatool\fP \fBdiff\fP <\fIarchive1\fP> <\fIarchive2\fP> + \fBpatool\fP \fBrepack\fP <\fIarchive1\fP> <\fIarchive2\fP> \fBpatool\fP \fBformats\fP [\fIoptions\fP] .SH DESCRIPTION Various archive types can be created, extracted, tested and listed by @@ -40,6 +41,7 @@ It relies on helper applications to handle those archive formats \fBpatool list package.deb\fP \fPpatool create --verbose myfiles.zip file1.txt dir/\fP \fBpatool diff release1.0.tar.gz release2.0.zip\fP + \fBpatool repack linux-2.6.33.tar.gz linux-2.6.33.tar.bz2\fP .SH COMMANDS Several commands and options are available. .SS \fBextract\fP @@ -92,6 +94,11 @@ Show differences between two archives. .TP \fB\-\-help\fP Show help for this command. +.SS \fBrepack\fP +Repackage archive to a different format. +.TP +\fB\-\-help\fP +Show help for this command. .SS \fBformats\fP Show all supported archive formats. .TP diff --git a/doc/patool.txt b/doc/patool.txt index 17cedaf..b30f289 100644 --- a/doc/patool.txt +++ b/doc/patool.txt @@ -8,7 +8,8 @@ NAME SYNOPSIS patool (extract|list|test) [options] ... patool create [options] [files...] - patool diff [options] + patool diff + patool repack patool formats [options] DESCRIPTION @@ -33,6 +34,7 @@ EXAMPLES patool list package.deb patool create --verbose myfiles.zip file1.txt dir/ patool diff release1.0.tar.gz release2.0.zip + patool repack linux-2.6.33.tar.gz linux-2.6.33.tar.bz2 COMMANDS Several commands and options are available. @@ -85,6 +87,11 @@ COMMANDS --help Show help for this command. + repack + Repackage archive to a different format. + + --help Show help for this command. + formats Show all supported archive formats. diff --git a/patool b/patool index 6d03370..f9ee607 100755 --- a/patool +++ b/patool @@ -75,6 +75,11 @@ def diff (archive1, archive2): """Show differences between two archives.""" return handle_archive(archive1, "diff", archive2) +@baker.command +def repack (archive1, archive2): + """Repackage one archive in another format.""" + return handle_archive(archive1, "repack", archive2) + @baker.command def formats (): """List supported and available archive formats.""" diff --git a/patoolib/__init__.py b/patoolib/__init__.py index d4486a1..25a96c8 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -441,6 +441,8 @@ def handle_archive (archive, command, *args, **kwargs): try: if command == "diff": res = _diff_archives(archive, args[0]) + elif command == "repack": + res = _repack_archive(archive, args[0]) else: _handle_archive(archive, command, *args, **kwargs) res = 0 @@ -457,15 +459,29 @@ def handle_archive (archive, command, *args, **kwargs): def _diff_archives (archive1, archive2): + """Show differences between two archives.""" diff = util.find_program("diff") if not diff: raise util.PatoolError("diff(1) is required for showing archive differences, please install it") tmpdir1 = util.tmpdir() tmpdir2 = util.tmpdir() try: - dir1 = _handle_archive(archive1, 'extract', outdir=tmpdir1) - dir2 = _handle_archive(archive2, 'extract', outdir=tmpdir2) - return util.run([diff, "-BurN", dir1, dir2]) + path1 = _handle_archive(archive1, 'extract', outdir=tmpdir1) + path2 = _handle_archive(archive2, 'extract', outdir=tmpdir2) + return util.run([diff, "-BurN", path1, path2]) finally: shutil.rmtree(tmpdir1, onerror=util.log_error) shutil.rmtree(tmpdir2, onerror=util.log_error) + + +def _repack_archive (archive1, archive2): + """Repackage an archive to a different format.""" + tmpdir = util.tmpdir() + try: + _handle_archive(archive1, 'extract', outdir=tmpdir) + archive = os.path.abspath(archive2) + files = tuple(os.listdir(tmpdir)) + os.chdir(tmpdir) + _handle_archive(archive, 'create', *files) + finally: + shutil.rmtree(tmpdir, onerror=util.log_error) diff --git a/tests/__init__.py b/tests/__init__.py index fc9d6e1..d40ef09 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -131,6 +131,21 @@ def needs_program (program): return check_prog +def needs_one_program (programs): + """Decorator skipping test if not one of given programs are available.""" + def check_prog (f): + def newfunc (*args, **kwargs): + for program in programs: + if patoolib.util.find_program(program): + break + else: + raise nose.SkipTest("None of programs %s available" % programs) + return f(*args, **kwargs) + newfunc.func_name = f.func_name + return newfunc + return check_prog + + def needs_codec (program, codec): """Decorator skipping test if given program codec is not available.""" def check_prog (f): diff --git a/tests/test_repack.py b/tests/test_repack.py new file mode 100644 index 0000000..a0ca7c1 --- /dev/null +++ b/tests/test_repack.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2010 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 . +import unittest +import os +import shutil +import patoolib +from tests import datadir, needs_program, needs_one_program + +class ArchiveRepackTest (unittest.TestCase): + + @needs_program('diff') + @needs_one_program(('tar', 'star', '7z')) + @needs_one_program(('unzip', '7z')) + def test_repack (self): + archive1 = os.path.join(datadir, "t.tar") + tmpdir = patoolib.util.tmpdir() + try: + archive2 = os.path.join(tmpdir, "t.zip") + patoolib.handle_archive(archive1, "repack", archive2) + res = patoolib.handle_archive(archive1, "diff", archive2) + finally: + shutil.rmtree(tmpdir) + # both archives have the same data + self.assertEqual(res, 0)