diff options
Diffstat (limited to 'pip/vcs')
-rw-r--r-- | pip/vcs/__init__.py | 38 | ||||
-rw-r--r-- | pip/vcs/bazaar.py | 8 | ||||
-rw-r--r-- | pip/vcs/git.py | 1 | ||||
-rw-r--r-- | pip/vcs/subversion.py | 96 |
4 files changed, 93 insertions, 50 deletions
diff --git a/pip/vcs/__init__.py b/pip/vcs/__init__.py index 33c9c7c5d..a2137e96a 100644 --- a/pip/vcs/__init__.py +++ b/pip/vcs/__init__.py @@ -5,7 +5,8 @@ import shutil from pip.backwardcompat import urlparse, urllib from pip.log import logger -from pip.util import display_path, backup_dir, find_command, ask, rmtree +from pip.util import (display_path, backup_dir, find_command, + ask, rmtree, ask_path_exists) __all__ = ['vcs', 'get_src_requirement'] @@ -182,27 +183,34 @@ class VersionControl(object): if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): - logger.info('%s in %s exists, and has correct URL (%s)' - % (self.repo_name.title(), display_path(dest), url)) - logger.notify('Updating %s %s%s' - % (display_path(dest), self.repo_name, rev_display)) + logger.info('%s in %s exists, and has correct URL (%s)' % + (self.repo_name.title(), display_path(dest), + url)) + logger.notify('Updating %s %s%s' % + (display_path(dest), self.repo_name, + rev_display)) self.update(dest, rev_options) else: - logger.warn('%s %s in %s exists with URL %s' - % (self.name, self.repo_name, display_path(dest), existing_url)) - prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) + logger.warn('%s %s in %s exists with URL %s' % + (self.name, self.repo_name, + display_path(dest), existing_url)) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) else: - logger.warn('Directory %s already exists, and is not a %s %s.' - % (dest, self.name, self.repo_name)) + logger.warn('Directory %s already exists, ' + 'and is not a %s %s.' % + (dest, self.name, self.repo_name)) prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: - logger.warn('The plan is to install the %s repository %s' - % (self.name, url)) - response = ask('What to do? %s' % prompt[0], prompt[1]) + logger.warn('The plan is to install the %s repository %s' % + (self.name, url)) + response = ask_path_exists('What to do? %s' % prompt[0], + prompt[1]) if response == 's': - logger.notify('Switching %s %s to %s%s' - % (self.repo_name, display_path(dest), url, rev_display)) + logger.notify('Switching %s %s to %s%s' % + (self.repo_name, display_path(dest), url, + rev_display)) self.switch(dest, url, rev_options) elif response == 'i': # do nothing diff --git a/pip/vcs/bazaar.py b/pip/vcs/bazaar.py index 9f5389835..5d5277771 100644 --- a/pip/vcs/bazaar.py +++ b/pip/vcs/bazaar.py @@ -2,6 +2,7 @@ import os import tempfile import re from pip import call_subprocess +from pip.backwardcompat import urlparse from pip.log import logger from pip.util import rmtree, display_path from pip.vcs import vcs, VersionControl @@ -13,10 +14,15 @@ class Bazaar(VersionControl): dirname = '.bzr' repo_name = 'branch' bundle_file = 'bzr-branch.txt' - schemes = ('bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp') + schemes = ('bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', 'bzr+lp') guide = ('# This was a Bazaar branch; to make it a branch again run:\n' 'bzr branch -r %(rev)s %(url)s .\n') + def __init__(self, url=None, *args, **kwargs): + super(Bazaar, self).__init__(url, *args, **kwargs) + urlparse.non_hierarchical.extend(['lp']) + urlparse.uses_fragment.extend(['lp']) + def parse_vcs_bundle_file(self, content): url = rev = None for line in content.splitlines(): diff --git a/pip/vcs/git.py b/pip/vcs/git.py index c159d7744..ecaf19f50 100644 --- a/pip/vcs/git.py +++ b/pip/vcs/git.py @@ -8,6 +8,7 @@ from pip.backwardcompat import url2pathname, urlparse urlsplit = urlparse.urlsplit urlunsplit = urlparse.urlunsplit + class Git(VersionControl): name = 'git' dirname = '.git' diff --git a/pip/vcs/subversion.py b/pip/vcs/subversion.py index 79c31ec0e..f54eee664 100644 --- a/pip/vcs/subversion.py +++ b/pip/vcs/subversion.py @@ -1,6 +1,7 @@ import os import re -from pip import call_subprocess +from pip.backwardcompat import urlparse +from pip import call_subprocess, InstallationError from pip.index import Link from pip.util import rmtree, display_path from pip.log import logger @@ -10,6 +11,8 @@ _svn_xml_url_re = re.compile('url="([^"]+)"') _svn_rev_re = re.compile('committed-rev="(\d+)"') _svn_url_re = re.compile(r'URL: (.+)') _svn_revision_re = re.compile(r'Revision: (.+)') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') class Subversion(VersionControl): @@ -54,6 +57,7 @@ class Subversion(VersionControl): def export(self, location): """Export the svn repository at the url to the destination location""" url, rev = self.get_url_rev() + rev_options = get_rev_options(url, rev) logger.notify('Exporting svn repository %s to %s' % (url, location)) logger.indent += 2 try: @@ -62,7 +66,7 @@ class Subversion(VersionControl): # --force fixes this, but was only added in svn 1.5 rmtree(location) call_subprocess( - [self.cmd, 'export', url, location], + [self.cmd, 'export'] + rev_options + [url, location], filter_stdout=self._filter, show_stdout=False) finally: logger.indent -= 2 @@ -77,11 +81,10 @@ class Subversion(VersionControl): def obtain(self, dest): url, rev = self.get_url_rev() + rev_options = get_rev_options(url, rev) if rev: - rev_options = ['-r', rev] rev_display = ' (to revision %s)' % rev else: - rev_options = [] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Checking out %s%s to %s' @@ -119,33 +122,12 @@ class Subversion(VersionControl): if not os.path.exists(entries_fn): ## FIXME: should we warn? continue - f = open(entries_fn) - data = f.read() - f.close() - - if data.startswith('8') or data.startswith('9') or data.startswith('10'): - data = list(map(str.splitlines, data.split('\n\x0c\n'))) - del data[0][0] # get rid of the '8' - dirurl = data[0][3] - revs = [int(d[9]) for d in data if len(d)>9 and d[9]]+[0] - if revs: - localrev = max(revs) - else: - localrev = 0 - elif data.startswith('<?xml'): - dirurl = _svn_xml_url_re.search(data).group(1) # get repository URL - revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)]+[0] - if revs: - localrev = max(revs) - else: - localrev = 0 - else: - logger.warn("Unrecognized .svn/entries format; skipping %s", base) - dirs[:] = [] - continue + + dirurl, localrev = self._get_svn_url_rev(base) + if base == location: base_url = dirurl+'/' # save the root url - elif not dirurl.startswith(base_url): + elif not dirurl or not dirurl.startswith(base_url): dirs[:] = [] continue # not part of the same svn tree, skip it revision = max(revision, localrev) @@ -170,22 +152,39 @@ class Subversion(VersionControl): logger.warn("Could not find setup.py for directory %s (tried all parent directories)" % orig_location) return None + + return self._get_svn_url_rev(location)[0] + + def _get_svn_url_rev(self, location): f = open(os.path.join(location, self.dirname, 'entries')) data = f.read() f.close() if data.startswith('8') or data.startswith('9') or data.startswith('10'): data = list(map(str.splitlines, data.split('\n\x0c\n'))) del data[0][0] # get rid of the '8' - return data[0][3] + url = data[0][3] + revs = [int(d[9]) for d in data if len(d)>9 and d[9]]+[0] elif data.startswith('<?xml'): match = _svn_xml_url_re.search(data) if not match: raise ValueError('Badly formatted data: %r' % data) - return match.group(1) # get repository URL + url = match.group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)]+[0] else: - logger.warn("Unrecognized .svn/entries format in %s" % location) - # Or raise exception? - return None + try: + # subversion >= 1.7 + xml = call_subprocess([self.cmd, 'info', '--xml', location], show_stdout=False) + url = _svn_info_xml_url_re.search(xml).group(1) + revs = [int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml)] + except InstallationError: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev def get_tag_revs(self, svn_tag_url): stdout = call_subprocess( @@ -241,4 +240,33 @@ class Subversion(VersionControl): full_egg_name = '%s-dev_r%s' % (egg_project_name, rev) return 'svn+%s@%s#egg=%s' % (repo, rev, full_egg_name) + +def get_rev_options(url, rev): + if rev: + rev_options = ['-r', rev] + else: + rev_options = [] + + r = urlparse.urlsplit(url) + if hasattr(r, 'username'): + # >= Python-2.5 + username, password = r.username, r.password + else: + netloc = r[1] + if '@' in netloc: + auth = netloc.split('@')[0] + if ':' in auth: + username, password = auth.split(':', 1) + else: + username, password = auth, None + else: + username, password = None, None + + if username: + rev_options += ['--username', username] + if password: + rev_options += ['--password', password] + return rev_options + + vcs.register(Subversion) |