Added new command "patool repack".
This commit is contained in:
parent
7a8b5ada3e
commit
5d66704369
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
5
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."""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue