Skip to content

Commit

Permalink
New approach to discovery of VCS backends
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiocerqueira committed Aug 16, 2012
1 parent 3870f51 commit 1067bef
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 7 deletions.
11 changes: 11 additions & 0 deletions pip/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,14 @@ def call_subprocess(cmd, show_stdout=True,
% (command_desc, proc.returncode, cwd))
if stdout is not None:
return ''.join(all_output)

def setup_project_name(setup_py):
try:
cmd = [sys.executable, setup_py, '--name']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception:
e = sys.exc_info()[1]
logger.warn(
"Error %s while executing command %s" % (e, ' '.join(cmd)))
proc.wait()
return pkg_resources.safe_name(proc.stdout.read().strip())
10 changes: 6 additions & 4 deletions pip/vcs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@ def unregister(self, cls=None, name=None):
def get_backend_name(self, dist):
"""
Return the name of the version control backend if found at given
location, e.g. vcs.get_backend_name(dist)
pkg_resources.distribution, e.g. vcs.get_backend_name(dist)
"""
for vc_type in self._registry.values():
location = os.path.join(dist.location.split(dist.key)[0], dist.key)
path = os.path.join(location, vc_type.dirname)
if os.path.exists(path):
vc = vc_type()
if vc.check_repository(dist):
return vc_type.name
return None

Expand Down Expand Up @@ -113,6 +112,9 @@ def cmd(self):
self._cmd = command
return command

def check_repository(self, dist):
raise NotImplementedError

def get_url_rev(self):
"""
Returns the correct repository URL and revision by parsing the given
Expand Down
27 changes: 26 additions & 1 deletion pip/vcs/bazaar.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import os
import subprocess
import tempfile
import re
import sys
from pip.backwardcompat import urlparse
from pip.log import logger
from pip.util import rmtree, display_path, call_subprocess
from pip.util import rmtree, display_path, call_subprocess, setup_project_name
from pip.vcs import vcs, VersionControl
from pip.download import path_to_url2

Expand All @@ -25,6 +27,29 @@ def __init__(self, url=None, *args, **kwargs):
urlparse.uses_fragment.extend(['lp'])
urlparse.non_hierarchical.extend(['lp'])

def check_repository(self, dist):
status_error = 'bzr: ERROR: Not a branch:'
try:
cmd = [self.cmd, 'root']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=dist.location)
except Exception:
e = sys.exc_info()[1]
logger.warn(
"Error %s while executing command %s" % (e, ' '.join(cmd)))
proc.wait()
stderr = proc.stderr.read()
stdout = proc.stdout.read()
if status_error in stderr:
return False
root_path = stdout.strip()
setup_py = os.path.join(root_path, 'setup.py')
if not os.path.isfile(setup_py):
return False
if setup_project_name(setup_py) != dist.project_name:
return False
return True


def parse_vcs_bundle_file(self, content):
url = rev = None
for line in content.splitlines():
Expand Down
26 changes: 25 additions & 1 deletion pip/vcs/git.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import tempfile
import re
import os.path
from pip.util import call_subprocess
import sys
import subprocess
from pip.util import call_subprocess, setup_project_name
from pip.util import display_path, rmtree
from pip.vcs import vcs, VersionControl
from pip.log import logger
Expand Down Expand Up @@ -34,6 +36,28 @@ def __init__(self, url=None, *args, **kwargs):

super(Git, self).__init__(url, *args, **kwargs)

def check_repository(self, dist):
status_error = 'fatal: Not a git repository (or any of the parent directories): .git'
try:
cmd = [self.cmd, 'rev-parse', '--show-toplevel']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=dist.location)
except Exception:
e = sys.exc_info()[1]
logger.warn(
"Error %s while executing command %s" % (e, ' '.join(cmd)))
proc.wait()
stderr = proc.stderr.read()
stdout = proc.stdout.read()
if status_error in stderr:
return False
root_path = stdout.strip()
setup_py = os.path.join(root_path, 'setup.py')
if not os.path.isfile(setup_py):
return False
if setup_project_name(setup_py) != dist.project_name:
return False
return True

def parse_vcs_bundle_file(self, content):
url = rev = None
for line in content.splitlines():
Expand Down
26 changes: 25 additions & 1 deletion pip/vcs/mercurial.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import os
import subprocess
import tempfile
import re
import sys
from pip.util import call_subprocess
from pip.util import call_subprocess, setup_project_name
from pip.util import display_path, rmtree
from pip.log import logger
from pip.vcs import vcs, VersionControl
Expand All @@ -19,6 +20,29 @@ class Mercurial(VersionControl):
guide = ('# This was a Mercurial repo; to make it a repo again run:\n'
'hg init\nhg pull %(url)s\nhg update -r %(rev)s\n')

def check_repository(self, dist):
status_error = 'abort: no repository found in'
try:
cmd = [self.cmd, 'root']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=dist.location)
except Exception:
e = sys.exc_info()[1]
logger.warn(
"Error %s while executing command %s" % (e, ' '.join(cmd)))
proc.wait()
stderr = proc.stderr.read()
stdout = proc.stdout.read()
if status_error in stderr:
return False
root_path = stdout.strip()
setup_py = os.path.join(root_path, 'setup.py')
if not os.path.isfile(setup_py):
return False
if setup_project_name(setup_py) != dist.project_name:
return False
return True


def parse_vcs_bundle_file(self, content):
url = rev = None
for line in content.splitlines():
Expand Down
7 changes: 7 additions & 0 deletions pip/vcs/subversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ class Subversion(VersionControl):
guide = ('# This was an svn checkout; to make it a checkout again run:\n'
'svn checkout --force -r %(rev)s %(url)s .\n')

def check_repository(self, dist):
svn_path = os.path.join(dist.location, self.dirname)
if os.path.exists(svn_path) and os.path.isdir(svn_path):
return True
else:
return False

def get_info(self, location):
"""Returns (url, revision), where both are strings"""
assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location
Expand Down

0 comments on commit 1067bef

Please sign in to comment.