Skip to content

Commit

Permalink
Added support for file:// urls
Browse files Browse the repository at this point in the history
  • Loading branch information
dvarrazzo committed Sep 26, 2012
1 parent 4dc33cf commit 17dd09c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
13 changes: 8 additions & 5 deletions docs/usage.rst
Expand Up @@ -62,12 +62,15 @@ status accepted. The default is "stable".

A few commands also allow specifying a local archive or local directory
containing a distribution: in this case the specification should contain at
least a path separator to disambiguate it from a distribution name, for
instance ``pgxn install ./foo.zip``. Currently the client supports ``.zip``
and ``.tar`` archives (eventually with *gzip* and *bz2* compression).
least a path separator to disambiguate it from a distribution name (for
instance ``pgxn install ./foo.zip``) or it should be specified as an URL with
``file://`` schema.

A few commands also allow specifying a package with an URL. Currently the
schemas ``http://`` and ``https://`` are supported.
A few commands also allow specifying a remote package with a URL. Currently
the schemas ``http://`` and ``https://`` are supported.

Currently the client supports ``.zip`` and ``.tar`` archives (eventually with
*gzip* and *bz2* compression).


.. _install:
Expand Down
25 changes: 18 additions & 7 deletions pgxnclient/spec.py
Expand Up @@ -9,6 +9,7 @@

import os
import re
import urllib
import operator as _op

from pgxnclient.i18n import _
Expand Down Expand Up @@ -71,18 +72,28 @@ def parse(self, spec):
Raise BadSpecError if couldn't parse.
"""
# TODO: handle file:// too
# check if it's a network resource
if spec.startswith('http://') or spec.startswith('https://'):
return Spec(url=spec)

if os.sep in spec:
# check if it's a local resource
if spec.startswith('file://'):
try_file = urllib.unquote_plus(spec[len('file://'):])
elif os.sep in spec:
try_file = spec
else:
try_file = None

if try_file:
# This is a local thing, let's see what
if os.path.isdir(spec):
return Spec(dirname=spec)
elif os.path.exists(spec):
return Spec(filename=spec)
if os.path.isdir(try_file):
return Spec(dirname=try_file)
elif os.path.exists(try_file):
return Spec(filename=try_file)
else:
raise ResourceNotFound(_("cannot find '%s'") % spec)
raise ResourceNotFound(_("cannot find '%s'") % try_file)

# so we think it's a PGXN spec

# split operator/version and name
m = re.match(r'(.+?)(?:(==|=|>=|>|<=|<)(.*))?$', spec)
Expand Down
12 changes: 12 additions & 0 deletions pgxnclient/tests/test_commands.py
Expand Up @@ -478,6 +478,18 @@ def test_install_local_zip(self, mock_unpack):
tmpdir, = mock_unpack.call_args[0]
self.assertEqual(make_cwd, os.path.join(tmpdir, 'foobar-0.42.1'))

def test_install_url_file(self):
fn = get_test_filename('foobar-0.42.1.zip')
url = 'file://' + os.path.abspath(fn).replace("f", '%%%2x' % ord('f'))

from pgxnclient.cli import main
main(['install', '--sudo', '--', url])

self.assertEquals(self.mock_popen.call_count, 2)
self.assertCallArgs([self.make], self.mock_popen.call_args_list[0][0][0][:1])
self.assertCallArgs(['sudo', self.make],
self.mock_popen.call_args_list[1][0][0][:2])

def test_install_local_dir(self):
self.mock_get.side_effect = lambda *args: self.fail('network invoked')

Expand Down

0 comments on commit 17dd09c

Please sign in to comment.