From 6cba7794753dece5714c956cefa475afb1632742 Mon Sep 17 00:00:00 2001 From: Bastian Kleineidam Date: Sat, 6 Mar 2010 16:52:13 +0100 Subject: [PATCH] Added support for AR (.a) archives. --- doc/changelog.txt | 1 + doc/patool.1 | 2 +- doc/patool.txt | 25 ++++++++++---------- doc/todo.txt | 1 - patoolib/__init__.py | 7 +++++- patoolib/programs/ar.py | 47 ++++++++++++++++++++++++++++++++++++++ patoolib/util.py | 3 +++ tests/__init__.py | 2 +- tests/data/t.a | 4 ++++ tests/data/t.a.foo | 4 ++++ tests/test_archives.py | 5 ++++ tests/test_foo_archives.py | 6 +++++ tests/test_mime.py | 2 ++ 13 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 patoolib/programs/ar.py create mode 100644 tests/data/t.a create mode 100644 tests/data/t.a.foo diff --git a/doc/changelog.txt b/doc/changelog.txt index 6cfc99a..0076b3d 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -7,6 +7,7 @@ * Fix permissions of extracted files: make them readable by the current user. * Added support for ACE (.ace) archives. + * Added support for AR (.a) archives. 0.5 "Vanishing Point" (released 4.3.2010) diff --git a/doc/patool.1 b/doc/patool.1 index 61604b1..7058060 100644 --- a/doc/patool.1 +++ b/doc/patool.1 @@ -26,7 +26,7 @@ files without having to remember a myriad of programs and options. The archive format is determined by the file(1) program and as a fallback by the archive file extension. .PP -\fBpatool\fP supports 7z (.7z), ACE (.ace), ZIP (.zip, .jar), GZIP (.gz), compress (.Z), +\fBpatool\fP supports 7z (.7z), ACE (.ace), AR (.a), ZIP (.zip, .jar), GZIP (.gz), compress (.Z), BZIP2 (.bz2), TAR (.tar), ARJ (.arj), CAB (.cab), CPIO (.cpio), RPM (.rpm), DEB (.deb), LZIP (.lz), LZOP (.lzo), LZMA (.lzma), RAR (.rar) and XZ (.xz) formats. diff --git a/doc/patool.txt b/doc/patool.txt index 1f8029f..eb24bd9 100644 --- a/doc/patool.txt +++ b/doc/patool.txt @@ -18,11 +18,12 @@ DESCRIPTION The archive format is determined by the file(1) program and as a fall‐ back by the archive file extension. - patool supports 7z (.7z), ACE (.ace), ZIP (.zip, .jar), GZIP (.gz), - compress (.Z), BZIP2 (.bz2), TAR (.tar), ARJ (.arj), CAB (.cab), CPIO - (.cpio), RPM (.rpm), DEB (.deb), LZIP (.lz), LZOP (.lzo), LZMA (.lzma), - RAR (.rar) and XZ (.xz) formats. It relies on helper applications to - handle those archive formats (for example bzip2 for BZIP2 archives). + patool supports 7z (.7z), ACE (.ace), AR (.a), ZIP (.zip, .jar), GZIP + (.gz), compress (.Z), BZIP2 (.bz2), TAR (.tar), ARJ (.arj), CAB (.cab), + CPIO (.cpio), RPM (.rpm), DEB (.deb), LZIP (.lz), LZOP (.lzo), LZMA + (.lzma), RAR (.rar) and XZ (.xz) formats. It relies on helper applica‐ + tions to handle those archive formats (for example bzip2 for BZIP2 ar‐ + chives). EXAMPLES patool extract archive.zip otherarchive.rar @@ -34,19 +35,19 @@ COMMANDS Several commands and options are available. extract - Extract files from an archive. This is the default command if no com‐ + Extract files from an archive. This is the default command if no com‐ mand was given. - Often one wants to extract all files in an archive to a single subdi‐ - rectory. However, some archives contain multiple files in their root + Often one wants to extract all files in an archive to a single subdi‐ + rectory. However, some archives contain multiple files in their root directories. The patool program overcomes this problem by first extracting files to a unique (temporary) directory, and then moving its - contents back if possible. This also prevents local files from being + contents back if possible. This also prevents local files from being overwritten by mistake. - All extracted files are checked that they are readable by the current + All extracted files are checked that they are readable by the current user. -v, --verbose - Be verbose when extracting (if the helper application supports + Be verbose when extracting (if the helper application supports it). --help Show help for this command. @@ -60,7 +61,7 @@ COMMANDS --help Show help for this command. create - Create an archive from given files. At least on of the given files to + Create an archive from given files. At least on of the given files to add to the archive has to exist. -v, --verbose diff --git a/doc/todo.txt b/doc/todo.txt index 24deb30..e05ddbb 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -1,2 +1 @@ -- Support ar archives. - Support lha archives. diff --git a/patoolib/__init__.py b/patoolib/__init__.py index 79fcd90..5e375e8 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -23,7 +23,8 @@ ArchiveCommands = ('list', 'extract', 'test', 'create') # Supported archive formats ArchiveFormats = ('gzip', 'bzip2', 'tar', 'zip', 'compress', '7z', 'rar', - 'cab', 'arj', 'cpio', 'rpm', 'deb', 'lzop', 'lzma', 'xz', 'lzip', 'ace') + 'cab', 'arj', 'cpio', 'rpm', 'deb', 'lzop', 'lzma', 'xz', 'lzip', 'ace', + 'ar') # Supported encodings (used with tar for example) # Note that all encodings must also be archive formats @@ -52,6 +53,7 @@ ArchiveMimetypes = { 'application/x-xz': 'xz', 'application/x-lzip': 'lzip', 'application/x-ace': 'ace', + 'application/x-archive': 'ar', } # List of programs supporting the given encoding @@ -73,6 +75,9 @@ ArchivePrograms = { 'test': ('unace',), 'list': ('unace',), }, + 'ar': { + None: ('ar',), + }, 'bzip2': { 'extract': ('pbzip2', 'bzip2', '7z'), 'test': ('pbzip2', 'bzip2', '7z'), diff --git a/patoolib/programs/ar.py b/patoolib/programs/ar.py new file mode 100644 index 0000000..7d48858 --- /dev/null +++ b/patoolib/programs/ar.py @@ -0,0 +1,47 @@ +# -*- 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 . +"""Archive commands for the ar program.""" + +def extract_ar (archive, encoding, cmd, **kwargs): + """Extract a AR archive.""" + cmdlist = [cmd] + opts = 'x' + if kwargs['verbose']: + opts += 'v' + cmdlist.extend([opts, archive, kwargs['outdir']]) + return cmdlist + +def list_ar (archive, encoding, cmd, **kwargs): + """List a AR archive.""" + cmdlist = [cmd] + opts = 't' + if kwargs['verbose']: + opts += 'v' + cmdlist.extend([opts, archive]) + return cmdlist + +test_ar = list_ar + +def create_ar (archive, encoding, cmd, *args, **kwargs): + """Create a AR archive.""" + cmdlist = [cmd] + opts = 'rc' + if kwargs['verbose']: + opts += 'v' + cmdlist.extend([opts, archive]) + cmdlist.extend(args) + return cmdlist + diff --git a/patoolib/util.py b/patoolib/util.py index 48c52d8..4545a49 100644 --- a/patoolib/util.py +++ b/patoolib/util.py @@ -40,6 +40,8 @@ mimedb.add_type('application/x-cab', '.cab', strict=False) mimedb.add_type('application/x-rpm', '.rpm', strict=False) mimedb.add_type('application/x-debian-package', '.deb', strict=False) mimedb.add_type('application/x-ace', '.ace', strict=False) +# Since .a is already a common type, strict=True must be used. +mimedb.add_type('application/x-archive', '.a', strict=True) class PatoolError (StandardError): @@ -190,6 +192,7 @@ FileText2Mime = { "Zip archive data": "application/zip", "compress'd data": "application/x-compress", "lzip compressed data": "application/x-lzip", + "current ar archive": "application/x-archive", } def guess_mime_file (file_prog, filename): diff --git a/tests/__init__.py b/tests/__init__.py index 2ecac88..1459e5e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -76,7 +76,7 @@ class ArchiveTest (unittest.TestCase): kwargs = dict( program=self.program, format=format, - encoding=encoding + encoding=encoding, ) self._archive_create(filename, topack, kwargs) kwargs['verbose'] = True diff --git a/tests/data/t.a b/tests/data/t.a new file mode 100644 index 0000000..f389b69 --- /dev/null +++ b/tests/data/t.a @@ -0,0 +1,4 @@ +! +t.txt/ 1266562138 1000 1000 100640 3 ` +42 + diff --git a/tests/data/t.a.foo b/tests/data/t.a.foo new file mode 100644 index 0000000..f389b69 --- /dev/null +++ b/tests/data/t.a.foo @@ -0,0 +1,4 @@ +! +t.txt/ 1266562138 1000 1000 100640 3 ` +42 + diff --git a/tests/test_archives.py b/tests/test_archives.py index c8b8485..1f21a85 100644 --- a/tests/test_archives.py +++ b/tests/test_archives.py @@ -212,6 +212,11 @@ class TestArchives (ArchiveTest): self.program = 'arj' self.archive_commands('t.arj') + @needs_program('ar') + def test_ar (self): + self.program = 'ar' + self.archive_commands('t.a', singlefile=True) + @needs_program('cpio') def test_cpio (self): self.program = 'cpio' diff --git a/tests/test_foo_archives.py b/tests/test_foo_archives.py index f8fd946..06458f1 100644 --- a/tests/test_foo_archives.py +++ b/tests/test_foo_archives.py @@ -243,6 +243,12 @@ class TestArchives (ArchiveTest): self.program = 'arj' self.archive_commands('t.arj.foo', format="arj") + @needs_program('file') + @needs_program('ar') + def test_ar (self): + self.program = 'ar' + self.archive_commands('t.a.foo', format='ar', singlefile=True) + @needs_program('file') @needs_program('cpio') def test_cpio (self): diff --git a/tests/test_mime.py b/tests/test_mime.py index 66e9ad0..42b0cfb 100644 --- a/tests/test_mime.py +++ b/tests/test_mime.py @@ -88,3 +88,5 @@ class TestMime (unittest.TestCase): self.mime_test("t.zip.foo", "application/zip", None) self.mime_test("t.ace", "application/x-ace", None) self.mime_test("t.ace.foo", "application/x-ace", None) + self.mime_test("t.a", "application/x-archive", None) + self.mime_test("t.a.foo", "application/x-archive", None)