Permalink
Browse files

Refactoring to avoid exposing the different archive formats

  • Loading branch information...
1 parent c93254e commit 530c853e01a1a053aaff242786e452eaa23714f9 @dvarrazzo committed Aug 31, 2012
View
@@ -0,0 +1,60 @@
+"""
+pgxnclient -- archives handling
+"""
+
+# Copyright (C) 2011-2012 Daniele Varrazzo
+
+# This file is part of the PGXN client
+
+from pgxnclient.utils.tar import unpack_tar, get_meta_from_tar
+from pgxnclient.utils.zip import unpack_zip, get_meta_from_zip
+
+
+def from_spec(spec):
+ """Return an `Archive` instance to handle the file requested by *spec*
+ """
+ assert spec.is_file()
+ return from_file(spec.filename)
+
+def from_file(filename):
+ """Return an `Archive` instance to handle the file *filename*
+ """
+ # Get the metadata from an archive file
+ if filename.endswith('.zip'):
+ return ZipArchive(filename)
+ else:
+ # Tar files have many naming variants. Let's not
+ # guess them.
+ return TarArchive(filename)
+
+
+class Archive(object):
+ """Base class to handle archives."""
+ def __init__(self, filename):
+ self.filename = filename
+
+ def get_meta(self):
+ raise NotImplementedError
+
+ def unpack(self, destdir):
+ raise NotImplementedError
+
+
+class TarArchive(Archive):
+ """Handle .tar archives"""
+ def get_meta(self):
+ return get_meta_from_tar(self.filename)
+
+ def unpack(self, destdir):
+ return unpack_tar(self.filename, destdir)
+
+
+class ZipArchive(Archive):
+ """Handle .zip archives"""
+ def get_meta(self):
+ return get_meta_from_zip(self.filename)
+
+ def unpack(self, destdir):
+ return unpack_zip(self.filename, destdir)
+
+
@@ -21,6 +21,7 @@
from pgxnclient import __version__
from pgxnclient import Spec, SemVer
+from pgxnclient import archive
from pgxnclient.api import Api
from pgxnclient.i18n import _, gettext
from pgxnclient.errors import NotFound, PgxnClientException, ProcessError, ResourceNotFound, UserAbort
@@ -223,8 +224,6 @@ def popen(self, cmd, *args, **kwargs):
from pgxnclient.errors import BadSpecError
-from pgxnclient.utils.zip import get_meta_from_zip
-from pgxnclient.utils.tar import get_meta_from_tar
class WithSpec(Command):
"""Mixin to implement commands taking a package specification.
@@ -385,13 +384,8 @@ def get_meta(self, spec):
return load_json(f)
elif spec.is_file():
- # Get the metadata from an archive file
- if spec.filename.endswith('.zip'):
- return get_meta_from_zip(spec.filename)
- else:
- # Tar files have many naming variants. Let's not
- # guess them.
- return get_meta_from_tar(spec.filename)
+ arc = archive.from_spec(spec)
+ return arc.get_meta()
class WithSpecLocal(WithSpec):
@@ -417,8 +411,6 @@ def get_spec(self):
import shutil
import tempfile
-from pgxnclient.utils.tar import unpack as unpack_tar
-from pgxnclient.utils.zip import unpack as unpack_zip
class WithUnpacking(object):
"""
@@ -438,12 +430,10 @@ def call_with_temp_dir(self, f, *args, **kwargs):
finally:
shutil.rmtree(dir)
- def unpack(self, zipname, destdir):
+ def unpack(self, filename, destdir):
"""Unpack the zip file *zipname* into *destdir*."""
- if zipname.endswith('.zip'):
- return unpack_zip(zipname, destdir)
- else:
- return unpack_tar(zipname, destdir)
+ arc = archive.from_file(filename)
+ return arc.unpack(destdir)
class WithPgConfig(object):
@@ -409,7 +409,7 @@ def test_install_sudo(self):
self.assertCallArgs(['gksudo', '-d', 'hello world', self.make],
self.mock_popen.call_args_list[1][0][0][:4])
- @patch('pgxnclient.commands.unpack_tar')
+ @patch('pgxnclient.archive.unpack_tar')
def test_install_local_tar(self, mock_unpack):
from pgxnclient.utils.tar import unpack
mock_unpack.side_effect = unpack
@@ -428,7 +428,7 @@ def test_install_local_tar(self, mock_unpack):
self.assertEqual(zipname, get_test_filename('foobar-0.42.1.tar.gz'))
self.assertEqual(make_cwd, os.path.join(tmpdir, 'foobar-0.42.1'))
- @patch('pgxnclient.commands.unpack_zip')
+ @patch('pgxnclient.archive.unpack_zip')
def test_install_local_zip(self, mock_unpack):
from pgxnclient.utils.zip import unpack
mock_unpack.side_effect = unpack
@@ -599,7 +599,7 @@ def test_check_psql_options(self, mock_get):
args = self.mock_popen.call_args[0][0]
self.assertEqual('somewhere', args[args.index('--host') + 1])
- @patch('pgxnclient.commands.unpack_zip')
+ @patch('pgxnclient.archive.unpack_zip')
@patch('pgxnclient.api.get_file')
def test_load_local_zip(self, mock_get, mock_unpack):
mock_get.side_effect = lambda *args: self.fail('network invoked')
@@ -616,7 +616,7 @@ def test_load_local_zip(self, mock_get, mock_unpack):
self.assertEquals(communicate.call_args[0][0],
'CREATE EXTENSION foobar;')
- @patch('pgxnclient.commands.unpack_tar')
+ @patch('pgxnclient.archive.unpack_tar')
@patch('pgxnclient.api.get_file')
def test_load_local_tar(self, mock_get, mock_unpack):
mock_get.side_effect = lambda *args: self.fail('network invoked')
View
@@ -40,6 +40,9 @@ def unpack(tarname, destdir):
return destdir
+unpack_tar = unpack # utility alias
+
+
def get_meta_from_tar(filename):
try:
tf = tarfile.open(filename, 'r')
View
@@ -68,6 +68,9 @@ def unpack(zipname, destdir):
return destdir
+unpack_zip = unpack # utility alias
+
+
def get_meta_from_zip(filename):
try:
zf = ZipFile(filename, 'r')

0 comments on commit 530c853

Please sign in to comment.