SEESenv/lib/python2.6/site-packages/pip-0.6.1-py2.6.egg/pip.py
author amit@thunder
Sat, 13 Feb 2010 12:29:22 +0530
changeset 3 6cee07c589cb
permissions -rw-r--r--
Changes in path of some of the files ...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     1
#!/usr/bin/env python
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     2
import sys
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     3
import os
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     4
import errno
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     5
import stat
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     6
import optparse
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     7
import pkg_resources
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     8
import urllib2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
     9
import urllib
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    10
import mimetypes
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    11
import zipfile
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    12
import tarfile
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    13
import tempfile
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    14
import subprocess
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    15
import posixpath
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    16
import re
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    17
import shutil
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    18
import fnmatch
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    19
import operator
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    20
import copy
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    21
try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    22
    from hashlib import md5
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    23
except ImportError:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    24
    import md5 as md5_module
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    25
    md5 = md5_module.new
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    26
import urlparse
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    27
from email.FeedParser import FeedParser
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    28
import traceback
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    29
from cStringIO import StringIO
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    30
import socket
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    31
from Queue import Queue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    32
from Queue import Empty as QueueEmpty
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    33
import threading
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    34
import httplib
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    35
import time
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    36
import logging
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    37
import ConfigParser
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    38
from distutils.util import strtobool
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    39
from distutils import sysconfig
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    40
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    41
class InstallationError(Exception):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    42
    """General exception during installation"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    43
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    44
class UninstallationError(Exception):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    45
    """General exception during uninstallation"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    46
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    47
class DistributionNotFound(InstallationError):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    48
    """Raised when a distribution cannot be found to satisfy a requirement"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    49
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    50
class BadCommand(Exception):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    51
    """Raised when virtualenv or a command is not found"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    52
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    53
try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    54
    any
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    55
except NameError:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    56
    def any(seq):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    57
        for item in seq:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    58
            if item:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    59
                return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    60
        return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    61
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    62
if getattr(sys, 'real_prefix', None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    63
    ## FIXME: is build/ a good name?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    64
    build_prefix = os.path.join(sys.prefix, 'build')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    65
    src_prefix = os.path.join(sys.prefix, 'src')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    66
else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    67
    ## FIXME: this isn't a very good default
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    68
    build_prefix = os.path.join(os.getcwd(), 'build')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    69
    src_prefix = os.path.join(os.getcwd(), 'src')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    70
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    71
# FIXME doesn't account for venv linked to global site-packages
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    72
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    73
site_packages = sysconfig.get_python_lib()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    74
user_dir = os.path.expanduser('~')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    75
if sys.platform == 'win32':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    76
    bin_py = os.path.join(sys.prefix, 'Scripts')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    77
    # buildout uses 'bin' on Windows too?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    78
    if not os.path.exists(bin_py):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    79
        bin_py = os.path.join(sys.prefix, 'bin')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    80
    config_dir = os.environ.get('APPDATA', user_dir) # Use %APPDATA% for roaming
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    81
    default_config_file = os.path.join(config_dir, 'pip', 'pip.ini')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    82
else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    83
    bin_py = os.path.join(sys.prefix, 'bin')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    84
    default_config_file = os.path.join(user_dir, '.pip', 'pip.conf')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    85
    # Forcing to use /usr/local/bin for standard Mac OS X framework installs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    86
    if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    87
        bin_py = '/usr/local/bin'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    88
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    89
class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    90
    """Custom help formatter for use in ConfigOptionParser that updates
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    91
    the defaults before expanding them, allowing them to show up correctly
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    92
    in the help listing"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    93
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    94
    def expand_default(self, option):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    95
        if self.parser is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    96
            self.parser.update_defaults(self.parser.defaults)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    97
        return optparse.IndentedHelpFormatter.expand_default(self, option)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    98
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
    99
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   100
class ConfigOptionParser(optparse.OptionParser):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   101
    """Custom option parser which updates its defaults by by checking the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   102
    configuration files and environmental variables"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   103
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   104
    def __init__(self, *args, **kwargs):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   105
        self.config = ConfigParser.RawConfigParser()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   106
        self.name = kwargs.pop('name')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   107
        self.files = self.get_config_files()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   108
        self.config.read(self.files)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   109
        assert self.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   110
        optparse.OptionParser.__init__(self, *args, **kwargs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   111
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   112
    def get_config_files(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   113
        config_file = os.environ.get('PIP_CONFIG_FILE', False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   114
        if config_file and os.path.exists(config_file):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   115
            return [config_file]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   116
        return [default_config_file]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   117
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   118
    def update_defaults(self, defaults):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   119
        """Updates the given defaults with values from the config files and
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   120
        the environ. Does a little special handling for certain types of
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   121
        options (lists)."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   122
        # Then go and look for the other sources of configuration:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   123
        config = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   124
        # 1. config files
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   125
        for section in ('global', self.name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   126
            config.update(dict(self.get_config_section(section)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   127
        # 2. environmental variables
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   128
        config.update(dict(self.get_environ_vars()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   129
        # Then set the options with those values
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   130
        for key, val in config.iteritems():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   131
            key = key.replace('_', '-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   132
            if not key.startswith('--'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   133
                key = '--%s' % key # only prefer long opts
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   134
            option = self.get_option(key)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   135
            if option is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   136
                # ignore empty values
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   137
                if not val:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   138
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   139
                # handle multiline configs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   140
                if option.action == 'append':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   141
                    val = val.split()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   142
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   143
                    option.nargs = 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   144
                if option.action in ('store_true', 'store_false', 'count'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   145
                    val = strtobool(val)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   146
                try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   147
                    val = option.convert_value(key, val)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   148
                except optparse.OptionValueError, e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   149
                    print ("An error occured during configuration: %s" % e)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   150
                    sys.exit(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   151
                defaults[option.dest] = val
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   152
        return defaults
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   153
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   154
    def get_config_section(self, name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   155
        """Get a section of a configuration"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   156
        if self.config.has_section(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   157
            return self.config.items(name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   158
        return []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   159
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   160
    def get_environ_vars(self, prefix='PIP_'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   161
        """Returns a generator with all environmental vars with prefix PIP_"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   162
        for key, val in os.environ.iteritems():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   163
            if key.startswith(prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   164
                yield (key.replace(prefix, '').lower(), val)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   165
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   166
    def get_default_values(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   167
        """Overridding to make updating the defaults after instantiation of
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   168
        the option parser possible, update_defaults() does the dirty work."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   169
        if not self.process_default_values:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   170
            # Old, pre-Optik 1.5 behaviour.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   171
            return optparse.Values(self.defaults)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   172
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   173
        defaults = self.update_defaults(self.defaults.copy()) # ours
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   174
        for option in self._get_all_options():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   175
            default = defaults.get(option.dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   176
            if isinstance(default, basestring):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   177
                opt_str = option.get_opt_string()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   178
                defaults[option.dest] = option.check_value(opt_str, default)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   179
        return optparse.Values(defaults)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   180
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   181
try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   182
    pip_dist = pkg_resources.get_distribution('pip')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   183
    version = '%s from %s (python %s)' % (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   184
        pip_dist, pip_dist.location, sys.version[:3])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   185
except pkg_resources.DistributionNotFound:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   186
    # when running pip.py without installing
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   187
    version=None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   188
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   189
def rmtree_errorhandler(func, path, exc_info):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   190
    """On Windows, the files in .svn are read-only, so when rmtree() tries to
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   191
    remove them, an exception is thrown.  We catch that here, remove the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   192
    read-only attribute, and hopefully continue without problems."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   193
    exctype, value = exc_info[:2]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   194
    # lookin for a windows error
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   195
    if exctype is not WindowsError or 'Access is denied' not in str(value):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   196
        raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   197
    # file type should currently be read only
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   198
    if ((os.stat(path).st_mode & stat.S_IREAD) != stat.S_IREAD):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   199
        raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   200
    # convert to read/write
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   201
    os.chmod(path, stat.S_IWRITE)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   202
    # use the original function to repeat the operation
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   203
    func(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   204
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   205
class VcsSupport(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   206
    _registry = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   207
    schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   208
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   209
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   210
        # Register more schemes with urlparse for various version control systems
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   211
        urlparse.uses_netloc.extend(self.schemes)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   212
        urlparse.uses_fragment.extend(self.schemes)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   213
        super(VcsSupport, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   214
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   215
    def __iter__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   216
        return self._registry.__iter__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   217
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   218
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   219
    def backends(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   220
        return self._registry.values()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   221
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   222
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   223
    def dirnames(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   224
        return [backend.dirname for backend in self.backends]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   225
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   226
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   227
    def all_schemes(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   228
        schemes = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   229
        for backend in self.backends:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   230
            schemes.extend(backend.schemes)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   231
        return schemes
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   232
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   233
    def register(self, cls):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   234
        if not hasattr(cls, 'name'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   235
            logger.warn('Cannot register VCS %s' % cls.__name__)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   236
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   237
        if cls.name not in self._registry:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   238
            self._registry[cls.name] = cls
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   239
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   240
    def unregister(self, cls=None, name=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   241
        if name in self._registry:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   242
            del self._registry[name]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   243
        elif cls in self._registry.values():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   244
            del self._registry[cls.name]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   245
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   246
            logger.warn('Cannot unregister because no class or name given')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   247
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   248
    def get_backend_name(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   249
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   250
        Return the name of the version control backend if found at given
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   251
        location, e.g. vcs.get_backend_name('/path/to/vcs/checkout')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   252
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   253
        for vc_type in self._registry.values():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   254
            path = os.path.join(location, vc_type.dirname)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   255
            if os.path.exists(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   256
                return vc_type.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   257
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   258
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   259
    def get_backend(self, name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   260
        name = name.lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   261
        if name in self._registry:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   262
            return self._registry[name]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   263
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   264
    def get_backend_from_location(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   265
        vc_type = self.get_backend_name(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   266
        if vc_type:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   267
            return self.get_backend(vc_type)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   268
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   269
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   270
vcs = VcsSupport()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   271
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   272
parser = ConfigOptionParser(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   273
    usage='%prog COMMAND [OPTIONS]',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   274
    version=version,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   275
    add_help_option=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   276
    formatter=UpdatingDefaultsHelpFormatter(),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   277
    name='global')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   278
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   279
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   280
    '-h', '--help',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   281
    dest='help',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   282
    action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   283
    help='Show help')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   284
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   285
    '-E', '--environment',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   286
    dest='venv',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   287
    metavar='DIR',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   288
    help='virtualenv environment to run pip in (either give the '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   289
    'interpreter or the environment base directory)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   290
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   291
    '-s', '--enable-site-packages',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   292
    dest='site_packages',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   293
    action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   294
    help='Include site-packages in virtualenv if one is to be '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   295
    'created. Ignored if --environment is not used or '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   296
    'the virtualenv already exists.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   297
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   298
    # Defines a default root directory for virtualenvs, relative
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   299
    # virtualenvs names/paths are considered relative to it.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   300
    '--virtualenv-base',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   301
    dest='venv_base',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   302
    type='str',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   303
    default='',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   304
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   305
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   306
    # Run only if inside a virtualenv, bail if not.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   307
    '--require-virtualenv', '--require-venv',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   308
    dest='require_venv',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   309
    action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   310
    default=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   311
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   312
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   313
    # Use automatically an activated virtualenv instead of installing
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   314
    # globally. -E will be ignored if used.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   315
    '--respect-virtualenv', '--respect-venv',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   316
    dest='respect_venv',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   317
    action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   318
    default=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   319
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   320
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   321
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   322
    '-v', '--verbose',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   323
    dest='verbose',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   324
    action='count',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   325
    default=0,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   326
    help='Give more output')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   327
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   328
    '-q', '--quiet',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   329
    dest='quiet',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   330
    action='count',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   331
    default=0,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   332
    help='Give less output')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   333
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   334
    '--log',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   335
    dest='log',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   336
    metavar='FILENAME',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   337
    help='Log file where a complete (maximum verbosity) record will be kept')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   338
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   339
    # Writes the log levels explicitely to the log'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   340
    '--log-explicit-levels',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   341
    dest='log_explicit_levels',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   342
    action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   343
    default=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   344
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   345
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   346
    # The default log file
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   347
    '--local-log', '--log-file',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   348
    dest='log_file',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   349
    metavar='FILENAME',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   350
    default='./pip-log.txt',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   351
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   352
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   353
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   354
    '--proxy',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   355
    dest='proxy',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   356
    type='str',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   357
    default='',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   358
    help="Specify a proxy in the form user:passwd@proxy.server:port. "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   359
    "Note that the user:password@ is optional and required only if you "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   360
    "are behind an authenticated proxy.  If you provide "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   361
    "user@proxy.server:port then you will be prompted for a password.")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   362
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   363
    '--timeout', '--default-timeout',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   364
    metavar='SECONDS',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   365
    dest='timeout',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   366
    type='float',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   367
    default=15,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   368
    help='Set the socket timeout (default %default seconds)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   369
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   370
    # The default version control system for editables, e.g. 'svn'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   371
    '--default-vcs',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   372
    dest='default_vcs',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   373
    type='str',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   374
    default='',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   375
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   376
parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   377
    # A regex to be used to skip requirements
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   378
    '--skip-requirements-regex',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   379
    dest='skip_requirements_regex',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   380
    type='str',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   381
    default='',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   382
    help=optparse.SUPPRESS_HELP)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   383
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   384
parser.disable_interspersed_args()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   385
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   386
_commands = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   387
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   388
class Command(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   389
    name = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   390
    usage = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   391
    hidden = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   392
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   393
        assert self.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   394
        self.parser = ConfigOptionParser(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   395
            usage=self.usage,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   396
            prog='%s %s' % (sys.argv[0], self.name),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   397
            version=parser.version,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   398
            formatter=UpdatingDefaultsHelpFormatter(),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   399
            name=self.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   400
        for option in parser.option_list:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   401
            if not option.dest or option.dest == 'help':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   402
                # -h, --version, etc
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   403
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   404
            self.parser.add_option(option)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   405
        _commands[self.name] = self
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   406
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   407
    def merge_options(self, initial_options, options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   408
        # Make sure we have all global options carried over
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   409
        for attr in ['log', 'venv', 'proxy', 'venv_base', 'require_venv',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   410
                     'respect_venv', 'log_explicit_levels', 'log_file',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   411
                     'timeout', 'default_vcs', 'skip_requirements_regex']:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   412
            setattr(options, attr, getattr(initial_options, attr) or getattr(options, attr))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   413
        options.quiet += initial_options.quiet
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   414
        options.verbose += initial_options.verbose
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   415
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   416
    def main(self, complete_args, args, initial_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   417
        global logger
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   418
        options, args = self.parser.parse_args(args)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   419
        self.merge_options(initial_options, options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   420
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   421
        if options.require_venv and not options.venv:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   422
            # If a venv is required check if it can really be found
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   423
            if not os.environ.get('VIRTUAL_ENV'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   424
                print 'Could not find an activated virtualenv (required).'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   425
                sys.exit(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   426
            # Automatically install in currently activated venv if required
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   427
            options.respect_venv = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   428
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   429
        if args and args[-1] == '___VENV_RESTART___':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   430
            ## FIXME: We don't do anything this this value yet:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   431
            venv_location = args[-2]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   432
            args = args[:-2]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   433
            options.venv = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   434
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   435
            # If given the option to respect the activated environment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   436
            # check if no venv is given as a command line parameter
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   437
            if options.respect_venv and os.environ.get('VIRTUAL_ENV'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   438
                if options.venv and os.path.exists(options.venv):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   439
                    # Make sure command line venv and environmental are the same
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   440
                    if (os.path.realpath(os.path.expanduser(options.venv)) !=
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   441
                            os.path.realpath(os.environ.get('VIRTUAL_ENV'))):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   442
                        print ("Given virtualenv (%s) doesn't match "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   443
                               "currently activated virtualenv (%s)."
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   444
                               % (options.venv, os.environ.get('VIRTUAL_ENV')))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   445
                        sys.exit(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   446
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   447
                    options.venv = os.environ.get('VIRTUAL_ENV')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   448
                    print 'Using already activated environment %s' % options.venv
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   449
        level = 1 # Notify
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   450
        level += options.verbose
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   451
        level -= options.quiet
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   452
        level = Logger.level_for_integer(4-level)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   453
        complete_log = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   454
        logger = Logger([(level, sys.stdout),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   455
                         (Logger.DEBUG, complete_log.append)])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   456
        if options.log_explicit_levels:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   457
            logger.explicit_levels = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   458
        if options.venv:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   459
            if options.verbose > 0:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   460
                # The logger isn't setup yet
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   461
                print 'Running in environment %s' % options.venv
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   462
            site_packages=False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   463
            if options.site_packages:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   464
                site_packages=True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   465
            restart_in_venv(options.venv, options.venv_base, site_packages,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   466
                            complete_args)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   467
            # restart_in_venv should actually never return, but for clarity...
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   468
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   469
        ## FIXME: not sure if this sure come before or after venv restart
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   470
        if options.log:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   471
            log_fp = open_logfile_append(options.log)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   472
            logger.consumers.append((logger.DEBUG, log_fp))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   473
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   474
            log_fp = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   475
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   476
        socket.setdefaulttimeout(options.timeout or None)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   477
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   478
        setup_proxy_handler(options.proxy)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   479
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   480
        exit = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   481
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   482
            self.run(options, args)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   483
        except (InstallationError, UninstallationError), e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   484
            logger.fatal(str(e))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   485
            logger.info('Exception information:\n%s' % format_exc())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   486
            exit = 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   487
        except:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   488
            logger.fatal('Exception:\n%s' % format_exc())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   489
            exit = 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   490
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   491
        if log_fp is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   492
            log_fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   493
        if exit:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   494
            log_fn = options.log_file
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   495
            text = '\n'.join(complete_log)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   496
            logger.fatal('Storing complete log in %s' % log_fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   497
            log_fp = open_logfile_append(log_fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   498
            log_fp.write(text)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   499
            log_fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   500
        return exit
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   501
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   502
class HelpCommand(Command):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   503
    name = 'help'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   504
    usage = '%prog'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   505
    summary = 'Show available commands'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   506
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   507
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   508
        if args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   509
            ## FIXME: handle errors better here
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   510
            command = args[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   511
            if command not in _commands:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   512
                raise InstallationError('No command with the name: %s' % command)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   513
            command = _commands[command]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   514
            command.parser.print_help()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   515
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   516
        parser.print_help()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   517
        print
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   518
        print 'Commands available:'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   519
        commands = list(set(_commands.values()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   520
        commands.sort(key=lambda x: x.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   521
        for command in commands:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   522
            if command.hidden:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   523
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   524
            print '  %s: %s' % (command.name, command.summary)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   525
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   526
HelpCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   527
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   528
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   529
class InstallCommand(Command):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   530
    name = 'install'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   531
    usage = '%prog [OPTIONS] PACKAGE_NAMES...'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   532
    summary = 'Install packages'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   533
    bundle = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   534
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   535
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   536
        super(InstallCommand, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   537
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   538
            '-e', '--editable',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   539
            dest='editables',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   540
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   541
            default=[],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   542
            metavar='VCS+REPOS_URL[@REV]#egg=PACKAGE',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   543
            help='Install a package directly from a checkout. Source will be checked '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   544
            'out into src/PACKAGE (lower-case) and installed in-place (using '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   545
            'setup.py develop). You can run this on an existing directory/checkout (like '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   546
            'pip install -e src/mycheckout). This option may be provided multiple times. '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   547
            'Possible values for VCS are: svn, git, hg and bzr.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   548
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   549
            '-r', '--requirement',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   550
            dest='requirements',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   551
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   552
            default=[],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   553
            metavar='FILENAME',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   554
            help='Install all the packages listed in the given requirements file.  '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   555
            'This option can be used multiple times.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   556
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   557
            '-f', '--find-links',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   558
            dest='find_links',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   559
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   560
            default=[],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   561
            metavar='URL',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   562
            help='URL to look for packages at')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   563
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   564
            '-i', '--index-url', '--pypi-url',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   565
            dest='index_url',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   566
            metavar='URL',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   567
            default='http://pypi.python.org/simple',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   568
            help='Base URL of Python Package Index (default %default)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   569
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   570
            '--extra-index-url',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   571
            dest='extra_index_urls',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   572
            metavar='URL',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   573
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   574
            default=[],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   575
            help='Extra URLs of package indexes to use in addition to --index-url')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   576
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   577
            '--no-index',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   578
            dest='no_index',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   579
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   580
            default=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   581
            help='Ignore package index (only looking at --find-links URLs instead)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   582
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   583
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   584
            '-b', '--build', '--build-dir', '--build-directory',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   585
            dest='build_dir',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   586
            metavar='DIR',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   587
            default=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   588
            help='Unpack packages into DIR (default %s) and build from there' % build_prefix)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   589
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   590
            '-d', '--download', '--download-dir', '--download-directory',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   591
            dest='download_dir',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   592
            metavar='DIR',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   593
            default=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   594
            help='Download packages into DIR instead of installing them')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   595
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   596
            '--download-cache',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   597
            dest='download_cache',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   598
            metavar='DIR',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   599
            default=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   600
            help='Cache downloaded packages in DIR')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   601
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   602
            '--src', '--source', '--source-dir', '--source-directory',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   603
            dest='src_dir',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   604
            metavar='DIR',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   605
            default=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   606
            help='Check out --editable packages into DIR (default %s)' % src_prefix)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   607
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   608
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   609
            '-U', '--upgrade',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   610
            dest='upgrade',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   611
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   612
            help='Upgrade all packages to the newest available version')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   613
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   614
            '-I', '--ignore-installed',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   615
            dest='ignore_installed',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   616
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   617
            help='Ignore the installed packages (reinstalling instead)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   618
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   619
            '--no-deps', '--no-dependencies',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   620
            dest='ignore_dependencies',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   621
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   622
            default=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   623
            help='Ignore package dependencies')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   624
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   625
            '--no-install',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   626
            dest='no_install',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   627
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   628
            help="Download and unpack all packages, but don't actually install them")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   629
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   630
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   631
            '--install-option',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   632
            dest='install_options',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   633
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   634
            help="Extra arguments to be supplied to the setup.py install "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   635
            "command (use like --install-option=\"--install-scripts=/usr/local/bin\").  "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   636
            "Use multiple --install-option options to pass multiple options to setup.py install.  "
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   637
            "If you are using an option with a directory path, be sure to use absolute path.")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   638
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   639
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   640
        if not options.build_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   641
            options.build_dir = build_prefix
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   642
        if not options.src_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   643
            options.src_dir = src_prefix
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   644
        if options.download_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   645
            options.no_install = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   646
            options.ignore_installed = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   647
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   648
            options.build_dir = os.path.abspath(options.build_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   649
            options.src_dir = os.path.abspath(options.src_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   650
        install_options = options.install_options or []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   651
        index_urls = [options.index_url] + options.extra_index_urls
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   652
        if options.no_index:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   653
            logger.notify('Ignoring indexes: %s' % ','.join(index_urls))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   654
            index_urls = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   655
        finder = PackageFinder(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   656
            find_links=options.find_links,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   657
            index_urls=index_urls)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   658
        requirement_set = RequirementSet(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   659
            build_dir=options.build_dir,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   660
            src_dir=options.src_dir,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   661
            download_dir=options.download_dir,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   662
            download_cache=options.download_cache,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   663
            upgrade=options.upgrade,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   664
            ignore_installed=options.ignore_installed,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   665
            ignore_dependencies=options.ignore_dependencies)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   666
        for name in args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   667
            requirement_set.add_requirement(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   668
                InstallRequirement.from_line(name, None))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   669
        for name in options.editables:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   670
            requirement_set.add_requirement(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   671
                InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   672
        for filename in options.requirements:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   673
            for req in parse_requirements(filename, finder=finder, options=options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   674
                requirement_set.add_requirement(req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   675
        requirement_set.install_files(finder, force_root_egg_info=self.bundle)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   676
        if not options.no_install and not self.bundle:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   677
            requirement_set.install(install_options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   678
            installed = ' '.join([req.name for req in
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   679
                                  requirement_set.successfully_installed])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   680
            if installed:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   681
                logger.notify('Successfully installed %s' % installed)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   682
        elif not self.bundle:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   683
            downloaded = ' '.join([req.name for req in
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   684
                                   requirement_set.successfully_downloaded])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   685
            if downloaded:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   686
                logger.notify('Successfully downloaded %s' % downloaded)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   687
        return requirement_set
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   688
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   689
InstallCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   690
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   691
class UninstallCommand(Command):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   692
    name = 'uninstall'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   693
    usage = '%prog [OPTIONS] PACKAGE_NAMES ...'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   694
    summary = 'Uninstall packages'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   695
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   696
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   697
        super(UninstallCommand, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   698
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   699
            '-r', '--requirement',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   700
            dest='requirements',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   701
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   702
            default=[],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   703
            metavar='FILENAME',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   704
            help='Uninstall all the packages listed in the given requirements file.  '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   705
            'This option can be used multiple times.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   706
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   707
            '-y', '--yes',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   708
            dest='yes',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   709
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   710
            help="Don't ask for confirmation of uninstall deletions.")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   711
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   712
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   713
        requirement_set = RequirementSet(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   714
            build_dir=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   715
            src_dir=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   716
            download_dir=None)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   717
        for name in args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   718
            requirement_set.add_requirement(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   719
                InstallRequirement.from_line(name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   720
        for filename in options.requirements:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   721
            for req in parse_requirements(filename, options=options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   722
                requirement_set.add_requirement(req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   723
        requirement_set.uninstall(auto_confirm=options.yes)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   724
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   725
UninstallCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   726
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   727
class BundleCommand(InstallCommand):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   728
    name = 'bundle'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   729
    usage = '%prog [OPTIONS] BUNDLE_NAME.pybundle PACKAGE_NAMES...'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   730
    summary = 'Create pybundles (archives containing multiple packages)'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   731
    bundle = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   732
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   733
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   734
        super(BundleCommand, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   735
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   736
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   737
        if not args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   738
            raise InstallationError('You must give a bundle filename')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   739
        if not options.build_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   740
            options.build_dir = backup_dir(build_prefix, '-bundle')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   741
        if not options.src_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   742
            options.src_dir = backup_dir(src_prefix, '-bundle')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   743
        # We have to get everything when creating a bundle:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   744
        options.ignore_installed = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   745
        logger.notify('Putting temporary build files in %s and source/develop files in %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   746
                      % (display_path(options.build_dir), display_path(options.src_dir)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   747
        bundle_filename = args[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   748
        args = args[1:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   749
        requirement_set = super(BundleCommand, self).run(options, args)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   750
        # FIXME: here it has to do something
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   751
        requirement_set.create_bundle(bundle_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   752
        logger.notify('Created bundle in %s' % bundle_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   753
        return requirement_set
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   754
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   755
BundleCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   756
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   757
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   758
class FreezeCommand(Command):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   759
    name = 'freeze'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   760
    usage = '%prog [OPTIONS]'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   761
    summary = 'Output all currently installed packages (exact versions) to stdout'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   762
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   763
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   764
        super(FreezeCommand, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   765
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   766
            '-r', '--requirement',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   767
            dest='requirement',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   768
            action='store',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   769
            default=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   770
            metavar='FILENAME',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   771
            help='Use the given requirements file as a hint about how to generate the new frozen requirements')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   772
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   773
            '-f', '--find-links',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   774
            dest='find_links',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   775
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   776
            default=[],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   777
            metavar='URL',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   778
            help='URL for finding packages, which will be added to the frozen requirements file')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   779
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   780
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   781
        requirement = options.requirement
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   782
        find_links = options.find_links or []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   783
        ## FIXME: Obviously this should be settable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   784
        find_tags = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   785
        skip_match = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   786
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   787
        skip_regex = options.skip_requirements_regex
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   788
        if skip_regex:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   789
            skip_match = re.compile(skip_regex)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   790
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   791
        logger.move_stdout_to_stderr()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   792
        dependency_links = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   793
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   794
        f = sys.stdout
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   795
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   796
        for dist in pkg_resources.working_set:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   797
            if dist.has_metadata('dependency_links.txt'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   798
                dependency_links.extend(dist.get_metadata_lines('dependency_links.txt'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   799
        for link in find_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   800
            if '#egg=' in link:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   801
                dependency_links.append(link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   802
        for link in find_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   803
            f.write('-f %s\n' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   804
        installations = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   805
        for dist in pkg_resources.working_set:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   806
            if dist.key in ('setuptools', 'pip', 'python'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   807
                ## FIXME: also skip virtualenv?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   808
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   809
            req = FrozenRequirement.from_dist(dist, dependency_links, find_tags=find_tags)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   810
            installations[req.name] = req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   811
        if requirement:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   812
            req_f = open(requirement)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   813
            for line in req_f:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   814
                if not line.strip() or line.strip().startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   815
                    f.write(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   816
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   817
                if skip_match and skip_match.search(line):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   818
                    f.write(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   819
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   820
                elif line.startswith('-e') or line.startswith('--editable'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   821
                    if line.startswith('-e'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   822
                        line = line[2:].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   823
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   824
                        line = line[len('--editable'):].strip().lstrip('=')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   825
                    line_req = InstallRequirement.from_editable(line, default_vcs=options.default_vcs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   826
                elif (line.startswith('-r') or line.startswith('--requirement')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   827
                      or line.startswith('-Z') or line.startswith('--always-unzip')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   828
                    logger.debug('Skipping line %r' % line.strip())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   829
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   830
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   831
                    line_req = InstallRequirement.from_line(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   832
                if not line_req.name:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   833
                    logger.notify("Skipping line because it's not clear what it would install: %s"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   834
                                  % line.strip())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   835
                    logger.notify("  (add #egg=PackageName to the URL to avoid this warning)")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   836
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   837
                if line_req.name not in installations:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   838
                    logger.warn("Requirement file contains %s, but that package is not installed"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   839
                                % line.strip())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   840
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   841
                f.write(str(installations[line_req.name]))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   842
                del installations[line_req.name]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   843
            f.write('## The following requirements were added by pip --freeze:\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   844
        for installation in sorted(installations.values(), key=lambda x: x.name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   845
            f.write(str(installation))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   846
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   847
FreezeCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   848
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   849
class ZipCommand(Command):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   850
    name = 'zip'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   851
    usage = '%prog [OPTIONS] PACKAGE_NAMES...'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   852
    summary = 'Zip individual packages'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   853
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   854
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   855
        super(ZipCommand, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   856
        if self.name == 'zip':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   857
            self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   858
                '--unzip',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   859
                action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   860
                dest='unzip',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   861
                help='Unzip (rather than zip) a package')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   862
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   863
            self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   864
                '--zip',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   865
                action='store_false',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   866
                dest='unzip',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   867
                default=True,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   868
                help='Zip (rather than unzip) a package')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   869
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   870
            '--no-pyc',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   871
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   872
            dest='no_pyc',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   873
            help='Do not include .pyc files in zip files (useful on Google App Engine)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   874
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   875
            '-l', '--list',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   876
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   877
            dest='list',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   878
            help='List the packages available, and their zip status')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   879
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   880
            '--sort-files',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   881
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   882
            dest='sort_files',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   883
            help='With --list, sort packages according to how many files they contain')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   884
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   885
            '--path',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   886
            action='append',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   887
            dest='paths',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   888
            help='Restrict operations to the given paths (may include wildcards)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   889
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   890
            '-n', '--simulate',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   891
            action='store_true',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   892
            help='Do not actually perform the zip/unzip operation')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   893
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   894
    def paths(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   895
        """All the entries of sys.path, possibly restricted by --path"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   896
        if not self.select_paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   897
            return sys.path
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   898
        result = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   899
        match_any = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   900
        for path in sys.path:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   901
            path = os.path.normcase(os.path.abspath(path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   902
            for match in self.select_paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   903
                match = os.path.normcase(os.path.abspath(match))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   904
                if '*' in match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   905
                    if re.search(fnmatch.translate(match+'*'), path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   906
                        result.append(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   907
                        match_any.add(match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   908
                        break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   909
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   910
                    if path.startswith(match):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   911
                        result.append(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   912
                        match_any.add(match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   913
                        break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   914
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   915
                logger.debug("Skipping path %s because it doesn't match %s"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   916
                             % (path, ', '.join(self.select_paths)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   917
        for match in self.select_paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   918
            if match not in match_any and '*' not in match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   919
                result.append(match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   920
                logger.debug("Adding path %s because it doesn't match anything already on sys.path"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   921
                             % match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   922
        return result
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   923
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   924
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   925
        self.select_paths = options.paths
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   926
        self.simulate = options.simulate
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   927
        if options.list:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   928
            return self.list(options, args)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   929
        if not args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   930
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   931
                'You must give at least one package to zip or unzip')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   932
        packages = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   933
        for arg in args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   934
            module_name, filename = self.find_package(arg)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   935
            if options.unzip and os.path.isdir(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   936
                raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   937
                    'The module %s (in %s) is not a zip file; cannot be unzipped'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   938
                    % (module_name, filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   939
            elif not options.unzip and not os.path.isdir(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   940
                raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   941
                    'The module %s (in %s) is not a directory; cannot be zipped'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   942
                    % (module_name, filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   943
            packages.append((module_name, filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   944
        last_status = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   945
        for module_name, filename in packages:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   946
            if options.unzip:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   947
                last_status = self.unzip_package(module_name, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   948
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   949
                last_status = self.zip_package(module_name, filename, options.no_pyc)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   950
        return last_status
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   951
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   952
    def unzip_package(self, module_name, filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   953
        zip_filename = os.path.dirname(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   954
        if not os.path.isfile(zip_filename) and zipfile.is_zipfile(zip_filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   955
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   956
                'Module %s (in %s) isn\'t located in a zip file in %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   957
                % (module_name, filename, zip_filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   958
        package_path = os.path.dirname(zip_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   959
        if not package_path in self.paths():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   960
            logger.warn(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   961
                'Unpacking %s into %s, but %s is not on sys.path'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   962
                % (display_path(zip_filename), display_path(package_path),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   963
                   display_path(package_path)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   964
        logger.notify('Unzipping %s (in %s)' % (module_name, display_path(zip_filename)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   965
        if self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   966
            logger.notify('Skipping remaining operations because of --simulate')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   967
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   968
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   969
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   970
            ## FIXME: this should be undoable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   971
            zip = zipfile.ZipFile(zip_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   972
            to_save = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   973
            for name in zip.namelist():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   974
                if name.startswith('%s/' % module_name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   975
                    content = zip.read(name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   976
                    dest = os.path.join(package_path, name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   977
                    if not os.path.exists(os.path.dirname(dest)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   978
                        os.makedirs(os.path.dirname(dest))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   979
                    if not content and dest.endswith('/'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   980
                        if not os.path.exists(dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   981
                            os.makedirs(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   982
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   983
                        f = open(dest, 'wb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   984
                        f.write(content)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   985
                        f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   986
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   987
                    to_save.append((name, zip.read(name)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   988
            zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   989
            if not to_save:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   990
                logger.info('Removing now-empty zip file %s' % display_path(zip_filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   991
                os.unlink(zip_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   992
                self.remove_filename_from_pth(zip_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   993
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   994
                logger.info('Removing entries in %s/ from zip file %s' % (module_name, display_path(zip_filename)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   995
                zip = zipfile.ZipFile(zip_filename, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   996
                for name, content in to_save:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   997
                    zip.writestr(name, content)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   998
                zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
   999
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1000
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1001
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1002
    def zip_package(self, module_name, filename, no_pyc):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1003
        orig_filename = filename
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1004
        logger.notify('Zip %s (in %s)' % (module_name, display_path(filename)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1005
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1006
        if filename.endswith('.egg'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1007
            dest_filename = filename
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1008
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1009
            dest_filename = filename + '.zip'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1010
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1011
            ## FIXME: I think this needs to be undoable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1012
            if filename == dest_filename:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1013
                filename = backup_dir(orig_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1014
                logger.notify('Moving %s aside to %s' % (orig_filename, filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1015
                if not self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1016
                    shutil.move(orig_filename, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1017
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1018
                logger.info('Creating zip file in %s' % display_path(dest_filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1019
                if not self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1020
                    zip = zipfile.ZipFile(dest_filename, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1021
                    zip.writestr(module_name + '/', '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1022
                    for dirpath, dirnames, filenames in os.walk(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1023
                        if no_pyc:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1024
                            filenames = [f for f in filenames
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1025
                                         if not f.lower().endswith('.pyc')]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1026
                        for fns, is_dir in [(dirnames, True), (filenames, False)]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1027
                            for fn in fns:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1028
                                full = os.path.join(dirpath, fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1029
                                dest = os.path.join(module_name, dirpath[len(filename):].lstrip(os.path.sep), fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1030
                                if is_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1031
                                    zip.writestr(dest+'/', '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1032
                                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1033
                                    zip.write(full, dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1034
                    zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1035
                logger.info('Removing old directory %s' % display_path(filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1036
                if not self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1037
                    shutil.rmtree(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1038
            except:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1039
                ## FIXME: need to do an undo here
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1040
                raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1041
            ## FIXME: should also be undone:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1042
            self.add_filename_to_pth(dest_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1043
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1044
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1045
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1046
    def remove_filename_from_pth(self, filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1047
        for pth in self.pth_files():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1048
            f = open(pth, 'r')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1049
            lines = f.readlines()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1050
            f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1051
            new_lines = [
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1052
                l for l in lines if l.strip() != filename]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1053
            if lines != new_lines:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1054
                logger.info('Removing reference to %s from .pth file %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1055
                            % (display_path(filename), display_path(pth)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1056
                if not filter(None, new_lines):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1057
                    logger.info('%s file would be empty: deleting' % display_path(pth))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1058
                    if not self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1059
                        os.unlink(pth)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1060
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1061
                    if not self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1062
                        f = open(pth, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1063
                        f.writelines(new_lines)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1064
                        f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1065
                return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1066
        logger.warn('Cannot find a reference to %s in any .pth file' % display_path(filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1067
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1068
    def add_filename_to_pth(self, filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1069
        path = os.path.dirname(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1070
        dest = os.path.join(path, filename + '.pth')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1071
        if path not in self.paths():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1072
            logger.warn('Adding .pth file %s, but it is not on sys.path' % display_path(dest))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1073
        if not self.simulate:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1074
            if os.path.exists(dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1075
                f = open(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1076
                lines = f.readlines()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1077
                f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1078
                if lines and not lines[-1].endswith('\n'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1079
                    lines[-1] += '\n'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1080
                lines.append(filename+'\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1081
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1082
                lines = [filename + '\n']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1083
            f = open(dest, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1084
            f.writelines(lines)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1085
            f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1086
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1087
    def pth_files(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1088
        for path in self.paths():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1089
            if not os.path.exists(path) or not os.path.isdir(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1090
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1091
            for filename in os.listdir(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1092
                if filename.endswith('.pth'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1093
                    yield os.path.join(path, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1094
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1095
    def find_package(self, package):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1096
        for path in self.paths():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1097
            full = os.path.join(path, package)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1098
            if os.path.exists(full):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1099
                return package, full
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1100
            if not os.path.isdir(path) and zipfile.is_zipfile(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1101
                zip = zipfile.ZipFile(path, 'r')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1102
                try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1103
                    zip.read('%s/__init__.py' % package)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1104
                except KeyError:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1105
                    pass
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1106
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1107
                    zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1108
                    return package, full
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1109
                zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1110
        ## FIXME: need special error for package.py case:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1111
        raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1112
            'No package with the name %s found' % package)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1113
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1114
    def list(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1115
        if args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1116
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1117
                'You cannot give an argument with --list')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1118
        for path in sorted(self.paths()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1119
            if not os.path.exists(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1120
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1121
            basename = os.path.basename(path.rstrip(os.path.sep))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1122
            if os.path.isfile(path) and zipfile.is_zipfile(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1123
                if os.path.dirname(path) not in self.paths():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1124
                    logger.notify('Zipped egg: %s' % display_path(path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1125
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1126
            if (basename != 'site-packages'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1127
                and not path.replace('\\', '/').endswith('lib/python')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1128
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1129
            logger.notify('In %s:' % display_path(path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1130
            logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1131
            zipped = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1132
            unzipped = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1133
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1134
                for filename in sorted(os.listdir(path)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1135
                    ext = os.path.splitext(filename)[1].lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1136
                    if ext in ('.pth', '.egg-info', '.egg-link'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1137
                        continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1138
                    if ext == '.py':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1139
                        logger.info('Not displaying %s: not a package' % display_path(filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1140
                        continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1141
                    full = os.path.join(path, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1142
                    if os.path.isdir(full):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1143
                        unzipped.append((filename, self.count_package(full)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1144
                    elif zipfile.is_zipfile(full):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1145
                        zipped.append(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1146
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1147
                        logger.info('Unknown file: %s' % display_path(filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1148
                if zipped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1149
                    logger.notify('Zipped packages:')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1150
                    logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1151
                    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1152
                        for filename in zipped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1153
                            logger.notify(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1154
                    finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1155
                        logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1156
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1157
                    logger.notify('No zipped packages.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1158
                if unzipped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1159
                    if options.sort_files:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1160
                        unzipped.sort(key=lambda x: -x[1])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1161
                    logger.notify('Unzipped packages:')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1162
                    logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1163
                    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1164
                        for filename, count in unzipped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1165
                            logger.notify('%s  (%i files)' % (filename, count))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1166
                    finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1167
                        logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1168
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1169
                    logger.notify('No unzipped packages.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1170
            finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1171
                logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1172
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1173
    def count_package(self, path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1174
        total = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1175
        for dirpath, dirnames, filenames in os.walk(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1176
            filenames = [f for f in filenames
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1177
                         if not f.lower().endswith('.pyc')]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1178
            total += len(filenames)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1179
        return total
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1180
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1181
ZipCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1182
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1183
class UnzipCommand(ZipCommand):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1184
    name = 'unzip'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1185
    summary = 'Unzip individual packages'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1186
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1187
UnzipCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1188
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1189
BASE_COMPLETION = """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1190
# pip %(shell)s completion start%(script)s# pip %(shell)s completion end
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1191
"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1192
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1193
COMPLETION_SCRIPTS = {
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1194
    'bash': """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1195
_pip_completion()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1196
{
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1197
    COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1198
                   COMP_CWORD=$COMP_CWORD \\
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1199
                   PIP_AUTO_COMPLETE=1 $1 ) )
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1200
}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1201
complete -o default -F _pip_completion pip
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1202
""", 'zsh': """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1203
function _pip_completion {
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1204
  local words cword
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1205
  read -Ac words
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1206
  read -cn cword
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1207
  reply=( $( COMP_WORDS="$words[*]" \\ 
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1208
             COMP_CWORD=$(( cword-1 )) \\
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1209
             PIP_AUTO_COMPLETE=1 $words[1] ) )
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1210
}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1211
compctl -K _pip_completion pip
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1212
"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1213
}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1214
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1215
class CompletionCommand(Command):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1216
    name = 'completion'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1217
    summary = 'A helper command to be used for command completion'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1218
    hidden = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1219
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1220
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1221
        super(CompletionCommand, self).__init__()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1222
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1223
            '--bash', '-b',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1224
            action='store_const',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1225
            const='bash',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1226
            dest='shell',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1227
            help='Emit completion code for bash')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1228
        self.parser.add_option(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1229
            '--zsh', '-z',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1230
            action='store_const',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1231
            const='zsh',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1232
            dest='shell',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1233
            help='Emit completion code for zsh')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1234
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1235
    def run(self, options, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1236
        """Prints the completion code of the given shell"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1237
        if options.shell in ('bash', 'zsh'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1238
            script = COMPLETION_SCRIPTS.get(options.shell, '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1239
            print BASE_COMPLETION % {'script': script, 'shell': options.shell}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1240
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1241
            print 'ERROR: You must pass --bash or --zsh'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1242
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1243
CompletionCommand()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1244
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1245
def autocomplete():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1246
    """Command and option completion for the main option parser (and options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1247
    and its subcommands (and options).
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1248
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1249
    Enable by sourcing one of the completion shell scripts (bash or zsh).
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1250
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1251
    # Don't complete if user hasn't sourced bash_completion file.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1252
    if not os.environ.has_key('PIP_AUTO_COMPLETE'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1253
        return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1254
    cwords = os.environ['COMP_WORDS'].split()[1:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1255
    cword = int(os.environ['COMP_CWORD'])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1256
    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1257
        current = cwords[cword-1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1258
    except IndexError:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1259
        current = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1260
    subcommands = [cmd for cmd, cls in _commands.items() if not cls.hidden]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1261
    options = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1262
    # subcommand
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1263
    if cword == 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1264
        # show options of main parser only when necessary
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1265
        if current.startswith('-') or current.startswith('--'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1266
            subcommands += [opt.get_opt_string()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1267
                            for opt in parser.option_list
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1268
                            if opt.help != optparse.SUPPRESS_HELP]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1269
        print ' '.join(filter(lambda x: x.startswith(current), subcommands))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1270
    # subcommand options
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1271
    # special case: the 'help' subcommand has no options
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1272
    elif cwords[0] in subcommands and cwords[0] != 'help':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1273
        subcommand = _commands.get(cwords[0])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1274
        options += [(opt.get_opt_string(), opt.nargs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1275
                    for opt in subcommand.parser.option_list
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1276
                    if opt.help != optparse.SUPPRESS_HELP]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1277
        # filter out previously specified options from available options
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1278
        prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1279
        options = filter(lambda (x, v): x not in prev_opts, options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1280
        # filter options by current input
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1281
        options = [(k, v) for k, v in options if k.startswith(current)]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1282
        for option in options:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1283
            opt_label = option[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1284
            # append '=' to options which require args
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1285
            if option[1]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1286
                opt_label += '='
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1287
            print opt_label
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1288
    sys.exit(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1289
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1290
def main(initial_args=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1291
    if initial_args is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1292
        initial_args = sys.argv[1:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1293
    autocomplete()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1294
    options, args = parser.parse_args(initial_args)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1295
    if options.help and not args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1296
        args = ['help']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1297
    if not args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1298
        parser.error('You must give a command (use "pip help" see a list of commands)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1299
    command = args[0].lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1300
    ## FIXME: search for a command match?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1301
    if command not in _commands:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1302
        parser.error('No command by the name %(script)s %(arg)s\n  (maybe you meant "%(script)s install %(arg)s")'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1303
                     % dict(script=os.path.basename(sys.argv[0]), arg=command))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1304
    command = _commands[command]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1305
    return command.main(initial_args, args[1:], options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1306
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1307
def get_proxy(proxystr=''):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1308
    """Get the proxy given the option passed on the command line.  If an
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1309
    empty string is passed it looks at the HTTP_PROXY environment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1310
    variable."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1311
    if not proxystr:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1312
        proxystr = os.environ.get('HTTP_PROXY', '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1313
    if proxystr:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1314
        if '@' in proxystr:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1315
            user_password, server_port = proxystr.split('@', 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1316
            if ':' in user_password:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1317
                user, password = user_password.split(':', 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1318
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1319
                user = user_password
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1320
                import getpass
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1321
                prompt = 'Password for %s@%s: ' % (user, server_port)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1322
                password = urllib.quote(getpass.getpass(prompt))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1323
            return '%s:%s@%s' % (user, password, server_port)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1324
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1325
            return proxystr
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1326
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1327
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1328
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1329
def setup_proxy_handler(proxystr=''):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1330
    """Set the proxy handler given the option passed on the command
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1331
    line.  If an empty string is passed it looks at the HTTP_PROXY
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1332
    environment variable.  """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1333
    proxy = get_proxy(proxystr)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1334
    if proxy:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1335
        proxy_support = urllib2.ProxyHandler({"http": proxy, "ftp": proxy})
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1336
        opener = urllib2.build_opener(proxy_support, urllib2.CacheFTPHandler)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1337
        urllib2.install_opener(opener)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1338
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1339
def format_exc(exc_info=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1340
    if exc_info is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1341
        exc_info = sys.exc_info()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1342
    out = StringIO()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1343
    traceback.print_exception(*exc_info, **dict(file=out))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1344
    return out.getvalue()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1345
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1346
def restart_in_venv(venv, base, site_packages, args):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1347
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1348
    Restart this script using the interpreter in the given virtual environment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1349
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1350
    if base and not os.path.isabs(venv) and not venv.startswith('~'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1351
        base = os.path.expanduser(base)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1352
        # ensure we have an abs basepath at this point:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1353
        #    a relative one makes no sense (or does it?)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1354
        if os.path.isabs(base):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1355
            venv = os.path.join(base, venv)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1356
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1357
    if venv.startswith('~'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1358
        venv = os.path.expanduser(venv)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1359
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1360
    if not os.path.exists(venv):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1361
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1362
            import virtualenv
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1363
        except ImportError:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1364
            print 'The virtual environment does not exist: %s' % venv
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1365
            print 'and virtualenv is not installed, so a new environment cannot be created'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1366
            sys.exit(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1367
        print 'Creating new virtualenv environment in %s' % venv
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1368
        virtualenv.logger = logger
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1369
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1370
        virtualenv.create_environment(venv, site_packages=site_packages)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1371
    if sys.platform == 'win32':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1372
        python = os.path.join(venv, 'Scripts', 'python.exe')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1373
        # check for bin directory which is used in buildouts
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1374
        if not os.path.exists(python):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1375
            python = os.path.join(venv, 'bin', 'python.exe')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1376
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1377
        python = os.path.join(venv, 'bin', 'python')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1378
    if not os.path.exists(python):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1379
        python = venv
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1380
    if not os.path.exists(python):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1381
        raise BadCommand('Cannot find virtual environment interpreter at %s' % python)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1382
    base = os.path.dirname(os.path.dirname(python))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1383
    file = __file__
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1384
    if file.endswith('.pyc'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1385
        file = file[:-1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1386
    proc = subprocess.Popen(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1387
        [python, file] + args + [base, '___VENV_RESTART___'])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1388
    proc.wait()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1389
    sys.exit(proc.returncode)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1390
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1391
class PackageFinder(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1392
    """This finds packages.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1393
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1394
    This is meant to match easy_install's technique for looking for
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1395
    packages, by reading pages and looking for appropriate links
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1396
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1397
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1398
    failure_limit = 3
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1399
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1400
    def __init__(self, find_links, index_urls):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1401
        self.find_links = find_links
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1402
        self.index_urls = index_urls
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1403
        self.dependency_links = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1404
        self.cache = PageCache()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1405
        # These are boring links that have already been logged somehow:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1406
        self.logged_links = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1407
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1408
    def add_dependency_links(self, links):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1409
        ## FIXME: this shouldn't be global list this, it should only
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1410
        ## apply to requirements of the package that specifies the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1411
        ## dependency_links value
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1412
        ## FIXME: also, we should track comes_from (i.e., use Link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1413
        self.dependency_links.extend(links)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1414
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1415
    def find_requirement(self, req, upgrade):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1416
        url_name = req.url_name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1417
        # Only check main index if index URL is given:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1418
        main_index_url = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1419
        if self.index_urls:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1420
            # Check that we have the url_name correctly spelled:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1421
            main_index_url = Link(posixpath.join(self.index_urls[0], url_name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1422
            # This will also cache the page, so it's okay that we get it again later:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1423
            page = self._get_page(main_index_url, req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1424
            if page is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1425
                url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1426
        def mkurl_pypi_url(url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1427
            loc =  posixpath.join(url, url_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1428
            # For maximum compatibility with easy_install, ensure the path
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1429
            # ends in a trailing slash.  Although this isn't in the spec
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1430
            # (and PyPI can handle it without the slash) some other index
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1431
            # implementations might break if they relied on easy_install's behavior.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1432
            if not loc.endswith('/'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1433
                loc = loc + '/'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1434
            return loc
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1435
        if url_name is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1436
            locations = [
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1437
                mkurl_pypi_url(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1438
                for url in self.index_urls] + self.find_links
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1439
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1440
            locations = list(self.find_links)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1441
        locations.extend(self.dependency_links)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1442
        for version in req.absolute_versions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1443
            if url_name is not None and main_index_url is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1444
                locations = [
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1445
                    posixpath.join(main_index_url.url, version)] + locations
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1446
        file_locations = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1447
        url_locations = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1448
        for url in locations:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1449
            if url.startswith('file:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1450
                fn = url_to_filename(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1451
                if os.path.isdir(fn):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1452
                    path = os.path.realpath(fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1453
                    for item in os.listdir(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1454
                        file_locations.append(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1455
                            filename_to_url2(os.path.join(path, item)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1456
                elif os.path.isfile(fn):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1457
                    file_locations.append(filename_to_url2(fn))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1458
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1459
                url_locations.append(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1460
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1461
        locations = [Link(url) for url in url_locations]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1462
        logger.debug('URLs to search for versions for %s:' % req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1463
        for location in locations:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1464
            logger.debug('* %s' % location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1465
        found_versions = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1466
        found_versions.extend(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1467
            self._package_versions(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1468
                [Link(url, '-f') for url in self.find_links], req.name.lower()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1469
        page_versions = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1470
        for page in self._get_pages(locations, req):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1471
            logger.debug('Analyzing links from page %s' % page.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1472
            logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1473
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1474
                page_versions.extend(self._package_versions(page.links, req.name.lower()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1475
            finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1476
                logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1477
        dependency_versions = list(self._package_versions(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1478
            [Link(url) for url in self.dependency_links], req.name.lower()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1479
        if dependency_versions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1480
            logger.info('dependency_links found: %s' % ', '.join([link.url for parsed, link, version in dependency_versions]))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1481
        file_versions = list(self._package_versions(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1482
                [Link(url) for url in file_locations], req.name.lower()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1483
        if not found_versions and not page_versions and not dependency_versions and not file_versions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1484
            logger.fatal('Could not find any downloads that satisfy the requirement %s' % req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1485
            raise DistributionNotFound('No distributions at all found for %s' % req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1486
        if req.satisfied_by is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1487
            found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1488
        if file_versions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1489
            file_versions.sort(reverse=True)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1490
            logger.info('Local files found: %s' % ', '.join([url_to_filename(link.url) for parsed, link, version in file_versions]))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1491
            found_versions = file_versions + found_versions
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1492
        all_versions = found_versions + page_versions + dependency_versions
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1493
        applicable_versions = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1494
        for (parsed_version, link, version) in all_versions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1495
            if version not in req.req:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1496
                logger.info("Ignoring link %s, version %s doesn't match %s"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1497
                            % (link, version, ','.join([''.join(s) for s in req.req.specs])))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1498
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1499
            applicable_versions.append((link, version))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1500
        applicable_versions = sorted(applicable_versions, key=operator.itemgetter(1),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1501
            cmp=lambda x, y : cmp(pkg_resources.parse_version(y), pkg_resources.parse_version(x))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1502
        )
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1503
        existing_applicable = bool([link for link, version in applicable_versions if link is Inf])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1504
        if not upgrade and existing_applicable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1505
            if applicable_versions[0][1] is Inf:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1506
                logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1507
                            % req.satisfied_by.version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1508
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1509
                logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1510
                            % (req.satisfied_by.version, applicable_versions[0][1]))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1511
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1512
        if not applicable_versions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1513
            logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1514
                         % (req, ', '.join([version for parsed_version, link, version in found_versions])))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1515
            raise DistributionNotFound('No distributions matching the version for %s' % req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1516
        if applicable_versions[0][0] is Inf:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1517
            # We have an existing version, and its the best version
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1518
            logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1519
                        % (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1520
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1521
        if len(applicable_versions) > 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1522
            logger.info('Using version %s (newest of versions: %s)' %
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1523
                        (applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1524
        return applicable_versions[0][0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1525
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1526
    def _find_url_name(self, index_url, url_name, req):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1527
        """Finds the true URL name of a package, when the given name isn't quite correct.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1528
        This is usually used to implement case-insensitivity."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1529
        if not index_url.url.endswith('/'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1530
            # Vaguely part of the PyPI API... weird but true.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1531
            ## FIXME: bad to modify this?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1532
            index_url.url += '/'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1533
        page = self._get_page(index_url, req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1534
        if page is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1535
            logger.fatal('Cannot fetch index base URL %s' % index_url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1536
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1537
        norm_name = normalize_name(req.url_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1538
        for link in page.links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1539
            base = posixpath.basename(link.path.rstrip('/'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1540
            if norm_name == normalize_name(base):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1541
                logger.notify('Real name of requirement %s is %s' % (url_name, base))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1542
                return base
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1543
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1544
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1545
    def _get_pages(self, locations, req):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1546
        """Yields (page, page_url) from the given locations, skipping
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1547
        locations that have errors, and adding download/homepage links"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1548
        pending_queue = Queue()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1549
        for location in locations:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1550
            pending_queue.put(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1551
        done = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1552
        seen = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1553
        threads = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1554
        for i in range(min(10, len(locations))):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1555
            t = threading.Thread(target=self._get_queued_page, args=(req, pending_queue, done, seen))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1556
            t.setDaemon(True)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1557
            threads.append(t)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1558
            t.start()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1559
        for t in threads:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1560
            t.join()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1561
        return done
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1562
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1563
    _log_lock = threading.Lock()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1564
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1565
    def _get_queued_page(self, req, pending_queue, done, seen):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1566
        while 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1567
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1568
                location = pending_queue.get(False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1569
            except QueueEmpty:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1570
                return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1571
            if location in seen:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1572
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1573
            seen.add(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1574
            page = self._get_page(location, req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1575
            if page is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1576
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1577
            done.append(page)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1578
            for link in page.rel_links():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1579
                pending_queue.put(link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1580
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1581
    _egg_fragment_re = re.compile(r'#egg=([^&]*)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1582
    _egg_info_re = re.compile(r'([a-z0-9_.]+)-([a-z0-9_.-]+)', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1583
    _py_version_re = re.compile(r'-py([123]\.[0-9])$')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1584
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1585
    def _sort_links(self, links):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1586
        "Brings links in order, non-egg links first, egg links second"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1587
        eggs, no_eggs = [], []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1588
        for link in links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1589
            if link.egg_fragment:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1590
                eggs.append(link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1591
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1592
                no_eggs.append(link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1593
        return no_eggs + eggs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1594
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1595
    def _package_versions(self, links, search_name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1596
        seen_links = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1597
        for link in self._sort_links(links):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1598
            if link.url in seen_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1599
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1600
            seen_links[link.url] = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1601
            if link.egg_fragment:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1602
                egg_info = link.egg_fragment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1603
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1604
                path = link.path
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1605
                egg_info, ext = link.splitext()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1606
                if not ext:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1607
                    if link not in self.logged_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1608
                        logger.debug('Skipping link %s; not a file' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1609
                        self.logged_links.add(link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1610
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1611
                if egg_info.endswith('.tar'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1612
                    # Special double-extension case:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1613
                    egg_info = egg_info[:-4]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1614
                    ext = '.tar' + ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1615
                if ext not in ('.tar.gz', '.tar.bz2', '.tar', '.tgz', '.zip'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1616
                    if link not in self.logged_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1617
                        logger.debug('Skipping link %s; unknown archive format: %s' % (link, ext))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1618
                        self.logged_links.add(link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1619
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1620
            version = self._egg_info_matches(egg_info, search_name, link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1621
            if version is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1622
                logger.debug('Skipping link %s; wrong project name (not %s)' % (link, search_name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1623
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1624
            match = self._py_version_re.search(version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1625
            if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1626
                version = version[:match.start()]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1627
                py_version = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1628
                if py_version != sys.version[:3]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1629
                    logger.debug('Skipping %s because Python version is incorrect' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1630
                    continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1631
            logger.debug('Found link %s, version: %s' % (link, version))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1632
            yield (pkg_resources.parse_version(version),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1633
                   link,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1634
                   version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1635
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1636
    def _egg_info_matches(self, egg_info, search_name, link):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1637
        match = self._egg_info_re.search(egg_info)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1638
        if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1639
            logger.debug('Could not parse version from link: %s' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1640
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1641
        name = match.group(0).lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1642
        # To match the "safe" name that pkg_resources creates:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1643
        name = name.replace('_', '-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1644
        if name.startswith(search_name.lower()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1645
            return match.group(0)[len(search_name):].lstrip('-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1646
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1647
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1648
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1649
    def _get_page(self, link, req):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1650
        return HTMLPage.get_page(link, req, cache=self.cache)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1651
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1652
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1653
class InstallRequirement(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1654
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1655
    def __init__(self, req, comes_from, source_dir=None, editable=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1656
                 url=None, update=True):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1657
        if isinstance(req, basestring):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1658
            req = pkg_resources.Requirement.parse(req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1659
        self.req = req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1660
        self.comes_from = comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1661
        self.source_dir = source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1662
        self.editable = editable
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1663
        self.url = url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1664
        self._egg_info_path = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1665
        # This holds the pkg_resources.Distribution object if this requirement
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1666
        # is already available:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1667
        self.satisfied_by = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1668
        # This hold the pkg_resources.Distribution object if this requirement
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1669
        # conflicts with another installed distribution:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1670
        self.conflicts_with = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1671
        self._temp_build_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1672
        self._is_bundle = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1673
        # True if the editable should be updated:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1674
        self.update = update
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1675
        # Set to True after successful installation
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1676
        self.install_succeeded = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1677
        # UninstallPathSet of uninstalled distribution (for possible rollback)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1678
        self.uninstalled = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1679
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1680
    @classmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1681
    def from_editable(cls, editable_req, comes_from=None, default_vcs=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1682
        name, url = parse_editable(editable_req, default_vcs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1683
        if url.startswith('file:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1684
            source_dir = url_to_filename(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1685
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1686
            source_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1687
        return cls(name, comes_from, source_dir=source_dir, editable=True, url=url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1688
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1689
    @classmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1690
    def from_line(cls, name, comes_from=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1691
        """Creates an InstallRequirement from a name, which might be a
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1692
        requirement, filename, or URL.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1693
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1694
        url = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1695
        name = name.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1696
        req = name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1697
        if is_url(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1698
            url = name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1699
            ## FIXME: I think getting the requirement here is a bad idea:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1700
            #req = get_requirement_from_url(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1701
            req = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1702
        elif is_filename(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1703
            if not os.path.exists(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1704
                logger.warn('Requirement %r looks like a filename, but the file does not exist'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1705
                            % name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1706
            url = filename_to_url(name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1707
            #req = get_requirement_from_url(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1708
            req = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1709
        return cls(req, comes_from, url=url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1710
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1711
    def __str__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1712
        if self.req:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1713
            s = str(self.req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1714
            if self.url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1715
                s += ' from %s' % self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1716
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1717
            s = self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1718
        if self.satisfied_by is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1719
            s += ' in %s' % display_path(self.satisfied_by.location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1720
        if self.comes_from:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1721
            if isinstance(self.comes_from, basestring):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1722
                comes_from = self.comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1723
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1724
                comes_from = self.comes_from.from_path()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1725
            if comes_from:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1726
                s += ' (from %s)' % comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1727
        return s
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1728
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1729
    def from_path(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1730
        if self.req is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1731
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1732
        s = str(self.req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1733
        if self.comes_from:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1734
            if isinstance(self.comes_from, basestring):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1735
                comes_from = self.comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1736
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1737
                comes_from = self.comes_from.from_path()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1738
            if comes_from:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1739
                s += '->' + comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1740
        return s
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1741
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1742
    def build_location(self, build_dir, unpack=True):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1743
        if self._temp_build_dir is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1744
            return self._temp_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1745
        if self.req is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1746
            self._temp_build_dir = tempfile.mkdtemp('-build', 'pip-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1747
            self._ideal_build_dir = build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1748
            return self._temp_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1749
        if self.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1750
            name = self.name.lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1751
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1752
            name = self.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1753
        # FIXME: Is there a better place to create the build_dir? (hg and bzr need this)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1754
        if not os.path.exists(build_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1755
            os.makedirs(build_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1756
        return os.path.join(build_dir, name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1757
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1758
    def correct_build_location(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1759
        """If the build location was a temporary directory, this will move it
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1760
        to a new more permanent location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1761
        if self.source_dir is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1762
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1763
        assert self.req is not None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1764
        assert self._temp_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1765
        old_location = self._temp_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1766
        new_build_dir = self._ideal_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1767
        del self._ideal_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1768
        if self.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1769
            name = self.name.lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1770
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1771
            name = self.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1772
        new_location = os.path.join(new_build_dir, name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1773
        if not os.path.exists(new_build_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1774
            logger.debug('Creating directory %s' % new_build_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1775
            os.makedirs(new_build_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1776
        if os.path.exists(new_location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1777
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1778
                'A package already exists in %s; please remove it to continue'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1779
                % display_path(new_location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1780
        logger.debug('Moving package %s from %s to new location %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1781
                     % (self, display_path(old_location), display_path(new_location)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1782
        shutil.move(old_location, new_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1783
        self._temp_build_dir = new_location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1784
        self.source_dir = new_location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1785
        self._egg_info_path = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1786
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1787
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1788
    def name(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1789
        if self.req is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1790
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1791
        return self.req.project_name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1792
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1793
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1794
    def url_name(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1795
        if self.req is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1796
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1797
        return urllib.quote(self.req.unsafe_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1798
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1799
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1800
    def setup_py(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1801
        return os.path.join(self.source_dir, 'setup.py')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1802
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1803
    def run_egg_info(self, force_root_egg_info=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1804
        assert self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1805
        if self.name:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1806
            logger.notify('Running setup.py egg_info for package %s' % self.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1807
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1808
            logger.notify('Running setup.py egg_info for package from %s' % self.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1809
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1810
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1811
            script = self._run_setup_py
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1812
            script = script.replace('__SETUP_PY__', repr(self.setup_py))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1813
            script = script.replace('__PKG_NAME__', repr(self.name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1814
            # We can't put the .egg-info files at the root, because then the source code will be mistaken
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1815
            # for an installed egg, causing problems
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1816
            if self.editable or force_root_egg_info:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1817
                egg_base_option = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1818
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1819
                egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1820
                if not os.path.exists(egg_info_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1821
                    os.makedirs(egg_info_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1822
                egg_base_option = ['--egg-base', 'pip-egg-info']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1823
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1824
                [sys.executable, '-c', script, 'egg_info'] + egg_base_option,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1825
                cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1826
                command_level=Logger.VERBOSE_DEBUG,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1827
                command_desc='python setup.py egg_info')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1828
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1829
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1830
        if not self.req:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1831
            self.req = pkg_resources.Requirement.parse(self.pkg_info()['Name'])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1832
            self.correct_build_location()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1833
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1834
    ## FIXME: This is a lame hack, entirely for PasteScript which has
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1835
    ## a self-provided entry point that causes this awkwardness
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1836
    _run_setup_py = """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1837
__file__ = __SETUP_PY__
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1838
from setuptools.command import egg_info
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1839
def replacement_run(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1840
    self.mkpath(self.egg_info)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1841
    installer = self.distribution.fetch_build_egg
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1842
    for ep in egg_info.iter_entry_points('egg_info.writers'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1843
        # require=False is the change we're making:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1844
        writer = ep.load(require=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1845
        if writer:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1846
            writer(self, ep.name, egg_info.os.path.join(self.egg_info,ep.name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1847
    self.find_sources()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1848
egg_info.egg_info.run = replacement_run
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1849
execfile(__file__)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1850
"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1851
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1852
    def egg_info_data(self, filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1853
        if self.satisfied_by is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1854
            if not self.satisfied_by.has_metadata(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1855
                return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1856
            return self.satisfied_by.get_metadata(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1857
        assert self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1858
        filename = self.egg_info_path(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1859
        if not os.path.exists(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1860
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1861
        fp = open(filename, 'r')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1862
        data = fp.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1863
        fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1864
        return data
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1865
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1866
    def egg_info_path(self, filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1867
        if self._egg_info_path is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1868
            if self.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1869
                base = self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1870
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1871
                base = os.path.join(self.source_dir, 'pip-egg-info')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1872
            filenames = os.listdir(base)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1873
            if self.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1874
                filenames = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1875
                for root, dirs, files in os.walk(base):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1876
                    for dir in vcs.dirnames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1877
                        if dir in dirs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1878
                            dirs.remove(dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1879
                    filenames.extend([os.path.join(root, dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1880
                                     for dir in dirs])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1881
                filenames = [f for f in filenames if f.endswith('.egg-info')]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1882
            assert filenames, "No files/directories in %s (from %s)" % (base, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1883
            assert len(filenames) == 1, "Unexpected files/directories in %s: %s" % (base, ' '.join(filenames))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1884
            self._egg_info_path = os.path.join(base, filenames[0])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1885
        return os.path.join(self._egg_info_path, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1886
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1887
    def egg_info_lines(self, filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1888
        data = self.egg_info_data(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1889
        if not data:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1890
            return []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1891
        result = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1892
        for line in data.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1893
            line = line.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1894
            if not line or line.startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1895
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1896
            result.append(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1897
        return result
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1898
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1899
    def pkg_info(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1900
        p = FeedParser()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1901
        data = self.egg_info_data('PKG-INFO')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1902
        if not data:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1903
            logger.warn('No PKG-INFO file found in %s' % display_path(self.egg_info_path('PKG-INFO')))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1904
        p.feed(data or '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1905
        return p.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1906
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1907
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1908
    def dependency_links(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1909
        return self.egg_info_lines('dependency_links.txt')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1910
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1911
    _requirements_section_re = re.compile(r'\[(.*?)\]')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1912
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1913
    def requirements(self, extras=()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1914
        in_extra = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1915
        for line in self.egg_info_lines('requires.txt'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1916
            match = self._requirements_section_re.match(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1917
            if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1918
                in_extra = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1919
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1920
            if in_extra and in_extra not in extras:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1921
                # Skip requirement for an extra we aren't requiring
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1922
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1923
            yield line
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1924
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1925
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1926
    def absolute_versions(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1927
        for qualifier, version in self.req.specs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1928
            if qualifier == '==':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1929
                yield version
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1930
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1931
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1932
    def installed_version(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1933
        return self.pkg_info()['version']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1934
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1935
    def assert_source_matches_version(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1936
        assert self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1937
        if self.comes_from is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1938
            # We don't check the versions of things explicitly installed.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1939
            # This makes, e.g., "pip Package==dev" possible
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1940
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1941
        version = self.installed_version
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1942
        if version not in self.req:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1943
            logger.fatal(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1944
                'Source in %s has the version %s, which does not match the requirement %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1945
                % (display_path(self.source_dir), version, self))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1946
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1947
                'Source in %s has version %s that conflicts with %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1948
                % (display_path(self.source_dir), version, self))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1949
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1950
            logger.debug('Source in %s has version %s, which satisfies requirement %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1951
                         % (display_path(self.source_dir), version, self))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1952
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1953
    def update_editable(self, obtain=True):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1954
        if not self.url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1955
            logger.info("Cannot update repository at %s; repository location is unknown" % self.source_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1956
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1957
        assert self.editable
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1958
        assert self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1959
        if self.url.startswith('file:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1960
            # Static paths don't get updated
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1961
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1962
        assert '+' in self.url, "bad url: %r" % self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1963
        if not self.update:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1964
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1965
        vc_type, url = self.url.split('+', 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1966
        backend = vcs.get_backend(vc_type)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1967
        if backend:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1968
            vcs_backend = backend(self.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1969
            if obtain:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1970
                vcs_backend.obtain(self.source_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1971
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1972
                vcs_backend.export(self.source_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1973
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1974
            assert 0, (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1975
                'Unexpected version control type (in %s): %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1976
                % (self.url, vc_type))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1977
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1978
    def uninstall(self, auto_confirm=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1979
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1980
        Uninstall the distribution currently satisfying this requirement.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1981
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1982
        Prompts before removing or modifying files unless
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1983
        ``auto_confirm`` is True.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1984
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1985
        Refuses to delete or modify files outside of ``sys.prefix`` -
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1986
        thus uninstallation within a virtual environment can only
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1987
        modify that virtual environment, even if the virtualenv is
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1988
        linked to global site-packages.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1989
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1990
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1991
        if not self.check_if_exists():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1992
            raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1993
        dist = self.satisfied_by or self.conflicts_with
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1994
        paths_to_remove = UninstallPathSet(dist, sys.prefix)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1995
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1996
        pip_egg_info_path = os.path.join(dist.location,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1997
                                         dist.egg_name()) + '.egg-info'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1998
        easy_install_egg = dist.egg_name() + '.egg'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  1999
        # This won't find a globally-installed develop egg if
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2000
        # we're in a virtualenv.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2001
        # (There doesn't seem to be any metadata in the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2002
        # Distribution object for a develop egg that points back
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2003
        # to its .egg-link and easy-install.pth files).  That's
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2004
        # OK, because we restrict ourselves to making changes
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2005
        # within sys.prefix anyway.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2006
        develop_egg_link = os.path.join(site_packages,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2007
                                        dist.project_name) + '.egg-link'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2008
        if os.path.exists(pip_egg_info_path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2009
            # package installed by pip
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2010
            paths_to_remove.add(pip_egg_info_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2011
            if dist.has_metadata('installed-files.txt'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2012
                for installed_file in dist.get_metadata('installed-files.txt').splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2013
                    path = os.path.normpath(os.path.join(pip_egg_info_path, installed_file))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2014
                    if os.path.exists(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2015
                        paths_to_remove.add(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2016
            if dist.has_metadata('top_level.txt'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2017
                for top_level_pkg in [p for p
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2018
                                      in dist.get_metadata('top_level.txt').splitlines()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2019
                                      if p]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2020
                    path = os.path.join(dist.location, top_level_pkg)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2021
                    if os.path.exists(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2022
                        paths_to_remove.add(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2023
                    elif os.path.exists(path + '.py'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2024
                        paths_to_remove.add(path + '.py')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2025
                        if os.path.exists(path + '.pyc'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2026
                            paths_to_remove.add(path + '.pyc')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2027
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2028
        elif dist.location.endswith(easy_install_egg):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2029
            # package installed by easy_install
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2030
            paths_to_remove.add(dist.location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2031
            easy_install_pth = os.path.join(os.path.dirname(dist.location),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2032
                                            'easy-install.pth')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2033
            paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2034
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2035
        elif os.path.isfile(develop_egg_link):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2036
            # develop egg
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2037
            fh = open(develop_egg_link, 'r')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2038
            link_pointer = os.path.normcase(fh.readline().strip())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2039
            fh.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2040
            assert (link_pointer == dist.location), 'Egg-link %s does not match installed location of %s (at %s)' % (link_pointer, self.name, dist.location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2041
            paths_to_remove.add(develop_egg_link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2042
            easy_install_pth = os.path.join(os.path.dirname(develop_egg_link),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2043
                                            'easy-install.pth')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2044
            paths_to_remove.add_pth(easy_install_pth, dist.location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2045
            # fix location (so we can uninstall links to sources outside venv)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2046
            paths_to_remove.location = develop_egg_link
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2047
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2048
        # find distutils scripts= scripts
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2049
        if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2050
            for script in dist.metadata_listdir('scripts'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2051
                paths_to_remove.add(os.path.join(bin_py, script))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2052
                if sys.platform == 'win32':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2053
                    paths_to_remove.add(os.path.join(bin_py, script) + '.bat')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2054
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2055
        # find console_scripts
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2056
        if dist.has_metadata('entry_points.txt'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2057
            config = ConfigParser.SafeConfigParser()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2058
            config.readfp(FakeFile(dist.get_metadata_lines('entry_points.txt')))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2059
            if config.has_section('console_scripts'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2060
                for name, value in config.items('console_scripts'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2061
                    paths_to_remove.add(os.path.join(bin_py, name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2062
                    if sys.platform == 'win32':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2063
                        paths_to_remove.add(os.path.join(bin_py, name) + '.exe')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2064
                        paths_to_remove.add(os.path.join(bin_py, name) + '-script.py')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2065
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2066
        paths_to_remove.remove(auto_confirm)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2067
        self.uninstalled = paths_to_remove
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2068
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2069
    def rollback_uninstall(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2070
        if self.uninstalled:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2071
            self.uninstalled.rollback()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2072
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2073
            logger.error("Can't rollback %s, nothing uninstalled."
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2074
                         % (self.project_name,))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2075
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2076
    def archive(self, build_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2077
        assert self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2078
        create_archive = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2079
        archive_name = '%s-%s.zip' % (self.name, self.installed_version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2080
        archive_path = os.path.join(build_dir, archive_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2081
        if os.path.exists(archive_path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2082
            response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2083
                           % display_path(archive_path), ('i', 'w', 'b'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2084
            if response == 'i':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2085
                create_archive = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2086
            elif response == 'w':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2087
                logger.warn('Deleting %s' % display_path(archive_path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2088
                os.remove(archive_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2089
            elif response == 'b':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2090
                dest_file = backup_dir(archive_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2091
                logger.warn('Backing up %s to %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2092
                            % (display_path(archive_path), display_path(dest_file)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2093
                shutil.move(archive_path, dest_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2094
        if create_archive:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2095
            zip = zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2096
            dir = os.path.normcase(os.path.abspath(self.source_dir))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2097
            for dirpath, dirnames, filenames in os.walk(dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2098
                if 'pip-egg-info' in dirnames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2099
                    dirnames.remove('pip-egg-info')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2100
                for dirname in dirnames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2101
                    dirname = os.path.join(dirpath, dirname)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2102
                    name = self._clean_zip_name(dirname, dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2103
                    zipdir = zipfile.ZipInfo(self.name + '/' + name + '/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2104
                    zipdir.external_attr = 0755 << 16L
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2105
                    zip.writestr(zipdir, '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2106
                for filename in filenames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2107
                    if filename == 'pip-delete-this-directory.txt':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2108
                        continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2109
                    filename = os.path.join(dirpath, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2110
                    name = self._clean_zip_name(filename, dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2111
                    zip.write(filename, self.name + '/' + name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2112
            zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2113
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2114
            logger.notify('Saved %s' % display_path(archive_path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2115
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2116
    def _clean_zip_name(self, name, prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2117
        assert name.startswith(prefix+'/'), (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2118
            "name %r doesn't start with prefix %r" % (name, prefix))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2119
        name = name[len(prefix)+1:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2120
        name = name.replace(os.path.sep, '/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2121
        return name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2122
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2123
    def install(self, install_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2124
        if self.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2125
            self.install_editable()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2126
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2127
        temp_location = tempfile.mkdtemp('-record', 'pip-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2128
        record_filename = os.path.join(temp_location, 'install-record.txt')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2129
        ## FIXME: I'm not sure if this is a reasonable location; probably not
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2130
        ## but we can't put it in the default location, as that is a virtualenv symlink that isn't writable
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2131
        header_dir = os.path.join(os.path.dirname(os.path.dirname(self.source_dir)), 'lib', 'include')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2132
        logger.notify('Running setup.py install for %s' % self.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2133
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2134
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2135
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2136
                [sys.executable, '-c',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2137
                 "import setuptools; __file__=%r; execfile(%r)" % (self.setup_py, self.setup_py),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2138
                 'install', '--single-version-externally-managed', '--record', record_filename,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2139
                 '--install-headers', header_dir] + install_options,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2140
                cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2141
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2142
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2143
        self.install_succeeded = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2144
        f = open(record_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2145
        for line in f:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2146
            line = line.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2147
            if line.endswith('.egg-info'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2148
                egg_info_dir = line
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2149
                break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2150
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2151
            logger.warn('Could not find .egg-info directory in install record for %s' % self)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2152
            ## FIXME: put the record somewhere
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2153
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2154
        f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2155
        new_lines = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2156
        f = open(record_filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2157
        for line in f:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2158
            filename = line.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2159
            if os.path.isdir(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2160
                filename += os.path.sep
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2161
            new_lines.append(make_path_relative(filename, egg_info_dir))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2162
        f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2163
        f = open(os.path.join(egg_info_dir, 'installed-files.txt'), 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2164
        f.write('\n'.join(new_lines)+'\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2165
        f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2166
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2167
    def remove_temporary_source(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2168
        """Remove the source files from this requirement, if they are marked
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2169
        for deletion"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2170
        if self.is_bundle or os.path.exists(self.delete_marker_filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2171
            logger.info('Removing source in %s' % self.source_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2172
            if self.source_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2173
                shutil.rmtree(self.source_dir, ignore_errors=True, onerror=rmtree_errorhandler)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2174
            self.source_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2175
            if self._temp_build_dir and os.path.exists(self._temp_build_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2176
                shutil.rmtree(self._temp_build_dir, ignore_errors=True, onerror=rmtree_errorhandler)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2177
            self._temp_build_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2178
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2179
    def install_editable(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2180
        logger.notify('Running setup.py develop for %s' % self.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2181
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2182
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2183
            ## FIXME: should we do --install-headers here too?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2184
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2185
                [sys.executable, '-c',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2186
                 "import setuptools; __file__=%r; execfile(%r)" % (self.setup_py, self.setup_py),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2187
                 'develop', '--no-deps'], cwd=self.source_dir, filter_stdout=self._filter_install,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2188
                show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2189
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2190
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2191
        self.install_succeeded = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2192
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2193
    def _filter_install(self, line):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2194
        level = Logger.NOTIFY
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2195
        for regex in [r'^running .*', r'^writing .*', '^creating .*', '^[Cc]opying .*',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2196
                      r'^reading .*', r"^removing .*\.egg-info' \(and everything under it\)$",
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2197
                      r'^byte-compiling ',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2198
                      # Not sure what this warning is, but it seems harmless:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2199
                      r"^warning: manifest_maker: standard file '-c' not found$"]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2200
            if re.search(regex, line.strip()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2201
                level = Logger.INFO
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2202
                break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2203
        return (level, line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2204
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2205
    def check_if_exists(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2206
        """Find an installed distribution that satisfies or conflicts
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2207
        with this requirement, and set self.satisfied_by or
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2208
        self.conflicts_with appropriately."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2209
        if self.req is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2210
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2211
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2212
            self.satisfied_by = pkg_resources.get_distribution(self.req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2213
        except pkg_resources.DistributionNotFound:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2214
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2215
        except pkg_resources.VersionConflict:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2216
            self.conflicts_with = pkg_resources.get_distribution(self.req.project_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2217
        return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2218
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2219
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2220
    def is_bundle(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2221
        if self._is_bundle is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2222
            return self._is_bundle
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2223
        base = self._temp_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2224
        if not base:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2225
            ## FIXME: this doesn't seem right:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2226
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2227
        self._is_bundle = (os.path.exists(os.path.join(base, 'pip-manifest.txt'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2228
                           or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt')))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2229
        return self._is_bundle
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2230
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2231
    def bundle_requirements(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2232
        for dest_dir in self._bundle_editable_dirs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2233
            package = os.path.basename(dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2234
            ## FIXME: svnism:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2235
            for vcs_backend in vcs.backends:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2236
                url = rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2237
                vcs_bundle_file = os.path.join(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2238
                    dest_dir, vcs_backend.bundle_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2239
                if os.path.exists(vcs_bundle_file):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2240
                    vc_type = vcs_backend.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2241
                    fp = open(vcs_bundle_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2242
                    content = fp.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2243
                    fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2244
                    url, rev = vcs_backend().parse_vcs_bundle_file(content)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2245
                    break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2246
            if url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2247
                url = '%s+%s@%s' % (vc_type, url, rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2248
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2249
                url = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2250
            yield InstallRequirement(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2251
                package, self, editable=True, url=url,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2252
                update=False, source_dir=dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2253
        for dest_dir in self._bundle_build_dirs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2254
            package = os.path.basename(dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2255
            yield InstallRequirement(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2256
                package, self,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2257
                source_dir=dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2258
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2259
    def move_bundle_files(self, dest_build_dir, dest_src_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2260
        base = self._temp_build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2261
        assert base
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2262
        src_dir = os.path.join(base, 'src')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2263
        build_dir = os.path.join(base, 'build')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2264
        bundle_build_dirs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2265
        bundle_editable_dirs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2266
        for source_dir, dest_dir, dir_collection in [
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2267
            (src_dir, dest_src_dir, bundle_editable_dirs),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2268
            (build_dir, dest_build_dir, bundle_build_dirs)]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2269
            if os.path.exists(source_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2270
                for dirname in os.listdir(source_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2271
                    dest = os.path.join(dest_dir, dirname)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2272
                    dir_collection.append(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2273
                    if os.path.exists(dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2274
                        logger.warn('The directory %s (containing package %s) already exists; cannot move source from bundle %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2275
                                    % (dest, dirname, self))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2276
                        continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2277
                    if not os.path.exists(dest_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2278
                        logger.info('Creating directory %s' % dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2279
                        os.makedirs(dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2280
                    shutil.move(os.path.join(source_dir, dirname), dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2281
                if not os.listdir(source_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2282
                    os.rmdir(source_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2283
        self._temp_build_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2284
        self._bundle_build_dirs = bundle_build_dirs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2285
        self._bundle_editable_dirs = bundle_editable_dirs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2286
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2287
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2288
    def delete_marker_filename(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2289
        assert self.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2290
        return os.path.join(self.source_dir, 'pip-delete-this-directory.txt')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2291
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2292
DELETE_MARKER_MESSAGE = '''\
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2293
This file is placed here by pip to indicate the source was put
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2294
here by pip.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2295
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2296
Once this package is successfully installed this source code will be
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2297
deleted (unless you remove this file).
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2298
'''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2299
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2300
class RequirementSet(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2301
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2302
    def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2303
                 upgrade=False, ignore_installed=False,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2304
                 ignore_dependencies=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2305
        self.build_dir = build_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2306
        self.src_dir = src_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2307
        self.download_dir = download_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2308
        self.download_cache = download_cache
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2309
        self.upgrade = upgrade
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2310
        self.ignore_installed = ignore_installed
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2311
        self.requirements = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2312
        # Mapping of alias: real_name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2313
        self.requirement_aliases = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2314
        self.unnamed_requirements = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2315
        self.ignore_dependencies = ignore_dependencies
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2316
        self.successfully_downloaded = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2317
        self.successfully_installed = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2318
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2319
    def __str__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2320
        reqs = [req for req in self.requirements.values()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2321
                if not req.comes_from]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2322
        reqs.sort(key=lambda req: req.name.lower())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2323
        return ' '.join([str(req.req) for req in reqs])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2324
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2325
    def add_requirement(self, install_req):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2326
        name = install_req.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2327
        if not name:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2328
            self.unnamed_requirements.append(install_req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2329
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2330
            if self.has_requirement(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2331
                raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2332
                    'Double requirement given: %s (aready in %s, name=%r)'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2333
                    % (install_req, self.get_requirement(name), name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2334
            self.requirements[name] = install_req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2335
            ## FIXME: what about other normalizations?  E.g., _ vs. -?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2336
            if name.lower() != name:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2337
                self.requirement_aliases[name.lower()] = name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2338
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2339
    def has_requirement(self, project_name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2340
        for name in project_name, project_name.lower():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2341
            if name in self.requirements or name in self.requirement_aliases:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2342
                return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2343
        return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2344
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2345
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2346
    def is_download(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2347
        if self.download_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2348
            self.download_dir = os.path.expanduser(self.download_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2349
            if os.path.exists(self.download_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2350
                return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2351
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2352
                logger.fatal('Could not find download directory')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2353
                raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2354
                    "Could not find or access download directory '%s'"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2355
                    % display_path(self.download_dir))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2356
        return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2357
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2358
    def get_requirement(self, project_name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2359
        for name in project_name, project_name.lower():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2360
            if name in self.requirements:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2361
                return self.requirements[name]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2362
            if name in self.requirement_aliases:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2363
                return self.requirements[self.requirement_aliases[name]]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2364
        raise KeyError("No project with the name %r" % project_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2365
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2366
    def uninstall(self, auto_confirm=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2367
        for req in self.requirements.values():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2368
            req.uninstall(auto_confirm=auto_confirm)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2369
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2370
    def install_files(self, finder, force_root_egg_info=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2371
        unnamed = list(self.unnamed_requirements)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2372
        reqs = self.requirements.values()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2373
        while reqs or unnamed:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2374
            if unnamed:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2375
                req_to_install = unnamed.pop(0)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2376
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2377
                req_to_install = reqs.pop(0)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2378
            install = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2379
            if not self.ignore_installed and not req_to_install.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2380
                req_to_install.check_if_exists()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2381
                if req_to_install.satisfied_by:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2382
                    if self.upgrade:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2383
                        req_to_install.conflicts_with = req_to_install.satisfied_by
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2384
                        req_to_install.satisfied_by = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2385
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2386
                        install = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2387
                if req_to_install.satisfied_by:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2388
                    logger.notify('Requirement already satisfied '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2389
                                  '(use --upgrade to upgrade): %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2390
                                  % req_to_install)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2391
            if req_to_install.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2392
                logger.notify('Obtaining %s' % req_to_install)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2393
            elif install:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2394
                if req_to_install.url and req_to_install.url.lower().startswith('file:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2395
                    logger.notify('Unpacking %s' % display_path(url_to_filename(req_to_install.url)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2396
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2397
                    logger.notify('Downloading/unpacking %s' % req_to_install)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2398
            logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2399
            is_bundle = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2400
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2401
                if req_to_install.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2402
                    if req_to_install.source_dir is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2403
                        location = req_to_install.build_location(self.src_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2404
                        req_to_install.source_dir = location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2405
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2406
                        location = req_to_install.source_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2407
                    if not os.path.exists(self.build_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2408
                        os.makedirs(self.build_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2409
                    req_to_install.update_editable(not self.is_download)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2410
                    if self.is_download:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2411
                        req_to_install.run_egg_info()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2412
                        req_to_install.archive(self.download_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2413
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2414
                        req_to_install.run_egg_info()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2415
                elif install:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2416
                    location = req_to_install.build_location(self.build_dir, not self.is_download)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2417
                    ## FIXME: is the existance of the checkout good enough to use it?  I don't think so.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2418
                    unpack = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2419
                    if not os.path.exists(os.path.join(location, 'setup.py')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2420
                        ## FIXME: this won't upgrade when there's an existing package unpacked in `location`
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2421
                        if req_to_install.url is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2422
                            url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2423
                        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2424
                            ## FIXME: should req_to_install.url already be a link?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2425
                            url = Link(req_to_install.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2426
                            assert url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2427
                        if url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2428
                            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2429
                                self.unpack_url(url, location, self.is_download)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2430
                            except urllib2.HTTPError, e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2431
                                logger.fatal('Could not install requirement %s because of error %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2432
                                             % (req_to_install, e))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2433
                                raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2434
                                    'Could not install requirement %s because of HTTP error %s for URL %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2435
                                    % (req_to_install, e, url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2436
                        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2437
                            unpack = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2438
                    if unpack:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2439
                        is_bundle = req_to_install.is_bundle
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2440
                        url = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2441
                        if is_bundle:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2442
                            req_to_install.move_bundle_files(self.build_dir, self.src_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2443
                            for subreq in req_to_install.bundle_requirements():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2444
                                reqs.append(subreq)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2445
                                self.add_requirement(subreq)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2446
                        elif self.is_download:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2447
                            req_to_install.source_dir = location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2448
                            if url and url.scheme in vcs.all_schemes:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2449
                                req_to_install.run_egg_info()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2450
                                req_to_install.archive(self.download_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2451
                        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2452
                            req_to_install.source_dir = location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2453
                            req_to_install.run_egg_info()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2454
                            if force_root_egg_info:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2455
                                # We need to run this to make sure that the .egg-info/
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2456
                                # directory is created for packing in the bundle
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2457
                                req_to_install.run_egg_info(force_root_egg_info=True)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2458
                            req_to_install.assert_source_matches_version()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2459
                            f = open(req_to_install.delete_marker_filename, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2460
                            f.write(DELETE_MARKER_MESSAGE)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2461
                            f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2462
                if not is_bundle and not self.is_download:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2463
                    ## FIXME: shouldn't be globally added:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2464
                    finder.add_dependency_links(req_to_install.dependency_links)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2465
                    ## FIXME: add extras in here:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2466
                    if not self.ignore_dependencies:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2467
                        for req in req_to_install.requirements():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2468
                            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2469
                                name = pkg_resources.Requirement.parse(req).project_name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2470
                            except ValueError, e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2471
                                ## FIXME: proper warning
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2472
                                logger.error('Invalid requirement: %r (%s) in requirement %s' % (req, e, req_to_install))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2473
                                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2474
                            if self.has_requirement(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2475
                                ## FIXME: check for conflict
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2476
                                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2477
                            subreq = InstallRequirement(req, req_to_install)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2478
                            reqs.append(subreq)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2479
                            self.add_requirement(subreq)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2480
                    if req_to_install.name not in self.requirements:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2481
                        self.requirements[req_to_install.name] = req_to_install
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2482
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2483
                    req_to_install.remove_temporary_source()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2484
                if install:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2485
                    self.successfully_downloaded.append(req_to_install)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2486
            finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2487
                logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2488
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2489
    def unpack_url(self, link, location, only_download=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2490
        if only_download:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2491
            location = self.download_dir
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2492
        for backend in vcs.backends:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2493
            if link.scheme in backend.schemes:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2494
                vcs_backend = backend(link.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2495
                if only_download:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2496
                    vcs_backend.export(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2497
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2498
                    vcs_backend.unpack(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2499
                return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2500
        dir = tempfile.mkdtemp()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2501
        if link.url.lower().startswith('file:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2502
            source = url_to_filename(link.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2503
            content_type = mimetypes.guess_type(source)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2504
            self.unpack_file(source, location, content_type, link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2505
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2506
        md5_hash = link.md5_hash
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2507
        target_url = link.url.split('#', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2508
        target_file = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2509
        if self.download_cache:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2510
            if not os.path.isdir(self.download_cache):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2511
                logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2512
                logger.notify('Creating supposed download cache at %s' % self.download_cache)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2513
                logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2514
                os.makedirs(self.download_cache)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2515
            target_file = os.path.join(self.download_cache,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2516
                                       urllib.quote(target_url, ''))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2517
        if (target_file and os.path.exists(target_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2518
            and os.path.exists(target_file+'.content-type')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2519
            fp = open(target_file+'.content-type')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2520
            content_type = fp.read().strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2521
            fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2522
            if md5_hash:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2523
                download_hash = md5()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2524
                fp = open(target_file, 'rb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2525
                while 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2526
                    chunk = fp.read(4096)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2527
                    if not chunk:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2528
                        break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2529
                    download_hash.update(chunk)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2530
                fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2531
            temp_location = target_file
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2532
            logger.notify('Using download cache from %s' % target_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2533
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2534
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2535
                resp = urllib2.urlopen(target_url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2536
            except urllib2.HTTPError, e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2537
                logger.fatal("HTTP error %s while getting %s" % (e.code, link))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2538
                raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2539
            except IOError, e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2540
                # Typically an FTP error
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2541
                logger.fatal("Error %s while getting %s" % (e, link))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2542
                raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2543
            content_type = resp.info()['content-type']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2544
            filename = link.filename
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2545
            ext = splitext(filename)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2546
            if not ext:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2547
                ext = mimetypes.guess_extension(content_type)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2548
                if ext:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2549
                    filename += ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2550
            if not ext and link.url != resp.geturl():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2551
                ext = os.path.splitext(resp.geturl())[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2552
                if ext:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2553
                    filename += ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2554
            temp_location = os.path.join(dir, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2555
            fp = open(temp_location, 'wb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2556
            if md5_hash:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2557
                download_hash = md5()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2558
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2559
                total_length = int(resp.info()['content-length'])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2560
            except (ValueError, KeyError):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2561
                total_length = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2562
            downloaded = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2563
            show_progress = total_length > 40*1000 or not total_length
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2564
            show_url = link.show_url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2565
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2566
                if show_progress:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2567
                    ## FIXME: the URL can get really long in this message:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2568
                    if total_length:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2569
                        logger.start_progress('Downloading %s (%s): ' % (show_url, format_size(total_length)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2570
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2571
                        logger.start_progress('Downloading %s (unknown size): ' % show_url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2572
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2573
                    logger.notify('Downloading %s' % show_url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2574
                logger.debug('Downloading from URL %s' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2575
                while 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2576
                    chunk = resp.read(4096)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2577
                    if not chunk:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2578
                        break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2579
                    downloaded += len(chunk)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2580
                    if show_progress:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2581
                        if not total_length:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2582
                            logger.show_progress('%s' % format_size(downloaded))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2583
                        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2584
                            logger.show_progress('%3i%%  %s' % (100*downloaded/total_length, format_size(downloaded)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2585
                    if md5_hash:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2586
                        download_hash.update(chunk)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2587
                    fp.write(chunk)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2588
                fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2589
            finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2590
                if show_progress:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2591
                    logger.end_progress('%s downloaded' % format_size(downloaded))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2592
        if md5_hash:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2593
            download_hash = download_hash.hexdigest()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2594
            if download_hash != md5_hash:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2595
                logger.fatal("MD5 hash of the package %s (%s) doesn't match the expected hash %s!"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2596
                             % (link, download_hash, md5_hash))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2597
                raise InstallationError('Bad MD5 hash for package %s' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2598
        if only_download:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2599
            self.copy_file(temp_location, location, content_type, link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2600
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2601
            self.unpack_file(temp_location, location, content_type, link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2602
        if target_file and target_file != temp_location:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2603
            logger.notify('Storing download in cache at %s' % display_path(target_file))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2604
            shutil.copyfile(temp_location, target_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2605
            fp = open(target_file+'.content-type', 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2606
            fp.write(content_type)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2607
            fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2608
            os.unlink(temp_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2609
        if target_file is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2610
            os.unlink(temp_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2611
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2612
    def copy_file(self, filename, location, content_type, link):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2613
        copy = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2614
        download_location = os.path.join(location, link.filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2615
        if os.path.exists(download_location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2616
            response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup '
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2617
                           % display_path(download_location), ('i', 'w', 'b'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2618
            if response == 'i':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2619
                copy = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2620
            elif response == 'w':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2621
                logger.warn('Deleting %s' % display_path(download_location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2622
                os.remove(download_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2623
            elif response == 'b':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2624
                dest_file = backup_dir(download_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2625
                logger.warn('Backing up %s to %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2626
                            % (display_path(download_location), display_path(dest_file)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2627
                shutil.move(download_location, dest_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2628
        if copy:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2629
            shutil.copy(filename, download_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2630
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2631
            logger.notify('Saved %s' % display_path(download_location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2632
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2633
    def unpack_file(self, filename, location, content_type, link):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2634
        if (content_type == 'application/zip'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2635
            or filename.endswith('.zip')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2636
            or filename.endswith('.pybundle')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2637
            or zipfile.is_zipfile(filename)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2638
            self.unzip_file(filename, location, flatten=not filename.endswith('.pybundle'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2639
        elif (content_type == 'application/x-gzip'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2640
              or tarfile.is_tarfile(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2641
              or splitext(filename)[1].lower() in ('.tar', '.tar.gz', '.tar.bz2', '.tgz', '.tbz')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2642
            self.untar_file(filename, location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2643
        elif (content_type and content_type.startswith('text/html')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2644
              and is_svn_page(file_contents(filename))):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2645
            # We don't really care about this
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2646
            Subversion('svn+' + link.url).unpack(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2647
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2648
            ## FIXME: handle?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2649
            ## FIXME: magic signatures?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2650
            logger.fatal('Cannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive format'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2651
                         % (filename, location, content_type))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2652
            raise InstallationError('Cannot determine archive format of %s' % location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2653
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2654
    def unzip_file(self, filename, location, flatten=True):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2655
        """Unzip the file (zip file located at filename) to the destination
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2656
        location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2657
        if not os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2658
            os.makedirs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2659
        zipfp = open(filename, 'rb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2660
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2661
            zip = zipfile.ZipFile(zipfp)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2662
            leading = has_leading_dir(zip.namelist()) and flatten
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2663
            for name in zip.namelist():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2664
                data = zip.read(name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2665
                fn = name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2666
                if leading:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2667
                    fn = split_leading_dir(name)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2668
                fn = os.path.join(location, fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2669
                dir = os.path.dirname(fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2670
                if not os.path.exists(dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2671
                    os.makedirs(dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2672
                if fn.endswith('/') or fn.endswith('\\'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2673
                    # A directory
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2674
                    if not os.path.exists(fn):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2675
                        os.makedirs(fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2676
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2677
                    fp = open(fn, 'wb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2678
                    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2679
                        fp.write(data)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2680
                    finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2681
                        fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2682
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2683
            zipfp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2684
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2685
    def untar_file(self, filename, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2686
        """Untar the file (tar file located at filename) to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2687
        if not os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2688
            os.makedirs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2689
        if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2690
            mode = 'r:gz'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2691
        elif filename.lower().endswith('.bz2') or filename.lower().endswith('.tbz'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2692
            mode = 'r:bz2'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2693
        elif filename.lower().endswith('.tar'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2694
            mode = 'r'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2695
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2696
            logger.warn('Cannot determine compression type for file %s' % filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2697
            mode = 'r:*'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2698
        tar = tarfile.open(filename, mode)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2699
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2700
            leading = has_leading_dir([member.name for member in tar.getmembers()])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2701
            for member in tar.getmembers():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2702
                fn = member.name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2703
                if leading:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2704
                    fn = split_leading_dir(fn)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2705
                path = os.path.join(location, fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2706
                if member.isdir():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2707
                    if not os.path.exists(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2708
                        os.makedirs(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2709
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2710
                    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2711
                        fp = tar.extractfile(member)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2712
                    except (KeyError, AttributeError), e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2713
                        # Some corrupt tar files seem to produce this
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2714
                        # (specifically bad symlinks)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2715
                        logger.warn(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2716
                            'In the tar file %s the member %s is invalid: %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2717
                            % (filename, member.name, e))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2718
                        continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2719
                    if not os.path.exists(os.path.dirname(path)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2720
                        os.makedirs(os.path.dirname(path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2721
                    destfp = open(path, 'wb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2722
                    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2723
                        shutil.copyfileobj(fp, destfp)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2724
                    finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2725
                        destfp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2726
                    fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2727
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2728
            tar.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2729
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2730
    def install(self, install_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2731
        """Install everything in this set (after having downloaded and unpacked the packages)"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2732
        to_install = sorted([r for r in self.requirements.values()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2733
                             if self.upgrade or not r.satisfied_by],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2734
                            key=lambda p: p.name.lower())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2735
        if to_install:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2736
            logger.notify('Installing collected packages: %s' % (', '.join([req.name for req in to_install])))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2737
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2738
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2739
            for requirement in to_install:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2740
                if requirement.conflicts_with:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2741
                    logger.notify('Found existing installation: %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2742
                                  % requirement.conflicts_with)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2743
                    logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2744
                    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2745
                        requirement.uninstall(auto_confirm=True)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2746
                    finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2747
                        logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2748
                try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2749
                    requirement.install(install_options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2750
                except:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2751
                    # if install did not succeed, rollback previous uninstall
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2752
                    if requirement.conflicts_with and not requirement.install_succeeded:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2753
                        requirement.rollback_uninstall()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2754
                    raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2755
                requirement.remove_temporary_source()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2756
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2757
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2758
        self.successfully_installed = to_install
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2759
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2760
    def create_bundle(self, bundle_filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2761
        ## FIXME: can't decide which is better; zip is easier to read
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2762
        ## random files from, but tar.bz2 is smaller and not as lame a
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2763
        ## format.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2764
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2765
        ## FIXME: this file should really include a manifest of the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2766
        ## packages, maybe some other metadata files.  It would make
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2767
        ## it easier to detect as well.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2768
        zip = zipfile.ZipFile(bundle_filename, 'w', zipfile.ZIP_DEFLATED)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2769
        vcs_dirs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2770
        for dir, basename in (self.build_dir, 'build'), (self.src_dir, 'src'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2771
            dir = os.path.normcase(os.path.abspath(dir))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2772
            for dirpath, dirnames, filenames in os.walk(dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2773
                for backend in vcs.backends:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2774
                    vcs_backend = backend()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2775
                    vcs_url = vcs_rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2776
                    if vcs_backend.dirname in dirnames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2777
                        for vcs_dir in vcs_dirs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2778
                            if dirpath.startswith(vcs_dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2779
                                # vcs bundle file already in parent directory
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2780
                                break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2781
                        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2782
                            vcs_url, vcs_rev = vcs_backend.get_info(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2783
                                os.path.join(dir, dirpath))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2784
                            vcs_dirs.append(dirpath)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2785
                        vcs_bundle_file = vcs_backend.bundle_file
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2786
                        vcs_guide = vcs_backend.guide % {'url': vcs_url,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2787
                                                         'rev': vcs_rev}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2788
                        dirnames.remove(vcs_backend.dirname)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2789
                        break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2790
                if 'pip-egg-info' in dirnames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2791
                    dirnames.remove('pip-egg-info')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2792
                for dirname in dirnames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2793
                    dirname = os.path.join(dirpath, dirname)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2794
                    name = self._clean_zip_name(dirname, dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2795
                    zip.writestr(basename + '/' + name + '/', '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2796
                for filename in filenames:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2797
                    if filename == 'pip-delete-this-directory.txt':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2798
                        continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2799
                    filename = os.path.join(dirpath, filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2800
                    name = self._clean_zip_name(filename, dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2801
                    zip.write(filename, basename + '/' + name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2802
                if vcs_url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2803
                    name = os.path.join(dirpath, vcs_bundle_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2804
                    name = self._clean_zip_name(name, dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2805
                    zip.writestr(basename + '/' + name, vcs_guide)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2806
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2807
        zip.writestr('pip-manifest.txt', self.bundle_requirements())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2808
        zip.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2809
        # Unlike installation, this will always delete the build directories
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2810
        logger.info('Removing temporary build dir %s and source dir %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2811
                    % (self.build_dir, self.src_dir))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2812
        for dir in self.build_dir, self.src_dir:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2813
            if os.path.exists(dir):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2814
                shutil.rmtree(dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2815
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2816
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2817
    BUNDLE_HEADER = '''\
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2818
# This is a pip bundle file, that contains many source packages
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2819
# that can be installed as a group.  You can install this like:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2820
#     pip this_file.zip
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2821
# The rest of the file contains a list of all the packages included:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2822
'''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2823
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2824
    def bundle_requirements(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2825
        parts = [self.BUNDLE_HEADER]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2826
        for req in sorted(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2827
            [req for req in self.requirements.values()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2828
             if not req.comes_from],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2829
            key=lambda x: x.name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2830
            parts.append('%s==%s\n' % (req.name, req.installed_version))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2831
        parts.append('# These packages were installed to satisfy the above requirements:\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2832
        for req in sorted(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2833
            [req for req in self.requirements.values()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2834
             if req.comes_from],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2835
            key=lambda x: x.name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2836
            parts.append('%s==%s\n' % (req.name, req.installed_version))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2837
        ## FIXME: should we do something with self.unnamed_requirements?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2838
        return ''.join(parts)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2839
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2840
    def _clean_zip_name(self, name, prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2841
        assert name.startswith(prefix+'/'), (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2842
            "name %r doesn't start with prefix %r" % (name, prefix))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2843
        name = name[len(prefix)+1:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2844
        name = name.replace(os.path.sep, '/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2845
        return name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2846
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2847
class HTMLPage(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2848
    """Represents one page, along with its URL"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2849
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2850
    ## FIXME: these regexes are horrible hacks:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2851
    _homepage_re = re.compile(r'<th>\s*home\s*page', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2852
    _download_re = re.compile(r'<th>\s*download\s+url', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2853
    ## These aren't so aweful:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2854
    _rel_re = re.compile("""<[^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*>""", re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2855
    _href_re = re.compile('href=(?:"([^"]*)"|\'([^\']*)\'|([^>\\s\\n]*))', re.I|re.S)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2856
    _base_re = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2857
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2858
    def __init__(self, content, url, headers=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2859
        self.content = content
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2860
        self.url = url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2861
        self.headers = headers
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2862
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2863
    def __str__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2864
        return self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2865
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2866
    @classmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2867
    def get_page(cls, link, req, cache=None, skip_archives=True):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2868
        url = link.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2869
        url = url.split('#', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2870
        if cache.too_many_failures(url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2871
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2872
        if url.lower().startswith('svn'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2873
            logger.debug('Cannot look at svn URL %s' % link)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2874
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2875
        if cache is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2876
            inst = cache.get_page(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2877
            if inst is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2878
                return inst
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2879
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2880
            if skip_archives:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2881
                if cache is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2882
                    if cache.is_archive(url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2883
                        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2884
                filename = link.filename
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2885
                for bad_ext in ['.tar', '.tar.gz', '.tar.bz2', '.tgz', '.zip']:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2886
                    if filename.endswith(bad_ext):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2887
                        content_type = cls._get_content_type(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2888
                        if content_type.lower().startswith('text/html'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2889
                            break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2890
                        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2891
                            logger.debug('Skipping page %s because of Content-Type: %s' % (link, content_type))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2892
                            if cache is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2893
                                cache.set_is_archive(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2894
                            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2895
            logger.debug('Getting page %s' % url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2896
            resp = urllib2.urlopen(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2897
            real_url = resp.geturl()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2898
            headers = resp.info()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2899
            inst = cls(resp.read(), real_url, headers)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2900
        except (urllib2.HTTPError, urllib2.URLError, socket.timeout, socket.error), e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2901
            desc = str(e)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2902
            if isinstance(e, socket.timeout):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2903
                log_meth = logger.info
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2904
                level =1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2905
                desc = 'timed out'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2906
            elif isinstance(e, urllib2.URLError):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2907
                log_meth = logger.info
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2908
                if hasattr(e, 'reason') and isinstance(e.reason, socket.timeout):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2909
                    desc = 'timed out'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2910
                    level = 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2911
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2912
                    level = 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2913
            elif isinstance(e, urllib2.HTTPError) and e.code == 404:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2914
                ## FIXME: notify?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2915
                log_meth = logger.info
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2916
                level = 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2917
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2918
                log_meth = logger.info
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2919
                level = 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2920
            log_meth('Could not fetch URL %s: %s' % (link, desc))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2921
            log_meth('Will skip URL %s when looking for download links for %s' % (link.url, req))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2922
            if cache is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2923
                cache.add_page_failure(url, level)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2924
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2925
        if cache is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2926
            cache.add_page([url, real_url], inst)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2927
        return inst
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2928
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2929
    @staticmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2930
    def _get_content_type(url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2931
        """Get the Content-Type of the given url, using a HEAD request"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2932
        scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2933
        if scheme == 'http':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2934
            ConnClass = httplib.HTTPConnection
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2935
        elif scheme == 'https':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2936
            ConnClass = httplib.HTTPSConnection
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2937
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2938
            ## FIXME: some warning or something?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2939
            ## assertion error?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2940
            return ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2941
        if query:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2942
            path += '?' + query
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2943
        conn = ConnClass(netloc)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2944
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2945
            conn.request('HEAD', path, headers={'Host': netloc})
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2946
            resp = conn.getresponse()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2947
            if resp.status != 200:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2948
                ## FIXME: doesn't handle redirects
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2949
                return ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2950
            return resp.getheader('Content-Type') or ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2951
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2952
            conn.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2953
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2954
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2955
    def base_url(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2956
        if not hasattr(self, "_base_url"):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2957
            match = self._base_re.search(self.content)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2958
            if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2959
                self._base_url = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2960
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2961
                self._base_url = self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2962
        return self._base_url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2963
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2964
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2965
    def links(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2966
        """Yields all links in the page"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2967
        for match in self._href_re.finditer(self.content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2968
            url = match.group(1) or match.group(2) or match.group(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2969
            url = self.clean_link(urlparse.urljoin(self.base_url, url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2970
            yield Link(url, self)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2971
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2972
    def rel_links(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2973
        for url in self.explicit_rel_links():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2974
            yield url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2975
        for url in self.scraped_rel_links():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2976
            yield url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2977
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2978
    def explicit_rel_links(self, rels=('homepage', 'download')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2979
        """Yields all links with the given relations"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2980
        for match in self._rel_re.finditer(self.content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2981
            found_rels = match.group(1).lower().split()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2982
            for rel in rels:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2983
                if rel in found_rels:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2984
                    break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2985
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2986
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2987
            match = self._href_re.search(match.group(0))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2988
            if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2989
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2990
            url = match.group(1) or match.group(2) or match.group(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2991
            url = self.clean_link(urlparse.urljoin(self.base_url, url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2992
            yield Link(url, self)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2993
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2994
    def scraped_rel_links(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2995
        for regex in (self._homepage_re, self._download_re):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2996
            match = regex.search(self.content)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2997
            if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2998
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  2999
            href_match = self._href_re.search(self.content, pos=match.end())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3000
            if not href_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3001
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3002
            url = match.group(1) or match.group(2) or match.group(3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3003
            if not url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3004
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3005
            url = self.clean_link(urlparse.urljoin(self.base_url, url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3006
            yield Link(url, self)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3007
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3008
    _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3009
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3010
    def clean_link(self, url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3011
        """Makes sure a link is fully encoded.  That is, if a ' ' shows up in
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3012
        the link, it will be rewritten to %20 (while not over-quoting
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3013
        % or other characters)."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3014
        return self._clean_re.sub(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3015
            lambda match: '%%%2x' % ord(match.group(0)), url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3016
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3017
class PageCache(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3018
    """Cache of HTML pages"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3019
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3020
    failure_limit = 3
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3021
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3022
    def __init__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3023
        self._failures = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3024
        self._pages = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3025
        self._archives = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3026
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3027
    def too_many_failures(self, url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3028
        return self._failures.get(url, 0) >= self.failure_limit
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3029
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3030
    def get_page(self, url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3031
        return self._pages.get(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3032
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3033
    def is_archive(self, url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3034
        return self._archives.get(url, False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3035
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3036
    def set_is_archive(self, url, value=True):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3037
        self._archives[url] = value
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3038
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3039
    def add_page_failure(self, url, level):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3040
        self._failures[url] = self._failures.get(url, 0)+level
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3041
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3042
    def add_page(self, urls, page):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3043
        for url in urls:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3044
            self._pages[url] = page
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3045
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3046
class Link(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3047
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3048
    def __init__(self, url, comes_from=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3049
        self.url = url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3050
        self.comes_from = comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3051
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3052
    def __str__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3053
        if self.comes_from:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3054
            return '%s (from %s)' % (self.url, self.comes_from)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3055
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3056
            return self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3057
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3058
    def __repr__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3059
        return '<Link %s>' % self
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3060
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3061
    def __eq__(self, other):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3062
        return self.url == other.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3063
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3064
    def __hash__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3065
        return hash(self.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3066
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3067
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3068
    def filename(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3069
        url = self.url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3070
        url = url.split('#', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3071
        url = url.split('?', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3072
        url = url.rstrip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3073
        name = posixpath.basename(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3074
        assert name, (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3075
            'URL %r produced no filename' % url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3076
        return name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3077
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3078
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3079
    def scheme(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3080
        return urlparse.urlsplit(self.url)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3081
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3082
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3083
    def path(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3084
        return urlparse.urlsplit(self.url)[2]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3085
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3086
    def splitext(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3087
        return splitext(posixpath.basename(self.path.rstrip('/')))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3088
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3089
    _egg_fragment_re = re.compile(r'#egg=([^&]*)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3090
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3091
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3092
    def egg_fragment(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3093
        match = self._egg_fragment_re.search(self.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3094
        if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3095
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3096
        return match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3097
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3098
    _md5_re = re.compile(r'md5=([a-f0-9]+)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3099
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3100
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3101
    def md5_hash(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3102
        match = self._md5_re.search(self.url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3103
        if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3104
            return match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3105
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3106
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3107
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3108
    def show_url(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3109
        return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3110
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3111
############################################################
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3112
## Writing freeze files
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3113
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3114
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3115
class FrozenRequirement(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3116
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3117
    def __init__(self, name, req, editable, comments=()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3118
        self.name = name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3119
        self.req = req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3120
        self.editable = editable
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3121
        self.comments = comments
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3122
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3123
    _rev_re = re.compile(r'-r(\d+)$')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3124
    _date_re = re.compile(r'-(20\d\d\d\d\d\d)$')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3125
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3126
    @classmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3127
    def from_dist(cls, dist, dependency_links, find_tags=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3128
        location = os.path.normcase(os.path.abspath(dist.location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3129
        comments = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3130
        if vcs.get_backend_name(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3131
            editable = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3132
            req = get_src_requirement(dist, location, find_tags)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3133
            if req is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3134
                logger.warn('Could not determine repository location of %s' % location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3135
                comments.append('## !! Could not determine repository location')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3136
                req = dist.as_requirement()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3137
                editable = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3138
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3139
            editable = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3140
            req = dist.as_requirement()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3141
            specs = req.specs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3142
            assert len(specs) == 1 and specs[0][0] == '=='
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3143
            version = specs[0][1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3144
            ver_match = cls._rev_re.search(version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3145
            date_match = cls._date_re.search(version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3146
            if ver_match or date_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3147
                svn_backend = vcs.get_backend('svn')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3148
                if svn_backend:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3149
                    svn_location = svn_backend(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3150
                        ).get_location(dist, dependency_links)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3151
                if not svn_location:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3152
                    logger.warn(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3153
                        'Warning: cannot find svn location for %s' % req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3154
                    comments.append('## FIXME: could not find svn URL in dependency_links for this package:')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3155
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3156
                    comments.append('# Installing as editable to satisfy requirement %s:' % req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3157
                    if ver_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3158
                        rev = ver_match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3159
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3160
                        rev = '{%s}' % date_match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3161
                    editable = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3162
                    req = 'svn+%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3163
        return cls(dist.project_name, req, editable, comments)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3164
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3165
    @staticmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3166
    def egg_name(dist):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3167
        name = dist.egg_name()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3168
        match = re.search(r'-py\d\.\d$', name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3169
        if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3170
            name = name[:match.start()]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3171
        return name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3172
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3173
    def __str__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3174
        req = self.req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3175
        if self.editable:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3176
            req = '-e %s' % req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3177
        return '\n'.join(list(self.comments)+[str(req)])+'\n'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3178
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3179
class VersionControl(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3180
    name = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3181
    dirname = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3182
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3183
    def __init__(self, url=None, *args, **kwargs):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3184
        self.url = url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3185
        self._cmd = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3186
        super(VersionControl, self).__init__(*args, **kwargs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3187
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3188
    def _filter(self, line):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3189
        return (Logger.INFO, line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3190
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3191
    @property
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3192
    def cmd(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3193
        if self._cmd is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3194
            return self._cmd
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3195
        command = find_command(self.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3196
        if command is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3197
            raise BadCommand('Cannot find command %s' % self.name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3198
        logger.info('Found command %s at %s' % (self.name, command))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3199
        self._cmd = command
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3200
        return command
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3201
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3202
    def get_url_rev(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3203
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3204
        Returns the correct repository URL and revision by parsing the given
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3205
        repository URL
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3206
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3207
        url = self.url.split('+', 1)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3208
        scheme, netloc, path, query, frag = urlparse.urlsplit(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3209
        rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3210
        if '@' in path:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3211
            path, rev = path.rsplit('@', 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3212
        url = urlparse.urlunsplit((scheme, netloc, path, query, ''))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3213
        return url, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3214
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3215
    def get_info(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3216
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3217
        Returns (url, revision), where both are strings
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3218
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3219
        assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3220
        return self.get_url(location), self.get_revision(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3221
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3222
    def normalize_url(self, url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3223
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3224
        Normalize a URL for comparison by unquoting it and removing any trailing slash.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3225
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3226
        return urllib.unquote(url).rstrip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3227
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3228
    def compare_urls(self, url1, url2):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3229
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3230
        Compare two repo URLs for identity, ignoring incidental differences.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3231
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3232
        return (self.normalize_url(url1) == self.normalize_url(url2))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3233
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3234
    def parse_vcs_bundle_file(self, content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3235
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3236
        Takes the contents of the bundled text file that explains how to revert
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3237
        the stripped off version control data of the given package and returns
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3238
        the URL and revision of it.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3239
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3240
        raise NotImplementedError
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3241
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3242
    def obtain(self, dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3243
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3244
        Called when installing or updating an editable package, takes the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3245
        source path of the checkout.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3246
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3247
        raise NotImplementedError
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3248
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3249
    def switch(self, dest, url, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3250
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3251
        Switch the repo at ``dest`` to point to ``URL``.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3252
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3253
        raise NotImplemented
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3254
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3255
    def update(self, dest, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3256
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3257
        Update an already-existing repo to the given ``rev_options``.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3258
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3259
        raise NotImplementedError
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3260
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3261
    def check_destination(self, dest, url, rev_options, rev_display):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3262
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3263
        Prepare a location to receive a checkout/clone.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3264
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3265
        Return True if the location is ready for (and requires) a
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3266
        checkout/clone, False otherwise.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3267
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3268
        checkout = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3269
        prompt = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3270
        if os.path.exists(dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3271
            checkout = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3272
            if os.path.exists(os.path.join(dest, self.dirname)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3273
                existing_url = self.get_url(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3274
                if self.compare_urls(existing_url, url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3275
                    logger.info('%s in %s exists, and has correct URL (%s)'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3276
                                % (self.repo_name.title(), display_path(dest), url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3277
                    logger.notify('Updating %s %s%s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3278
                                  % (display_path(dest), self.repo_name, rev_display))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3279
                    self.update(dest, rev_options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3280
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3281
                    logger.warn('%s %s in %s exists with URL %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3282
                                % (self.name, self.repo_name, display_path(dest), existing_url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3283
                    prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3284
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3285
                logger.warn('Directory %s already exists, and is not a %s %s.'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3286
                            % (dest, self.name, self.repo_name))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3287
                prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3288
        if prompt:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3289
            logger.warn('The plan is to install the %s repository %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3290
                        % (self.name, url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3291
            response = ask('What to do?  %s' % prompt[0], prompt[1])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3292
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3293
            if response == 's':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3294
                logger.notify('Switching %s %s to %s%s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3295
                              % (self.repo_name, display_path(dest), url, rev_display))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3296
                self.switch(dest, url, rev_options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3297
            elif response == 'i':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3298
                # do nothing
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3299
                pass
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3300
            elif response == 'w':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3301
                logger.warn('Deleting %s' % display_path(dest))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3302
                shutil.rmtree(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3303
                checkout = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3304
            elif response == 'b':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3305
                dest_dir = backup_dir(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3306
                logger.warn('Backing up %s to %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3307
                            % (display_path(dest), dest_dir))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3308
                shutil.move(dest, dest_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3309
                checkout = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3310
        return checkout
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3311
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3312
    def unpack(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3313
        raise NotImplementedError
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3314
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3315
    def get_src_requirement(self, dist, location, find_tags=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3316
        raise NotImplementedError
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3317
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3318
_svn_xml_url_re = re.compile('url="([^"]+)"')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3319
_svn_rev_re = re.compile('committed-rev="(\d+)"')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3320
_svn_url_re = re.compile(r'URL: (.+)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3321
_svn_revision_re = re.compile(r'Revision: (.+)')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3322
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3323
class Subversion(VersionControl):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3324
    name = 'svn'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3325
    dirname = '.svn'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3326
    repo_name = 'checkout'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3327
    schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3328
    bundle_file = 'svn-checkout.txt'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3329
    guide = ('# This was an svn checkout; to make it a checkout again run:\n'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3330
            'svn checkout --force -r %(rev)s %(url)s .\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3331
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3332
    def get_info(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3333
        """Returns (url, revision), where both are strings"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3334
        assert not location.rstrip('/').endswith(self.dirname), 'Bad directory: %s' % location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3335
        output = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3336
            ['svn', 'info', location], show_stdout=False, extra_environ={'LANG': 'C'})
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3337
        match = _svn_url_re.search(output)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3338
        if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3339
            logger.warn('Cannot determine URL of svn checkout %s' % display_path(location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3340
            logger.info('Output that cannot be parsed: \n%s' % output)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3341
            return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3342
        url = match.group(1).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3343
        match = _svn_revision_re.search(output)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3344
        if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3345
            logger.warn('Cannot determine revision of svn checkout %s' % display_path(location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3346
            logger.info('Output that cannot be parsed: \n%s' % output)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3347
            return url, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3348
        return url, match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3349
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3350
    def get_url(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3351
        return self.get_info(location)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3352
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3353
    def get_revision(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3354
        return self.get_info(location)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3355
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3356
    def parse_vcs_bundle_file(self, content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3357
        for line in content.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3358
            if not line.strip() or line.strip().startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3359
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3360
            match = re.search(r'^-r\s*([^ ])?', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3361
            if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3362
                return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3363
            rev = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3364
            rest = line[match.end():].strip().split(None, 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3365
            return rest, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3366
        return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3367
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3368
    def unpack(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3369
        """Check out the svn repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3370
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3371
        logger.notify('Checking out svn repository %s to %s' % (url, location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3372
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3373
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3374
            if os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3375
                # Subversion doesn't like to check out over an existing directory
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3376
                # --force fixes this, but was only added in svn 1.5
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3377
                shutil.rmtree(location, onerror=rmtree_errorhandler)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3378
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3379
                ['svn', 'checkout', url, location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3380
                filter_stdout=self._filter, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3381
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3382
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3383
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3384
    def export(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3385
        """Export the svn repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3386
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3387
        logger.notify('Checking out svn repository %s to %s' % (url, location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3388
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3389
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3390
            if os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3391
                # Subversion doesn't like to check out over an existing directory
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3392
                # --force fixes this, but was only added in svn 1.5
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3393
                shutil.rmtree(location, onerror=rmtree_errorhandler)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3394
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3395
                ['svn', 'export', url, location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3396
                filter_stdout=self._filter, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3397
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3398
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3399
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3400
    def switch(self, dest, url, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3401
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3402
            ['svn', 'switch'] + rev_options + [url, dest])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3403
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3404
    def update(self, dest, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3405
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3406
            ['svn', 'update'] + rev_options + [dest])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3407
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3408
    def obtain(self, dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3409
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3410
        if rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3411
            rev_options = ['-r', rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3412
            rev_display = ' (to revision %s)' % rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3413
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3414
            rev_options = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3415
            rev_display = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3416
        if self.check_destination(dest, url, rev_options, rev_display):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3417
            logger.notify('Checking out %s%s to %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3418
                          % (url, rev_display, display_path(dest)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3419
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3420
                ['svn', 'checkout', '-q'] + rev_options + [url, dest])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3421
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3422
    def get_location(self, dist, dependency_links):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3423
        egg_fragment_re = re.compile(r'#egg=(.*)$')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3424
        for url in dependency_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3425
            egg_fragment = Link(url).egg_fragment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3426
            if not egg_fragment:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3427
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3428
            if '-' in egg_fragment:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3429
                ## FIXME: will this work when a package has - in the name?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3430
                key = '-'.join(egg_fragment.split('-')[:-1]).lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3431
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3432
                key = egg_fragment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3433
            if key == dist.key:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3434
                return url.split('#', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3435
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3436
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3437
    def get_revision(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3438
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3439
        Return the maximum revision for all files under a given location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3440
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3441
        # Note: taken from setuptools.command.egg_info
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3442
        revision = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3443
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3444
        for base, dirs, files in os.walk(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3445
            if self.dirname not in dirs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3446
                dirs[:] = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3447
                continue    # no sense walking uncontrolled subdirs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3448
            dirs.remove(self.dirname)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3449
            entries_fn = os.path.join(base, self.dirname, 'entries')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3450
            if not os.path.exists(entries_fn):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3451
                ## FIXME: should we warn?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3452
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3453
            f = open(entries_fn)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3454
            data = f.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3455
            f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3456
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3457
            if data.startswith('8') or data.startswith('9') or data.startswith('10'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3458
                data = map(str.splitlines,data.split('\n\x0c\n'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3459
                del data[0][0]  # get rid of the '8'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3460
                dirurl = data[0][3]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3461
                revs = [int(d[9]) for d in data if len(d)>9 and d[9]]+[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3462
                if revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3463
                    localrev = max(revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3464
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3465
                    localrev = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3466
            elif data.startswith('<?xml'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3467
                dirurl = _svn_xml_url_re.search(data).group(1)    # get repository URL
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3468
                revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)]+[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3469
                if revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3470
                    localrev = max(revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3471
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3472
                    localrev = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3473
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3474
                logger.warn("Unrecognized .svn/entries format; skipping %s", base)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3475
                dirs[:] = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3476
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3477
            if base == location:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3478
                base_url = dirurl+'/'   # save the root url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3479
            elif not dirurl.startswith(base_url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3480
                dirs[:] = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3481
                continue    # not part of the same svn tree, skip it
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3482
            revision = max(revision, localrev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3483
        return revision
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3484
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3485
    def get_url(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3486
        # In cases where the source is in a subdirectory, not alongside setup.py
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3487
        # we have to look up in the location until we find a real setup.py
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3488
        orig_location = location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3489
        while not os.path.exists(os.path.join(location, 'setup.py')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3490
            last_location = location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3491
            location = os.path.dirname(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3492
            if location == last_location:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3493
                # We've traversed up to the root of the filesystem without finding setup.py
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3494
                logger.warn("Could not find setup.py for directory %s (tried all parent directories)"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3495
                            % orig_location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3496
                return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3497
        f = open(os.path.join(location, self.dirname, 'entries'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3498
        data = f.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3499
        f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3500
        if data.startswith('8') or data.startswith('9') or data.startswith('10'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3501
            data = map(str.splitlines,data.split('\n\x0c\n'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3502
            del data[0][0]  # get rid of the '8'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3503
            return data[0][3]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3504
        elif data.startswith('<?xml'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3505
            match = _svn_xml_url_re.search(data)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3506
            if not match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3507
                raise ValueError('Badly formatted data: %r' % data)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3508
            return match.group(1)    # get repository URL
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3509
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3510
            logger.warn("Unrecognized .svn/entries format in %s" % location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3511
            # Or raise exception?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3512
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3513
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3514
    def get_tag_revs(self, svn_tag_url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3515
        stdout = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3516
            ['svn', 'ls', '-v', svn_tag_url], show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3517
        results = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3518
        for line in stdout.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3519
            parts = line.split()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3520
            rev = int(parts[0])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3521
            tag = parts[-1].strip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3522
            results.append((tag, rev))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3523
        return results
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3524
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3525
    def find_tag_match(self, rev, tag_revs):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3526
        best_match_rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3527
        best_tag = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3528
        for tag, tag_rev in tag_revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3529
            if (tag_rev > rev and
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3530
                (best_match_rev is None or best_match_rev > tag_rev)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3531
                # FIXME: Is best_match > tag_rev really possible?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3532
                # or is it a sign something is wacky?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3533
                best_match_rev = tag_rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3534
                best_tag = tag
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3535
        return best_tag
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3536
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3537
    def get_src_requirement(self, dist, location, find_tags=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3538
        repo = self.get_url(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3539
        if repo is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3540
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3541
        parts = repo.split('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3542
        ## FIXME: why not project name?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3543
        egg_project_name = dist.egg_name().split('-', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3544
        rev = self.get_revision(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3545
        if parts[-2] in ('tags', 'tag'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3546
            # It's a tag, perfect!
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3547
            full_egg_name = '%s-%s' % (egg_project_name, parts[-1])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3548
        elif parts[-2] in ('branches', 'branch'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3549
            # It's a branch :(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3550
            full_egg_name = '%s-%s-r%s' % (dist.egg_name(), parts[-1], rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3551
        elif parts[-1] == 'trunk':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3552
            # Trunk :-/
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3553
            full_egg_name = '%s-dev_r%s' % (dist.egg_name(), rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3554
            if find_tags:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3555
                tag_url = '/'.join(parts[:-1]) + '/tags'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3556
                tag_revs = self.get_tag_revs(tag_url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3557
                match = self.find_tag_match(rev, tag_revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3558
                if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3559
                    logger.notify('trunk checkout %s seems to be equivalent to tag %s' % match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3560
                    repo = '%s/%s' % (tag_url, match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3561
                    full_egg_name = '%s-%s' % (egg_project_name, match)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3562
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3563
            # Don't know what it is
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3564
            logger.warn('svn URL does not fit normal structure (tags/branches/trunk): %s' % repo)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3565
            full_egg_name = '%s-dev_r%s' % (egg_project_name, rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3566
        return 'svn+%s@%s#egg=%s' % (repo, rev, full_egg_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3567
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3568
vcs.register(Subversion)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3569
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3570
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3571
class Git(VersionControl):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3572
    name = 'git'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3573
    dirname = '.git'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3574
    repo_name = 'clone'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3575
    schemes = ('git', 'git+http', 'git+ssh', 'git+git')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3576
    bundle_file = 'git-clone.txt'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3577
    guide = ('# This was a Git repo; to make it a repo again run:\n'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3578
        'git init\ngit remote add origin %(url)s -f\ngit checkout %(rev)s\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3579
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3580
    def parse_vcs_bundle_file(self, content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3581
        url = rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3582
        for line in content.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3583
            if not line.strip() or line.strip().startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3584
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3585
            url_match = re.search(r'git\s*remote\s*add\s*origin(.*)\s*-f', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3586
            if url_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3587
                url = url_match.group(1).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3588
            rev_match = re.search(r'^git\s*checkout\s*-q\s*(.*)\s*', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3589
            if rev_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3590
                rev = rev_match.group(1).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3591
            if url and rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3592
                return url, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3593
        return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3594
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3595
    def unpack(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3596
        """Clone the Git repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3597
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3598
        logger.notify('Cloning Git repository %s to %s' % (url, location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3599
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3600
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3601
            if os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3602
                os.rmdir(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3603
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3604
                [self.cmd, 'clone', url, location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3605
                filter_stdout=self._filter, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3606
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3607
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3608
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3609
    def export(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3610
        """Export the Git repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3611
        temp_dir = tempfile.mkdtemp('-export', 'pip-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3612
        self.unpack(temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3613
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3614
            if not location.endswith('/'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3615
                location = location + '/'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3616
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3617
                [self.cmd, 'checkout-index', '-a', '-f', '--prefix', location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3618
                filter_stdout=self._filter, show_stdout=False, cwd=temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3619
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3620
            shutil.rmtree(temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3621
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3622
    def check_rev_options(self, rev, dest, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3623
        """Check the revision options before checkout to compensate that tags
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3624
        and branches may need origin/ as a prefix"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3625
        if rev is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3626
            # bail and use preset
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3627
            return rev_options
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3628
        revisions = self.get_tag_revs(dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3629
        revisions.update(self.get_branch_revs(dest))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3630
        if rev in revisions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3631
            # if rev is a sha
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3632
            return [rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3633
        inverse_revisions = dict((v,k) for k, v in revisions.iteritems())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3634
        if rev not in inverse_revisions: # is rev a name or tag?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3635
            origin_rev = 'origin/%s' % rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3636
            if origin_rev in inverse_revisions:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3637
                rev = inverse_revisions[origin_rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3638
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3639
                logger.warn("Could not find a tag or branch '%s', assuming commit." % rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3640
        return [rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3641
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3642
    def switch(self, dest, url, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3643
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3644
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3645
            [self.cmd, 'config', 'remote.origin.url', url], cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3646
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3647
            [self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3648
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3649
    def update(self, dest, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3650
        call_subprocess([self.cmd, 'fetch', '-q'], cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3651
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3652
            [self.cmd, 'checkout', '-q', '-f'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3653
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3654
    def obtain(self, dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3655
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3656
        if rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3657
            rev_options = [rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3658
            rev_display = ' (to %s)' % rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3659
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3660
            rev_options = ['origin/master']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3661
            rev_display = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3662
        if self.check_destination(dest, url, rev_options, rev_display):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3663
            logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3664
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3665
                [self.cmd, 'clone', '-q', url, dest])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3666
            rev_options = self.check_rev_options(rev, dest, rev_options)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3667
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3668
                [self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3669
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3670
    def get_url(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3671
        url = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3672
            [self.cmd, 'config', 'remote.origin.url'],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3673
            show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3674
        return url.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3675
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3676
    def get_revision(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3677
        current_rev = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3678
            [self.cmd, 'rev-parse', 'HEAD'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3679
        return current_rev.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3680
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3681
    def get_tag_revs(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3682
        tags = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3683
            [self.cmd, 'tag'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3684
        tag_revs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3685
        for line in tags.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3686
            tag = line.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3687
            rev = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3688
                [self.cmd, 'rev-parse', tag], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3689
            tag_revs.append((rev.strip(), tag))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3690
        tag_revs = dict(tag_revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3691
        return tag_revs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3692
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3693
    def get_branch_revs(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3694
        branches = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3695
            [self.cmd, 'branch', '-r'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3696
        branch_revs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3697
        for line in branches.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3698
            line = line.split('->')[0].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3699
            branch = "".join([b for b in line.split() if b != '*'])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3700
            rev = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3701
                [self.cmd, 'rev-parse', branch], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3702
            branch_revs.append((rev.strip(), branch))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3703
        branch_revs = dict(branch_revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3704
        return branch_revs
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3705
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3706
    def get_src_requirement(self, dist, location, find_tags):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3707
        repo = self.get_url(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3708
        if not repo.lower().startswith('git:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3709
            repo = 'git+' + repo
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3710
        egg_project_name = dist.egg_name().split('-', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3711
        if not repo:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3712
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3713
        current_rev = self.get_revision(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3714
        tag_revs = self.get_tag_revs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3715
        branch_revs = self.get_branch_revs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3716
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3717
        if current_rev in tag_revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3718
            # It's a tag
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3719
            full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3720
        elif (current_rev in branch_revs and
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3721
              branch_revs[current_rev] != 'origin/master'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3722
            # It's the head of a branch
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3723
            full_egg_name = '%s-%s' % (dist.egg_name(),
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3724
                                       branch_revs[current_rev].replace('origin/', ''))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3725
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3726
            full_egg_name = '%s-dev' % dist.egg_name()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3727
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3728
        return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3729
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3730
    def get_url_rev(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3731
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3732
        Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3733
        That's required because although they use SSH they sometimes doesn't
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3734
        work with a ssh:// scheme (e.g. Github). But we need a scheme for
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3735
        parsing. Hence we remove it again afterwards and return it as a stub.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3736
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3737
        if not '://' in self.url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3738
            self.url = self.url.replace('git+', 'git+ssh://')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3739
            url, rev = super(Git, self).get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3740
            url = url.replace('ssh://', '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3741
            return url, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3742
        return super(Git, self).get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3743
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3744
vcs.register(Git)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3745
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3746
class Mercurial(VersionControl):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3747
    name = 'hg'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3748
    dirname = '.hg'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3749
    repo_name = 'clone'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3750
    schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3751
    bundle_file = 'hg-clone.txt'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3752
    guide = ('# This was a Mercurial repo; to make it a repo again run:\n'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3753
            'hg init\nhg pull %(url)s\nhg update -r %(rev)s\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3754
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3755
    def parse_vcs_bundle_file(self, content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3756
        url = rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3757
        for line in content.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3758
            if not line.strip() or line.strip().startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3759
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3760
            url_match = re.search(r'hg\s*pull\s*(.*)\s*', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3761
            if url_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3762
                url = url_match.group(1).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3763
            rev_match = re.search(r'^hg\s*update\s*-r\s*(.*)\s*', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3764
            if rev_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3765
                rev = rev_match.group(1).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3766
            if url and rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3767
                return url, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3768
        return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3769
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3770
    def unpack(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3771
        """Clone the Hg repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3772
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3773
        logger.notify('Cloning Mercurial repository %s to %s' % (url, location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3774
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3775
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3776
            if os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3777
                os.rmdir(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3778
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3779
                ['hg', 'clone', url, location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3780
                filter_stdout=self._filter, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3781
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3782
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3783
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3784
    def export(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3785
        """Export the Hg repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3786
        temp_dir = tempfile.mkdtemp('-export', 'pip-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3787
        self.unpack(temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3788
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3789
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3790
                ['hg', 'archive', location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3791
                filter_stdout=self._filter, show_stdout=False, cwd=temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3792
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3793
            shutil.rmtree(temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3794
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3795
    def switch(self, dest, url, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3796
        repo_config = os.path.join(dest, self.dirname, 'hgrc')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3797
        config = ConfigParser.SafeConfigParser()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3798
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3799
            config.read(repo_config)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3800
            config.set('paths', 'default', url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3801
            config_file = open(repo_config, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3802
            config.write(config_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3803
            config_file.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3804
        except (OSError, ConfigParser.NoSectionError), e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3805
            logger.warn(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3806
                'Could not switch Mercurial repository to %s: %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3807
                % (url, e))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3808
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3809
            call_subprocess(['hg', 'update', '-q'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3810
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3811
    def update(self, dest, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3812
        call_subprocess(['hg', 'pull', '-q'], cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3813
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3814
            ['hg', 'update', '-q'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3815
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3816
    def obtain(self, dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3817
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3818
        if rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3819
            rev_options = [rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3820
            rev_display = ' (to revision %s)' % rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3821
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3822
            rev_options = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3823
            rev_display = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3824
        if self.check_destination(dest, url, rev_options, rev_display):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3825
            logger.notify('Cloning hg %s%s to %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3826
                          % (url, rev_display, display_path(dest)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3827
            call_subprocess(['hg', 'clone', '-q', url, dest])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3828
            call_subprocess(['hg', 'update', '-q'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3829
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3830
    def get_url(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3831
        url = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3832
            ['hg', 'showconfig', 'paths.default'],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3833
            show_stdout=False, cwd=location).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3834
        if url.startswith('/') or url.startswith('\\'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3835
            url = filename_to_url(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3836
        return url.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3837
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3838
    def get_tag_revs(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3839
        tags = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3840
            ['hg', 'tags'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3841
        tag_revs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3842
        for line in tags.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3843
            tags_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3844
            if tags_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3845
                tag = tags_match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3846
                rev = tags_match.group(2)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3847
                tag_revs.append((rev.strip(), tag.strip()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3848
        return dict(tag_revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3849
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3850
    def get_branch_revs(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3851
        branches = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3852
            ['hg', 'branches'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3853
        branch_revs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3854
        for line in branches.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3855
            branches_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3856
            if branches_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3857
                branch = branches_match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3858
                rev = branches_match.group(2)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3859
                branch_revs.append((rev.strip(), branch.strip()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3860
        return dict(branch_revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3861
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3862
    def get_revision(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3863
        current_revision = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3864
            ['hg', 'parents', '--template={rev}'],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3865
            show_stdout=False, cwd=location).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3866
        return current_revision
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3867
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3868
    def get_revision_hash(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3869
        current_rev_hash = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3870
            ['hg', 'parents', '--template={node}'],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3871
            show_stdout=False, cwd=location).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3872
        return current_rev_hash
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3873
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3874
    def get_src_requirement(self, dist, location, find_tags):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3875
        repo = self.get_url(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3876
        if not repo.lower().startswith('hg:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3877
            repo = 'hg+' + repo
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3878
        egg_project_name = dist.egg_name().split('-', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3879
        if not repo:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3880
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3881
        current_rev = self.get_revision(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3882
        current_rev_hash = self.get_revision_hash(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3883
        tag_revs = self.get_tag_revs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3884
        branch_revs = self.get_branch_revs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3885
        if current_rev in tag_revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3886
            # It's a tag
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3887
            full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3888
        elif current_rev in branch_revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3889
            # It's the tip of a branch
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3890
            full_egg_name = '%s-%s' % (dist.egg_name(), branch_revs[current_rev])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3891
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3892
            full_egg_name = '%s-dev' % dist.egg_name()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3893
        return '%s@%s#egg=%s' % (repo, current_rev_hash, full_egg_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3894
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3895
vcs.register(Mercurial)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3896
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3897
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3898
class Bazaar(VersionControl):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3899
    name = 'bzr'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3900
    dirname = '.bzr'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3901
    repo_name = 'branch'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3902
    bundle_file = 'bzr-branch.txt'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3903
    schemes = ('bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3904
    guide = ('# This was a Bazaar branch; to make it a branch again run:\n'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3905
             'bzr branch -r %(rev)s %(url)s .\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3906
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3907
    def parse_vcs_bundle_file(self, content):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3908
        url = rev = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3909
        for line in content.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3910
            if not line.strip() or line.strip().startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3911
                continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3912
            match = re.search(r'^bzr\s*branch\s*-r\s*(\d*)', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3913
            if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3914
                rev = match.group(1).strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3915
            url = line[match.end():].strip().split(None, 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3916
            if url and rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3917
                return url, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3918
        return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3919
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3920
    def unpack(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3921
        """Get the bzr branch at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3922
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3923
        logger.notify('Checking out bzr repository %s to %s' % (url, location))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3924
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3925
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3926
            if os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3927
                os.rmdir(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3928
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3929
                [self.cmd, 'branch', url, location],
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3930
                filter_stdout=self._filter, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3931
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3932
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3933
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3934
    def export(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3935
        """Export the Bazaar repository at the url to the destination location"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3936
        temp_dir = tempfile.mkdtemp('-export', 'pip-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3937
        self.unpack(temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3938
        if os.path.exists(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3939
            # Remove the location to make sure Bazaar can export it correctly
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3940
            shutil.rmtree(location, onerror=rmtree_errorhandler)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3941
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3942
            call_subprocess([self.cmd, 'export', location], cwd=temp_dir,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3943
                            filter_stdout=self._filter, show_stdout=False)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3944
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3945
            shutil.rmtree(temp_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3946
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3947
    def switch(self, dest, url, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3948
        call_subprocess([self.cmd, 'switch', url], cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3949
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3950
    def update(self, dest, rev_options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3951
        call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3952
            [self.cmd, 'pull', '-q'] + rev_options, cwd=dest)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3953
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3954
    def obtain(self, dest):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3955
        url, rev = self.get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3956
        if rev:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3957
            rev_options = ['-r', rev]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3958
            rev_display = ' (to revision %s)' % rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3959
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3960
            rev_options = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3961
            rev_display = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3962
        if self.check_destination(dest, url, rev_options, rev_display):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3963
            logger.notify('Checking out %s%s to %s'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3964
                          % (url, rev_display, display_path(dest)))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3965
            call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3966
                [self.cmd, 'branch', '-q'] + rev_options + [url, dest])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3967
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3968
    def get_url_rev(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3969
        # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3970
        url, rev = super(Bazaar, self).get_url_rev()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3971
        if url.startswith('ssh://'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3972
            url = 'bzr+' + url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3973
        return url, rev
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3974
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3975
    def get_url(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3976
        urls = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3977
            [self.cmd, 'info'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3978
        for line in urls.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3979
            line = line.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3980
            for x in ('checkout of branch: ',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3981
                      'parent branch: '):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3982
                if line.startswith(x):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3983
                    return line.split(x)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3984
        return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3985
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3986
    def get_revision(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3987
        revision = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3988
            [self.cmd, 'revno'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3989
        return revision.splitlines()[-1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3990
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3991
    def get_tag_revs(self, location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3992
        tags = call_subprocess(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3993
            [self.cmd, 'tags'], show_stdout=False, cwd=location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3994
        tag_revs = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3995
        for line in tags.splitlines():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3996
            tags_match = re.search(r'([.\w-]+)\s*(.*)$', line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3997
            if tags_match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3998
                tag = tags_match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  3999
                rev = tags_match.group(2)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4000
                tag_revs.append((rev.strip(), tag.strip()))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4001
        return dict(tag_revs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4002
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4003
    def get_src_requirement(self, dist, location, find_tags):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4004
        repo = self.get_url(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4005
        if not repo.lower().startswith('bzr:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4006
            repo = 'bzr+' + repo
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4007
        egg_project_name = dist.egg_name().split('-', 1)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4008
        if not repo:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4009
            return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4010
        current_rev = self.get_revision(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4011
        tag_revs = self.get_tag_revs(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4012
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4013
        if current_rev in tag_revs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4014
            # It's a tag
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4015
            tag = tag_revs.get(current_rev, current_rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4016
            full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4017
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4018
            full_egg_name = '%s-dev_r%s' % (dist.egg_name(), current_rev)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4019
        return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4020
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4021
vcs.register(Bazaar)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4022
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4023
def get_src_requirement(dist, location, find_tags):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4024
    version_control = vcs.get_backend_from_location(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4025
    if version_control:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4026
        return version_control().get_src_requirement(dist, location, find_tags)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4027
    logger.warn('cannot determine version of editable source in %s (is not SVN checkout, Git clone, Mercurial clone or Bazaar branch)' % location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4028
    return dist.as_requirement()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4029
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4030
############################################################
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4031
## Requirement files
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4032
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4033
_scheme_re = re.compile(r'^(http|https|file):', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4034
_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4035
def get_file_content(url, comes_from=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4036
    """Gets the content of a file; it may be a filename, file: URL, or
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4037
    http: URL.  Returns (location, content)"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4038
    match = _scheme_re.search(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4039
    if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4040
        scheme = match.group(1).lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4041
        if (scheme == 'file' and comes_from
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4042
            and comes_from.startswith('http')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4043
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4044
                'Requirements file %s references URL %s, which is local'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4045
                % (comes_from, url))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4046
        if scheme == 'file':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4047
            path = url.split(':', 1)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4048
            path = path.replace('\\', '/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4049
            match = _url_slash_drive_re.match(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4050
            if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4051
                path = match.group(1) + ':' + path.split('|', 1)[1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4052
            path = urllib.unquote(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4053
            if path.startswith('/'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4054
                path = '/' + path.lstrip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4055
            url = path
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4056
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4057
            ## FIXME: catch some errors
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4058
            resp = urllib2.urlopen(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4059
            return resp.geturl(), resp.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4060
    f = open(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4061
    content = f.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4062
    f.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4063
    return url, content
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4064
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4065
def parse_requirements(filename, finder=None, comes_from=None, options=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4066
    skip_match = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4067
    skip_regex = options.skip_requirements_regex
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4068
    if skip_regex:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4069
        skip_match = re.compile(skip_regex)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4070
    filename, content = get_file_content(filename, comes_from=comes_from)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4071
    for line_number, line in enumerate(content.splitlines()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4072
        line_number += 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4073
        line = line.strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4074
        if not line or line.startswith('#'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4075
            continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4076
        if skip_match and skip_match.search(line):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4077
            continue
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4078
        if line.startswith('-r') or line.startswith('--requirement'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4079
            if line.startswith('-r'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4080
                req_url = line[2:].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4081
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4082
                req_url = line[len('--requirement'):].strip().strip('=')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4083
            if _scheme_re.search(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4084
                # Relative to a URL
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4085
                req_url = urlparse.urljoin(filename, url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4086
            elif not _scheme_re.search(req_url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4087
                req_url = os.path.join(os.path.dirname(filename), req_url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4088
            for item in parse_requirements(req_url, finder, comes_from=filename, options=options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4089
                yield item
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4090
        elif line.startswith('-Z') or line.startswith('--always-unzip'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4091
            # No longer used, but previously these were used in
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4092
            # requirement files, so we'll ignore.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4093
            pass
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4094
        elif finder and line.startswith('-f') or line.startswith('--find-links'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4095
            if line.startswith('-f'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4096
                line = line[2:].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4097
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4098
                line = line[len('--find-links'):].strip().lstrip('=')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4099
            ## FIXME: it would be nice to keep track of the source of
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4100
            ## the find_links:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4101
            finder.find_links.append(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4102
        elif line.startswith('-i') or line.startswith('--index-url'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4103
            if line.startswith('-i'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4104
                line = line[2:].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4105
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4106
                line = line[len('--index-url'):].strip().lstrip('=')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4107
            finder.index_urls = [line]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4108
        elif line.startswith('--extra-index-url'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4109
            line = line[len('--extra-index-url'):].strip().lstrip('=')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4110
            finder.index_urls.append(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4111
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4112
            comes_from = '-r %s (line %s)' % (filename, line_number)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4113
            if line.startswith('-e') or line.startswith('--editable'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4114
                if line.startswith('-e'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4115
                    line = line[2:].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4116
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4117
                    line = line[len('--editable'):].strip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4118
                req = InstallRequirement.from_editable(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4119
                    line, comes_from=comes_from, default_vcs=options.default_vcs)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4120
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4121
                req = InstallRequirement.from_line(line, comes_from)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4122
            yield req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4123
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4124
############################################################
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4125
## Logging
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4126
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4127
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4128
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4129
class Logger(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4130
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4131
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4132
    Logging object for use in command-line script.  Allows ranges of
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4133
    levels, to avoid some redundancy of displayed information.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4134
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4135
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4136
    VERBOSE_DEBUG = logging.DEBUG-1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4137
    DEBUG = logging.DEBUG
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4138
    INFO = logging.INFO
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4139
    NOTIFY = (logging.INFO+logging.WARN)/2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4140
    WARN = WARNING = logging.WARN
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4141
    ERROR = logging.ERROR
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4142
    FATAL = logging.FATAL
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4143
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4144
    LEVELS = [VERBOSE_DEBUG, DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4145
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4146
    def __init__(self, consumers):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4147
        self.consumers = consumers
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4148
        self.indent = 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4149
        self.explicit_levels = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4150
        self.in_progress = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4151
        self.in_progress_hanging = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4152
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4153
    def debug(self, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4154
        self.log(self.DEBUG, msg, *args, **kw)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4155
    def info(self, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4156
        self.log(self.INFO, msg, *args, **kw)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4157
    def notify(self, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4158
        self.log(self.NOTIFY, msg, *args, **kw)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4159
    def warn(self, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4160
        self.log(self.WARN, msg, *args, **kw)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4161
    def error(self, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4162
        self.log(self.WARN, msg, *args, **kw)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4163
    def fatal(self, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4164
        self.log(self.FATAL, msg, *args, **kw)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4165
    def log(self, level, msg, *args, **kw):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4166
        if args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4167
            if kw:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4168
                raise TypeError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4169
                    "You may give positional or keyword arguments, not both")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4170
        args = args or kw
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4171
        rendered = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4172
        for consumer_level, consumer in self.consumers:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4173
            if self.level_matches(level, consumer_level):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4174
                if (self.in_progress_hanging
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4175
                    and consumer in (sys.stdout, sys.stderr)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4176
                    self.in_progress_hanging = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4177
                    sys.stdout.write('\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4178
                    sys.stdout.flush()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4179
                if rendered is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4180
                    if args:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4181
                        rendered = msg % args
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4182
                    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4183
                        rendered = msg
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4184
                    rendered = ' '*self.indent + rendered
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4185
                    if self.explicit_levels:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4186
                        ## FIXME: should this be a name, not a level number?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4187
                        rendered = '%02i %s' % (level, rendered)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4188
                if hasattr(consumer, 'write'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4189
                    consumer.write(rendered+'\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4190
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4191
                    consumer(rendered)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4192
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4193
    def start_progress(self, msg):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4194
        assert not self.in_progress, (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4195
            "Tried to start_progress(%r) while in_progress %r"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4196
            % (msg, self.in_progress))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4197
        if self.level_matches(self.NOTIFY, self._stdout_level()):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4198
            sys.stdout.write(' '*self.indent + msg)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4199
            sys.stdout.flush()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4200
            self.in_progress_hanging = True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4201
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4202
            self.in_progress_hanging = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4203
        self.in_progress = msg
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4204
        self.last_message = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4205
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4206
    def end_progress(self, msg='done.'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4207
        assert self.in_progress, (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4208
            "Tried to end_progress without start_progress")
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4209
        if self.stdout_level_matches(self.NOTIFY):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4210
            if not self.in_progress_hanging:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4211
                # Some message has been printed out since start_progress
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4212
                sys.stdout.write('...' + self.in_progress + msg + '\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4213
                sys.stdout.flush()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4214
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4215
                # These erase any messages shown with show_progress (besides .'s)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4216
                logger.show_progress('')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4217
                logger.show_progress('')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4218
                sys.stdout.write(msg + '\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4219
                sys.stdout.flush()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4220
        self.in_progress = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4221
        self.in_progress_hanging = False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4222
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4223
    def show_progress(self, message=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4224
        """If we are in a progress scope, and no log messages have been
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4225
        shown, write out another '.'"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4226
        if self.in_progress_hanging:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4227
            if message is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4228
                sys.stdout.write('.')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4229
                sys.stdout.flush()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4230
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4231
                if self.last_message:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4232
                    padding = ' ' * max(0, len(self.last_message)-len(message))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4233
                else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4234
                    padding = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4235
                sys.stdout.write('\r%s%s%s%s' % (' '*self.indent, self.in_progress, message, padding))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4236
                sys.stdout.flush()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4237
                self.last_message = message
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4238
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4239
    def stdout_level_matches(self, level):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4240
        """Returns true if a message at this level will go to stdout"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4241
        return self.level_matches(level, self._stdout_level())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4242
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4243
    def _stdout_level(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4244
        """Returns the level that stdout runs at"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4245
        for level, consumer in self.consumers:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4246
            if consumer is sys.stdout:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4247
                return level
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4248
        return self.FATAL
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4249
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4250
    def level_matches(self, level, consumer_level):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4251
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4252
        >>> l = Logger()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4253
        >>> l.level_matches(3, 4)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4254
        False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4255
        >>> l.level_matches(3, 2)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4256
        True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4257
        >>> l.level_matches(slice(None, 3), 3)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4258
        False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4259
        >>> l.level_matches(slice(None, 3), 2)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4260
        True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4261
        >>> l.level_matches(slice(1, 3), 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4262
        True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4263
        >>> l.level_matches(slice(2, 3), 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4264
        False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4265
        """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4266
        if isinstance(level, slice):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4267
            start, stop = level.start, level.stop
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4268
            if start is not None and start > consumer_level:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4269
                return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4270
            if stop is not None or stop <= consumer_level:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4271
                return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4272
            return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4273
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4274
            return level >= consumer_level
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4275
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4276
    @classmethod
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4277
    def level_for_integer(cls, level):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4278
        levels = cls.LEVELS
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4279
        if level < 0:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4280
            return levels[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4281
        if level >= len(levels):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4282
            return levels[-1]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4283
        return levels[level]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4284
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4285
    def move_stdout_to_stderr(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4286
        to_remove = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4287
        to_add = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4288
        for consumer_level, consumer in self.consumers:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4289
            if consumer == sys.stdout:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4290
                to_remove.append((consumer_level, consumer))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4291
                to_add.append((consumer_level, sys.stderr))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4292
        for item in to_remove:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4293
            self.consumers.remove(item)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4294
        self.consumers.extend(to_add)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4295
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4296
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4297
def call_subprocess(cmd, show_stdout=True,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4298
                    filter_stdout=None, cwd=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4299
                    raise_on_returncode=True,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4300
                    command_level=Logger.DEBUG, command_desc=None,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4301
                    extra_environ=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4302
    if command_desc is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4303
        cmd_parts = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4304
        for part in cmd:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4305
            if ' ' in part or '\n' in part or '"' in part or "'" in part:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4306
                part = '"%s"' % part.replace('"', '\\"')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4307
            cmd_parts.append(part)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4308
        command_desc = ' '.join(cmd_parts)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4309
    if show_stdout:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4310
        stdout = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4311
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4312
        stdout = subprocess.PIPE
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4313
    logger.log(command_level, "Running command %s" % command_desc)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4314
    env = os.environ.copy()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4315
    if extra_environ:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4316
        env.update(extra_environ)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4317
    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4318
        proc = subprocess.Popen(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4319
            cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4320
            cwd=cwd, env=env)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4321
    except Exception, e:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4322
        logger.fatal(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4323
            "Error %s while executing command %s" % (e, command_desc))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4324
        raise
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4325
    all_output = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4326
    if stdout is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4327
        stdout = proc.stdout
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4328
        while 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4329
            line = stdout.readline()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4330
            if not line:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4331
                break
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4332
            line = line.rstrip()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4333
            all_output.append(line + '\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4334
            if filter_stdout:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4335
                level = filter_stdout(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4336
                if isinstance(level, tuple):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4337
                    level, line = level
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4338
                logger.log(level, line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4339
                if not logger.stdout_level_matches(level):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4340
                    logger.show_progress()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4341
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4342
                logger.info(line)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4343
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4344
        returned_stdout, returned_stderr = proc.communicate()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4345
        all_output = [returned_stdout or '']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4346
    proc.wait()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4347
    if proc.returncode:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4348
        if raise_on_returncode:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4349
            if all_output:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4350
                logger.notify('Complete output from command %s:' % command_desc)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4351
                logger.notify('\n'.join(all_output) + '\n----------------------------------------')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4352
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4353
                "Command %s failed with error code %s"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4354
                % (command_desc, proc.returncode))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4355
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4356
            logger.warn(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4357
                "Command %s had error code %s"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4358
                % (command_desc, proc.returncode))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4359
    if stdout is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4360
        return ''.join(all_output)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4361
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4362
############################################################
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4363
## Utility functions
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4364
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4365
def is_svn_page(html):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4366
    """Returns true if the page appears to be the index page of an svn repository"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4367
    return (re.search(r'<title>[^<]*Revision \d+:', html)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4368
            and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4369
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4370
def file_contents(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4371
    fp = open(filename, 'rb')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4372
    try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4373
        return fp.read()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4374
    finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4375
        fp.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4376
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4377
def split_leading_dir(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4378
    path = str(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4379
    path = path.lstrip('/').lstrip('\\')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4380
    if '/' in path and (('\\' in path and path.find('/') < path.find('\\'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4381
                        or '\\' not in path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4382
        return path.split('/', 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4383
    elif '\\' in path:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4384
        return path.split('\\', 1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4385
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4386
        return path, ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4387
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4388
def has_leading_dir(paths):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4389
    """Returns true if all the paths have the same leading path name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4390
    (i.e., everything is in one subdirectory in an archive)"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4391
    common_prefix = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4392
    for path in paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4393
        prefix, rest = split_leading_dir(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4394
        if not prefix:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4395
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4396
        elif common_prefix is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4397
            common_prefix = prefix
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4398
        elif prefix != common_prefix:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4399
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4400
    return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4401
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4402
def format_size(bytes):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4403
    if bytes > 1000*1000:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4404
        return '%.1fMb' % (bytes/1000.0/1000)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4405
    elif bytes > 10*1000:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4406
        return '%iKb' % (bytes/1000)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4407
    elif bytes > 1000:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4408
        return '%.1fKb' % (bytes/1000.0)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4409
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4410
        return '%ibytes' % bytes
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4411
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4412
_normalize_re = re.compile(r'[^a-z]', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4413
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4414
def normalize_name(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4415
    return _normalize_re.sub('-', name.lower())
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4416
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4417
def make_path_relative(path, rel_to):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4418
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4419
    Make a filename relative, where the filename path, and it is
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4420
    relative to rel_to
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4421
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4422
        >>> make_relative_path('/usr/share/something/a-file.pth',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4423
        ...                    '/usr/share/another-place/src/Directory')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4424
        '../../../something/a-file.pth'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4425
        >>> make_relative_path('/usr/share/something/a-file.pth',
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4426
        ...                    '/home/user/src/Directory')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4427
        '../../../usr/share/something/a-file.pth'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4428
        >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4429
        'a-file.pth'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4430
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4431
    path_filename = os.path.basename(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4432
    path = os.path.dirname(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4433
    path = os.path.normpath(os.path.abspath(path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4434
    rel_to = os.path.normpath(os.path.abspath(rel_to))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4435
    path_parts = path.strip(os.path.sep).split(os.path.sep)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4436
    rel_to_parts = rel_to.strip(os.path.sep).split(os.path.sep)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4437
    while path_parts and rel_to_parts and path_parts[0] == rel_to_parts[0]:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4438
        path_parts.pop(0)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4439
        rel_to_parts.pop(0)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4440
    full_parts = ['..']*len(rel_to_parts) + path_parts + [path_filename]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4441
    if full_parts == ['']:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4442
        return '.' + os.path.sep
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4443
    return os.path.sep.join(full_parts)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4444
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4445
def display_path(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4446
    """Gives the display value for a given path, making it relative to cwd
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4447
    if possible."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4448
    path = os.path.normcase(os.path.abspath(path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4449
    if path.startswith(os.getcwd() + os.path.sep):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4450
        path = '.' + path[len(os.getcwd()):]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4451
    return path
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4452
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4453
def parse_editable(editable_req, default_vcs=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4454
    """Parses svn+http://blahblah@rev#egg=Foobar into a requirement
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4455
    (Foobar) and a URL"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4456
    url = editable_req
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4457
    if os.path.isdir(url) and os.path.exists(os.path.join(url, 'setup.py')):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4458
        # Treating it as code that has already been checked out
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4459
        url = filename_to_url(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4460
    if url.lower().startswith('file:'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4461
        return None, url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4462
    for version_control in vcs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4463
        if url.lower().startswith('%s:' % version_control):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4464
            url = '%s+%s' % (version_control, url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4465
    if '+' not in url:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4466
        if default_vcs:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4467
            url = default_vcs + '+' + url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4468
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4469
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4470
                '--editable=%s should be formatted with svn+URL, git+URL, hg+URL or bzr+URL' % editable_req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4471
    vc_type = url.split('+', 1)[0].lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4472
    if not vcs.get_backend(vc_type):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4473
        raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4474
            'For --editable=%s only svn (svn+URL), Git (git+URL), Mercurial (hg+URL) and Bazaar (bzr+URL) is currently supported' % editable_req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4475
    match = re.search(r'(?:#|#.*?&)egg=([^&]*)', editable_req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4476
    if (not match or not match.group(1)) and vcs.get_backend(vc_type):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4477
        parts = [p for p in editable_req.split('#', 1)[0].split('/') if p]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4478
        if parts[-2] in ('tags', 'branches', 'tag', 'branch'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4479
            req = parts[-3]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4480
        elif parts[-1] == 'trunk':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4481
            req = parts[-2]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4482
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4483
            raise InstallationError(
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4484
                '--editable=%s is not the right format; it must have #egg=Package'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4485
                % editable_req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4486
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4487
        req = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4488
    ## FIXME: use package_to_requirement?
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4489
    match = re.search(r'^(.*?)(?:-dev|-\d.*)', req)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4490
    if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4491
        # Strip off -dev, -0.2, etc.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4492
        req = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4493
    return req, url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4494
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4495
def backup_dir(dir, ext='.bak'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4496
    """Figure out the name of a directory to back up the given dir to
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4497
    (adding .bak, .bak2, etc)"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4498
    n = 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4499
    extension = ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4500
    while os.path.exists(dir + extension):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4501
        n += 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4502
        extension = ext + str(n)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4503
    return dir + extension
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4504
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4505
def ask(message, options):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4506
    """Ask the message interactively, with the given possible responses"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4507
    while 1:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4508
        if os.environ.get('PIP_NO_INPUT'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4509
            raise Exception('No input was expected ($PIP_NO_INPUT set); question: %s' % message)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4510
        response = raw_input(message)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4511
        response = response.strip().lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4512
        if response not in options:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4513
            print 'Your response (%r) was not one of the expected responses: %s' % (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4514
                response, ', '.join(options))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4515
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4516
            return response
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4517
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4518
def open_logfile_append(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4519
    """Open the named log file in append mode.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4520
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4521
    If the file already exists, a separator will also be printed to
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4522
    the file to separate past activity from current activity.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4523
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4524
    exists = os.path.exists(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4525
    log_fp = open(filename, 'a')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4526
    if exists:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4527
        print >> log_fp, '-'*60
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4528
        print >> log_fp, '%s run on %s' % (sys.argv[0], time.strftime('%c'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4529
    return log_fp
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4530
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4531
def is_url(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4532
    """Returns true if the name looks like a URL"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4533
    if ':' not in name:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4534
        return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4535
    scheme = name.split(':', 1)[0].lower()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4536
    return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4537
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4538
def is_filename(name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4539
    if (splitext(name)[1].lower() in ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.pybundle')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4540
        and os.path.exists(name)):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4541
        return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4542
    if os.path.sep not in name and '/' not in name:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4543
        # Doesn't have any path components, probably a requirement like 'Foo'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4544
        return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4545
    return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4546
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4547
_drive_re = re.compile('^([a-z]):', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4548
_url_drive_re = re.compile('^([a-z])[:|]', re.I)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4549
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4550
def filename_to_url(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4551
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4552
    Convert a path to a file: URL.  The path will be made absolute.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4553
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4554
    filename = os.path.normcase(os.path.abspath(filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4555
    if _drive_re.match(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4556
        filename = filename[0] + '|' + filename[2:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4557
    url = urllib.quote(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4558
    url = url.replace(os.path.sep, '/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4559
    url = url.lstrip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4560
    return 'file:///' + url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4561
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4562
def filename_to_url2(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4563
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4564
    Convert a path to a file: URL.  The path will be made absolute and have
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4565
    quoted path parts.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4566
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4567
    filename = os.path.normcase(os.path.abspath(filename))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4568
    drive, filename = os.path.splitdrive(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4569
    filepath = filename.split(os.path.sep)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4570
    url = '/'.join([urllib.quote(part) for part in filepath])
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4571
    if not drive:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4572
        url = url.lstrip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4573
    return 'file:///' + drive + url
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4574
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4575
def url_to_filename(url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4576
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4577
    Convert a file: URL to a path.
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4578
    """
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4579
    assert url.startswith('file:'), (
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4580
        "You can only turn file: urls into filenames (not %r)" % url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4581
    filename = url[len('file:'):].lstrip('/')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4582
    filename = urllib.unquote(filename)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4583
    if _url_drive_re.match(filename):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4584
        filename = filename[0] + ':' + filename[2:]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4585
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4586
        filename = '/' + filename
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4587
    return filename
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4588
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4589
def get_requirement_from_url(url):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4590
    """Get a requirement from the URL, if possible.  This looks for #egg
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4591
    in the URL"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4592
    link = Link(url)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4593
    egg_info = link.egg_fragment
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4594
    if not egg_info:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4595
        egg_info = splitext(link.filename)[0]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4596
    return package_to_requirement(egg_info)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4597
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4598
def package_to_requirement(package_name):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4599
    """Translate a name like Foo-1.2 to Foo==1.3"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4600
    match = re.search(r'^(.*?)(-dev|-\d.*)', package_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4601
    if match:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4602
        name = match.group(1)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4603
        version = match.group(2)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4604
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4605
        name = package_name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4606
        version = ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4607
    if version:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4608
        return '%s==%s' % (name, version)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4609
    else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4610
        return name
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4611
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4612
def is_framework_layout(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4613
    """Return True if the current platform is the default Python of Mac OS X
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4614
    which installs scripts in /usr/local/bin"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4615
    return (sys.platform[:6] == 'darwin' and
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4616
            (path[:9] == '/Library/' or path[:16] == '/System/Library/'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4617
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4618
def strip_prefix(path, prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4619
    """ If ``path`` begins with ``prefix``, return ``path`` with
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4620
    ``prefix`` stripped off.  Otherwise return None."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4621
    prefixes = [prefix]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4622
    # Yep, we are special casing the framework layout of MacPython here
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4623
    if is_framework_layout(sys.prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4624
        for location in ('/Library', '/usr/local'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4625
            if path.startswith(location):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4626
                prefixes.append(location)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4627
    for prefix in prefixes:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4628
        if path.startswith(prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4629
            return prefix, path.replace(prefix + os.path.sep, '')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4630
    return None, None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4631
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4632
class UninstallPathSet(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4633
    """A set of file paths to be removed in the uninstallation of a
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4634
    requirement."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4635
    def __init__(self, dist, restrict_to_prefix):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4636
        self.paths = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4637
        self._refuse = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4638
        self.pth = {}
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4639
        self.prefix = os.path.normcase(os.path.realpath(restrict_to_prefix))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4640
        self.dist = dist
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4641
        self.location = dist.location
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4642
        self.save_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4643
        self._moved_paths = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4644
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4645
    def _can_uninstall(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4646
        prefix, stripped = strip_prefix(self.location, self.prefix)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4647
        if not stripped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4648
            logger.notify("Not uninstalling %s at %s, outside environment %s"
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4649
                          % (self.dist.project_name, self.dist.location,
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4650
                             self.prefix))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4651
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4652
        return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4653
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4654
    def add(self, path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4655
        path = os.path.abspath(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4656
        if not os.path.exists(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4657
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4658
        prefix, stripped = strip_prefix(os.path.normcase(path), self.prefix)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4659
        if stripped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4660
            self.paths.add((prefix, stripped))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4661
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4662
            self._refuse.add((prefix, path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4663
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4664
    def add_pth(self, pth_file, entry):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4665
        prefix, stripped = strip_prefix(os.path.normcase(pth_file), self.prefix)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4666
        if stripped:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4667
            entry = os.path.normcase(entry)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4668
            if stripped not in self.pth:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4669
                self.pth[stripped] = UninstallPthEntries(os.path.join(prefix, stripped))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4670
            self.pth[stripped].add(os.path.normcase(entry))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4671
        else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4672
            self._refuse.add((prefix, pth_file))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4673
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4674
    def compact(self, paths):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4675
        """Compact a path set to contain the minimal number of paths
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4676
        necessary to contain all paths in the set. If /a/path/ and
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4677
        /a/path/to/a/file.txt are both in the set, leave only the
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4678
        shorter path."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4679
        short_paths = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4680
        def sort_set(x, y):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4681
            prefix_x, path_x = x
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4682
            prefix_y, path_y = y
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4683
            return cmp(len(path_x), len(path_y))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4684
        for prefix, path in sorted(paths, sort_set):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4685
            if not any([(path.startswith(shortpath) and
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4686
                         path[len(shortpath.rstrip(os.path.sep))] == os.path.sep)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4687
                        for shortprefix, shortpath in short_paths]):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4688
                short_paths.add((prefix, path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4689
        return short_paths
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4690
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4691
    def remove(self, auto_confirm=False):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4692
        """Remove paths in ``self.paths`` with confirmation (unless
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4693
        ``auto_confirm`` is True)."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4694
        if not self._can_uninstall():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4695
            return
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4696
        logger.notify('Uninstalling %s:' % self.dist.project_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4697
        logger.indent += 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4698
        paths = sorted(self.compact(self.paths))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4699
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4700
            if auto_confirm:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4701
                response = 'y'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4702
            else:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4703
                for prefix, path in paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4704
                    logger.notify(os.path.join(prefix, path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4705
                response = ask('Proceed (y/n)? ', ('y', 'n'))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4706
            if self._refuse:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4707
                logger.notify('Not removing or modifying (outside of prefix):')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4708
                for prefix, path in self.compact(self._refuse):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4709
                    logger.notify(os.path.join(prefix, path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4710
            if response == 'y':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4711
                self.save_dir = tempfile.mkdtemp('-uninstall', 'pip-')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4712
                for prefix, path in paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4713
                    full_path = os.path.join(prefix, path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4714
                    new_path = os.path.join(self.save_dir, path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4715
                    new_dir = os.path.dirname(new_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4716
                    logger.info('Removing file or directory %s' % full_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4717
                    self._moved_paths.append((prefix, path))
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4718
                    os.renames(full_path, new_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4719
                for pth in self.pth.values():
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4720
                    pth.remove()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4721
                logger.notify('Successfully uninstalled %s' % self.dist.project_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4722
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4723
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4724
            logger.indent -= 2
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4725
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4726
    def rollback(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4727
        """Rollback the changes previously made by remove()."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4728
        if self.save_dir is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4729
            logger.error("Can't roll back %s; was not uninstalled" % self.dist.project_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4730
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4731
        logger.notify('Rolling back uninstall of %s' % self.dist.project_name)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4732
        for prefix, path in self._moved_paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4733
            tmp_path = os.path.join(self.save_dir, path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4734
            real_path = os.path.join(prefix, path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4735
            logger.info('Replacing %s' % real_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4736
            os.renames(tmp_path, real_path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4737
        for pth in self.pth:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4738
            pth.rollback()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4739
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4740
    def commit(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4741
        """Remove temporary save dir: rollback will no longer be possible."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4742
        if self.save_dir is not None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4743
            shutil.rmtree(self.save_dir)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4744
            self.save_dir = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4745
            self._moved_paths = []
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4746
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4747
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4748
class UninstallPthEntries(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4749
    def __init__(self, pth_file):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4750
        if not os.path.isfile(pth_file):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4751
            raise UninstallationError("Cannot remove entries from nonexistent file %s" % pth_file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4752
        self.file = pth_file
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4753
        self.entries = set()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4754
        self._saved_lines = None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4755
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4756
    def add(self, entry):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4757
        self.entries.add(entry)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4758
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4759
    def remove(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4760
        logger.info('Removing pth entries from %s:' % self.file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4761
        fh = open(self.file, 'r')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4762
        lines = fh.readlines()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4763
        self._saved_lines = lines
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4764
        fh.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4765
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4766
            for entry in self.entries:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4767
                logger.info('Removing entry: %s' % entry)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4768
            try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4769
                lines.remove(entry + '\n')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4770
            except ValueError:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4771
                pass
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4772
        finally:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4773
            pass
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4774
        fh = open(self.file, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4775
        fh.writelines(lines)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4776
        fh.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4777
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4778
    def rollback(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4779
        if self._saved_lines is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4780
            logger.error('Cannot roll back changes to %s, none were made' % self.file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4781
            return False
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4782
        logger.info('Rolling %s back to previous state' % self.file)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4783
        fh = open(self.file, 'w')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4784
        fh.writelines(self._saved_lines)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4785
        fh.close()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4786
        return True
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4787
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4788
class FakeFile(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4789
    """Wrap a list of lines in an object with readline() to make
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4790
    ConfigParser happy."""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4791
    def __init__(self, lines):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4792
        self._gen = (l for l in lines)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4793
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4794
    def readline(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4795
        try:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4796
            return self._gen.next()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4797
        except StopIteration:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4798
            return ''
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4799
    
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4800
def splitext(path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4801
    """Like os.path.splitext, but take off .tar too"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4802
    base, ext = posixpath.splitext(path)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4803
    if base.lower().endswith('.tar'):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4804
        ext = base[-4:] + ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4805
        base = base[:-4]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4806
    return base, ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4807
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4808
def find_command(cmd, paths=None, pathext=None):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4809
    """Searches the PATH for the given command and returns its path"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4810
    if paths is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4811
        paths = os.environ.get('PATH', []).split(os.pathsep)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4812
    if isinstance(paths, basestring):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4813
        paths = [paths]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4814
    # check if there are funny path extensions for executables, e.g. Windows
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4815
    if pathext is None:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4816
        pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4817
    pathext = [ext for ext in pathext.lower().split(os.pathsep)]
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4818
    # don't use extensions if the command ends with one of them
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4819
    if os.path.splitext(cmd)[1].lower() in pathext:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4820
        pathext = ['']
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4821
    # check if we find the command on PATH
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4822
    for path in paths:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4823
        # try without extension first
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4824
        cmd_path = os.path.join(path, cmd)
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4825
        for ext in pathext:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4826
            # then including the extension
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4827
            cmd_path_ext = cmd_path + ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4828
            if os.path.exists(cmd_path_ext):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4829
                return cmd_path_ext
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4830
        if os.path.exists(cmd_path):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4831
            return cmd_path
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4832
    return None
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4833
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4834
class _Inf(object):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4835
    """I am bigger than everything!"""
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4836
    def __cmp__(self, a):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4837
        if self is a:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4838
            return 0
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4839
        return 1
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4840
    def __repr__(self):
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4841
        return 'Inf'
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4842
Inf = _Inf()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4843
del _Inf
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4844
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4845
if __name__ == '__main__':
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4846
    exit = main()
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4847
    if exit:
6cee07c589cb Changes in path of some of the files ...
amit@thunder
parents:
diff changeset
  4848
        sys.exit(exit)