summaryrefslogtreecommitdiff
path: root/pip/vcs
diff options
context:
space:
mode:
Diffstat (limited to 'pip/vcs')
-rw-r--r--pip/vcs/__init__.py38
-rw-r--r--pip/vcs/bazaar.py8
-rw-r--r--pip/vcs/git.py1
-rw-r--r--pip/vcs/subversion.py96
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)