Created
December 20, 2012 19:11
-
-
Save westurner/4347838 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
from __future__ import print_function | |
""" | |
parse_editable_url | |
""" | |
import urllib | |
import urlparse | |
import logging | |
log = logging.getLogger() | |
from collections import namedtuple | |
PkgURL = namedtuple('PkgURL', | |
('vcs','scheme','url','version','pkgname')) | |
def pkgurlstr(self): | |
return u'PkgURL%s' % str(tuple(self)) | |
PkgURL.__str__ = pkgurlstr | |
def parse_editable_url(url): | |
if not url: | |
raise Exception() | |
_url = urlparse.urlsplit(url) | |
vcs = None | |
scheme = None | |
path = None | |
version = None | |
pkgname = None | |
if _url.scheme: | |
_ = _url.scheme.split('+', 1) | |
_len = len(_) | |
if _len == 2: | |
vcs, scheme = _ | |
elif _len ==1: | |
vcs, scheme = _[0], None | |
else: | |
vcs = scheme = None | |
if _url.path: | |
atsign = _url.path.find('@') | |
hashsign = _url.path.find('#egg=', atsign > -1 and atsign-1 or 0) | |
if atsign > -1: | |
path = _url.path[0:atsign] | |
if hashsign > -1: | |
version = _url.path[atsign+1:hashsign] | |
pkgname = _url.path[hashsign+5:] | |
else: | |
version = _url.path[atsign+1:] | |
pkgname = None | |
elif atsign == -1: #@ | |
if hashsign > -1: | |
path = _url.path[0:hashsign] | |
pkgname = _url.path[hashsign+5:] | |
version = None | |
else: | |
path = _url.path | |
pkgname = None | |
version = None | |
if scheme is None and vcs is not None: | |
scheme = vcs | |
vcs = None | |
if vcs is None: | |
raise Exception() # -> default | |
if version is '': | |
version = None | |
url = u"%s://%s%s" % (scheme, _url.netloc, path) | |
return PkgURL(vcs, scheme, url, version, pkgname) | |
import unittest | |
class Test_parse_editable_url(unittest.TestCase): | |
def test_parse_editable_url(self): | |
TESTDATA = ( | |
('hg+bb://pypy/pypy', | |
PkgURL('hg', 'bb', 'bb://pypy/pypy', | |
None, None)), | |
('hg+bb+ssh://pypy/pypy', | |
PkgURL('hg', 'bb+ssh', 'bb+ssh://pypy/pypy', | |
None, None)), | |
('hg+bb+ssh://pypy/pypy@tip', | |
PkgURL('hg', 'bb+ssh', 'bb+ssh://pypy/pypy', | |
'tip', None)), | |
('hg+bb+ssh://pypy/pypy@tip#egg=pypy', | |
PkgURL('hg', 'bb+ssh', 'bb+ssh://pypy/pypy', | |
'tip', 'pypy')), | |
('hg+bb+ssh://pypy/[email protected]#egg=pypy', | |
PkgURL('hg', 'bb+ssh', 'bb+ssh://pypy/pypy', | |
'0.1', 'pypy')), | |
('hg+bb+ssh://pypy/pypy@#', | |
PkgURL('hg', 'bb+ssh', 'bb+ssh://pypy/pypy', | |
'#', None)), | |
('hg+bb+ssh://pypy/pypy#egg=pypy', | |
PkgURL('hg', 'bb+ssh', 'bb+ssh://pypy/pypy', | |
None, 'pypy')), | |
('git+https://github.com/pypa/pip', | |
PkgURL('git', 'https', 'https://github.com/pypa/pip', | |
None, None)), | |
('git+https://github.com/pypa/pip@master#egg=pip-dev', | |
PkgURL('git', 'https', 'https://github.com/pypa/pip', | |
'master', 'pip-dev')), | |
) | |
for _input, _expected_output in TESTDATA: | |
print('>> ', end='') | |
print(_input) | |
print('## ', end='') | |
print(_expected_output, end=' # expected\n') | |
output = parse_editable_url(_input) | |
print('<< ', end='') | |
print(output) | |
self.assertEqual(output, _expected_output) | |
def test_parse_editable_exceptions(self): | |
TESTDATA = ( | |
(None), | |
(''), | |
('http://bitbucket.org/pypy/pypy'), | |
) | |
for _input in TESTDATA: | |
self.assertRaises(Exception, parse_editable_url, _input) | |
def main(): | |
import optparse | |
import logging | |
prs = optparse.OptionParser(usage="./%prog : <url>") | |
prs.add_option('-v', '--verbose', | |
dest='verbose', | |
action='store_true',) | |
prs.add_option('-q', '--quiet', | |
dest='quiet', | |
action='store_true',) | |
prs.add_option('-t', '--test', | |
dest='run_tests', | |
action='store_true',) | |
(opts, args) = prs.parse_args() | |
if not opts.quiet: | |
logging.basicConfig() | |
if opts.verbose: | |
logging.getLogger().setLevel(logging.DEBUG) | |
if opts.run_tests: | |
import sys | |
sys.argv = [sys.argv[0]] + args | |
import unittest | |
exit(unittest.main()) | |
if not args: | |
exit(prs.print_help()) | |
for url in args: | |
parse_editable_url(url) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment