Added new command "patool repack".

This commit is contained in:
Bastian Kleineidam 2010-03-11 18:33:58 +01:00
parent 7a8b5ada3e
commit 5d66704369
7 changed files with 94 additions and 5 deletions

View File

@ -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)

View File

@ -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

View File

@ -8,7 +8,8 @@ NAME
SYNOPSIS
patool (extract|list|test) [options] <archive-file>...
patool create [options] <archive-file> [files...]
patool diff [options] <archive1> <archive2>
patool diff <archive1> <archive2>
patool repack <archive1> <archive2>
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.

5
patool
View File

@ -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."""

View File

@ -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)

View File

@ -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):

37
tests/test_repack.py Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
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)