Statistics
| Branch: | Tag: | Revision:

root / snf-branding / distribute_setup.py @ 42255095

History | View | Annotate | Download (15.4 kB)

1 9d889386 Olga Brani
#!python
2 9d889386 Olga Brani
"""Bootstrap distribute installation
3 9d889386 Olga Brani

4 9d889386 Olga Brani
If you want to use setuptools in your package's setup.py, just include this
5 9d889386 Olga Brani
file in the same directory with it, and add this to the top of your setup.py::
6 9d889386 Olga Brani

7 9d889386 Olga Brani
    from distribute_setup import use_setuptools
8 9d889386 Olga Brani
    use_setuptools()
9 9d889386 Olga Brani

10 9d889386 Olga Brani
If you want to require a specific version of setuptools, set a download
11 9d889386 Olga Brani
mirror, or use an alternate download directory, you can do so by supplying
12 9d889386 Olga Brani
the appropriate options to ``use_setuptools()``.
13 9d889386 Olga Brani

14 9d889386 Olga Brani
This file can also be run as a script to install or upgrade setuptools.
15 9d889386 Olga Brani
"""
16 9d889386 Olga Brani
import os
17 9d889386 Olga Brani
import sys
18 9d889386 Olga Brani
import time
19 9d889386 Olga Brani
import fnmatch
20 9d889386 Olga Brani
import tempfile
21 9d889386 Olga Brani
import tarfile
22 9d889386 Olga Brani
from distutils import log
23 9d889386 Olga Brani
24 9d889386 Olga Brani
try:
25 9d889386 Olga Brani
    from site import USER_SITE
26 9d889386 Olga Brani
except ImportError:
27 9d889386 Olga Brani
    USER_SITE = None
28 9d889386 Olga Brani
29 9d889386 Olga Brani
try:
30 9d889386 Olga Brani
    import subprocess
31 9d889386 Olga Brani
32 9d889386 Olga Brani
    def _python_cmd(*args):
33 9d889386 Olga Brani
        args = (sys.executable,) + args
34 9d889386 Olga Brani
        return subprocess.call(args) == 0
35 9d889386 Olga Brani
36 9d889386 Olga Brani
except ImportError:
37 9d889386 Olga Brani
    # will be used for python 2.3
38 9d889386 Olga Brani
    def _python_cmd(*args):
39 9d889386 Olga Brani
        args = (sys.executable,) + args
40 9d889386 Olga Brani
        # quoting arguments if windows
41 9d889386 Olga Brani
        if sys.platform == 'win32':
42 9d889386 Olga Brani
            def quote(arg):
43 9d889386 Olga Brani
                if ' ' in arg:
44 9d889386 Olga Brani
                    return '"%s"' % arg
45 9d889386 Olga Brani
                return arg
46 9d889386 Olga Brani
            args = [quote(arg) for arg in args]
47 9d889386 Olga Brani
        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
48 9d889386 Olga Brani
49 9d889386 Olga Brani
DEFAULT_VERSION = "0.6.10"
50 9d889386 Olga Brani
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
51 9d889386 Olga Brani
SETUPTOOLS_FAKED_VERSION = "0.6c11"
52 9d889386 Olga Brani
53 9d889386 Olga Brani
SETUPTOOLS_PKG_INFO = """\
54 9d889386 Olga Brani
Metadata-Version: 1.0
55 9d889386 Olga Brani
Name: setuptools
56 9d889386 Olga Brani
Version: %s
57 9d889386 Olga Brani
Summary: xxxx
58 9d889386 Olga Brani
Home-page: xxx
59 9d889386 Olga Brani
Author: xxx
60 9d889386 Olga Brani
Author-email: xxx
61 9d889386 Olga Brani
License: xxx
62 9d889386 Olga Brani
Description: xxx
63 9d889386 Olga Brani
""" % SETUPTOOLS_FAKED_VERSION
64 9d889386 Olga Brani
65 9d889386 Olga Brani
66 9d889386 Olga Brani
def _install(tarball):
67 9d889386 Olga Brani
    # extracting the tarball
68 9d889386 Olga Brani
    tmpdir = tempfile.mkdtemp()
69 9d889386 Olga Brani
    log.warn('Extracting in %s', tmpdir)
70 9d889386 Olga Brani
    old_wd = os.getcwd()
71 9d889386 Olga Brani
    try:
72 9d889386 Olga Brani
        os.chdir(tmpdir)
73 9d889386 Olga Brani
        tar = tarfile.open(tarball)
74 9d889386 Olga Brani
        _extractall(tar)
75 9d889386 Olga Brani
        tar.close()
76 9d889386 Olga Brani
77 9d889386 Olga Brani
        # going in the directory
78 9d889386 Olga Brani
        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
79 9d889386 Olga Brani
        os.chdir(subdir)
80 9d889386 Olga Brani
        log.warn('Now working in %s', subdir)
81 9d889386 Olga Brani
82 9d889386 Olga Brani
        # installing
83 9d889386 Olga Brani
        log.warn('Installing Distribute')
84 9d889386 Olga Brani
        if not _python_cmd('setup.py', 'install'):
85 9d889386 Olga Brani
            log.warn('Something went wrong during the installation.')
86 9d889386 Olga Brani
            log.warn('See the error message above.')
87 9d889386 Olga Brani
    finally:
88 9d889386 Olga Brani
        os.chdir(old_wd)
89 9d889386 Olga Brani
90 9d889386 Olga Brani
91 9d889386 Olga Brani
def _build_egg(egg, tarball, to_dir):
92 9d889386 Olga Brani
    # extracting the tarball
93 9d889386 Olga Brani
    tmpdir = tempfile.mkdtemp()
94 9d889386 Olga Brani
    log.warn('Extracting in %s', tmpdir)
95 9d889386 Olga Brani
    old_wd = os.getcwd()
96 9d889386 Olga Brani
    try:
97 9d889386 Olga Brani
        os.chdir(tmpdir)
98 9d889386 Olga Brani
        tar = tarfile.open(tarball)
99 9d889386 Olga Brani
        _extractall(tar)
100 9d889386 Olga Brani
        tar.close()
101 9d889386 Olga Brani
102 9d889386 Olga Brani
        # going in the directory
103 9d889386 Olga Brani
        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
104 9d889386 Olga Brani
        os.chdir(subdir)
105 9d889386 Olga Brani
        log.warn('Now working in %s', subdir)
106 9d889386 Olga Brani
107 9d889386 Olga Brani
        # building an egg
108 9d889386 Olga Brani
        log.warn('Building a Distribute egg in %s', to_dir)
109 9d889386 Olga Brani
        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
110 9d889386 Olga Brani
111 9d889386 Olga Brani
    finally:
112 9d889386 Olga Brani
        os.chdir(old_wd)
113 9d889386 Olga Brani
    # returning the result
114 9d889386 Olga Brani
    log.warn(egg)
115 9d889386 Olga Brani
    if not os.path.exists(egg):
116 9d889386 Olga Brani
        raise IOError('Could not build the egg.')
117 9d889386 Olga Brani
118 9d889386 Olga Brani
119 9d889386 Olga Brani
def _do_download(version, download_base, to_dir, download_delay):
120 9d889386 Olga Brani
    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
121 9d889386 Olga Brani
                       % (version, sys.version_info[0], sys.version_info[1]))
122 9d889386 Olga Brani
    if not os.path.exists(egg):
123 9d889386 Olga Brani
        tarball = download_setuptools(version, download_base,
124 9d889386 Olga Brani
                                      to_dir, download_delay)
125 9d889386 Olga Brani
        _build_egg(egg, tarball, to_dir)
126 9d889386 Olga Brani
    sys.path.insert(0, egg)
127 9d889386 Olga Brani
    import setuptools
128 9d889386 Olga Brani
    setuptools.bootstrap_install_from = egg
129 9d889386 Olga Brani
130 9d889386 Olga Brani
131 9d889386 Olga Brani
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
132 9d889386 Olga Brani
                   to_dir=os.curdir, download_delay=15, no_fake=True):
133 9d889386 Olga Brani
    # making sure we use the absolute path
134 9d889386 Olga Brani
    to_dir = os.path.abspath(to_dir)
135 9d889386 Olga Brani
    was_imported = 'pkg_resources' in sys.modules or \
136 9d889386 Olga Brani
        'setuptools' in sys.modules
137 9d889386 Olga Brani
    try:
138 9d889386 Olga Brani
        try:
139 9d889386 Olga Brani
            import pkg_resources
140 9d889386 Olga Brani
            if not hasattr(pkg_resources, '_distribute'):
141 9d889386 Olga Brani
                if not no_fake:
142 9d889386 Olga Brani
                    _fake_setuptools()
143 9d889386 Olga Brani
                raise ImportError
144 9d889386 Olga Brani
        except ImportError:
145 9d889386 Olga Brani
            return _do_download(version, download_base, to_dir, download_delay)
146 9d889386 Olga Brani
        try:
147 9d889386 Olga Brani
            pkg_resources.require("distribute>="+version)
148 9d889386 Olga Brani
            return
149 9d889386 Olga Brani
        except pkg_resources.VersionConflict:
150 9d889386 Olga Brani
            e = sys.exc_info()[1]
151 9d889386 Olga Brani
            if was_imported:
152 9d889386 Olga Brani
                sys.stderr.write(
153 9d889386 Olga Brani
                "The required version of distribute (>=%s) is not available,\n"
154 9d889386 Olga Brani
                "and can't be installed while this script is running. Please\n"
155 9d889386 Olga Brani
                "install a more recent version first, using\n"
156 9d889386 Olga Brani
                "'easy_install -U distribute'."
157 9d889386 Olga Brani
                "\n\n(Currently using %r)\n" % (version, e.args[0]))
158 9d889386 Olga Brani
                sys.exit(2)
159 9d889386 Olga Brani
            else:
160 9d889386 Olga Brani
                del pkg_resources, sys.modules['pkg_resources']    # reload ok
161 9d889386 Olga Brani
                return _do_download(version, download_base, to_dir,
162 9d889386 Olga Brani
                                    download_delay)
163 9d889386 Olga Brani
        except pkg_resources.DistributionNotFound:
164 9d889386 Olga Brani
            return _do_download(version, download_base, to_dir,
165 9d889386 Olga Brani
                                download_delay)
166 9d889386 Olga Brani
    finally:
167 9d889386 Olga Brani
        if not no_fake:
168 9d889386 Olga Brani
            _create_fake_setuptools_pkg_info(to_dir)
169 9d889386 Olga Brani
170 9d889386 Olga Brani
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
171 9d889386 Olga Brani
                        to_dir=os.curdir, delay=15):
172 9d889386 Olga Brani
    """Download distribute from a specified location and return its filename
173 9d889386 Olga Brani

174 9d889386 Olga Brani
    `version` should be a valid distribute version number that is available
175 9d889386 Olga Brani
    as an egg for download under the `download_base` URL (which should end
176 9d889386 Olga Brani
    with a '/'). `to_dir` is the directory where the egg will be downloaded.
177 9d889386 Olga Brani
    `delay` is the number of seconds to pause before an actual download
178 9d889386 Olga Brani
    attempt.
179 9d889386 Olga Brani
    """
180 9d889386 Olga Brani
    # making sure we use the absolute path
181 9d889386 Olga Brani
    to_dir = os.path.abspath(to_dir)
182 9d889386 Olga Brani
    try:
183 9d889386 Olga Brani
        from urllib.request import urlopen
184 9d889386 Olga Brani
    except ImportError:
185 9d889386 Olga Brani
        from urllib2 import urlopen
186 9d889386 Olga Brani
    tgz_name = "distribute-%s.tar.gz" % version
187 9d889386 Olga Brani
    url = download_base + tgz_name
188 9d889386 Olga Brani
    saveto = os.path.join(to_dir, tgz_name)
189 9d889386 Olga Brani
    src = dst = None
190 9d889386 Olga Brani
    if not os.path.exists(saveto):  # Avoid repeated downloads
191 9d889386 Olga Brani
        try:
192 9d889386 Olga Brani
            log.warn("Downloading %s", url)
193 9d889386 Olga Brani
            src = urlopen(url)
194 9d889386 Olga Brani
            # Read/write all in one block, so we don't create a corrupt file
195 9d889386 Olga Brani
            # if the download is interrupted.
196 9d889386 Olga Brani
            data = src.read()
197 9d889386 Olga Brani
            dst = open(saveto, "wb")
198 9d889386 Olga Brani
            dst.write(data)
199 9d889386 Olga Brani
        finally:
200 9d889386 Olga Brani
            if src:
201 9d889386 Olga Brani
                src.close()
202 9d889386 Olga Brani
            if dst:
203 9d889386 Olga Brani
                dst.close()
204 9d889386 Olga Brani
    return os.path.realpath(saveto)
205 9d889386 Olga Brani
206 9d889386 Olga Brani
def _no_sandbox(function):
207 9d889386 Olga Brani
    def __no_sandbox(*args, **kw):
208 9d889386 Olga Brani
        try:
209 9d889386 Olga Brani
            from setuptools.sandbox import DirectorySandbox
210 9d889386 Olga Brani
            if not hasattr(DirectorySandbox, '_old'):
211 9d889386 Olga Brani
                def violation(*args):
212 9d889386 Olga Brani
                    pass
213 9d889386 Olga Brani
                DirectorySandbox._old = DirectorySandbox._violation
214 9d889386 Olga Brani
                DirectorySandbox._violation = violation
215 9d889386 Olga Brani
                patched = True
216 9d889386 Olga Brani
            else:
217 9d889386 Olga Brani
                patched = False
218 9d889386 Olga Brani
        except ImportError:
219 9d889386 Olga Brani
            patched = False
220 9d889386 Olga Brani
221 9d889386 Olga Brani
        try:
222 9d889386 Olga Brani
            return function(*args, **kw)
223 9d889386 Olga Brani
        finally:
224 9d889386 Olga Brani
            if patched:
225 9d889386 Olga Brani
                DirectorySandbox._violation = DirectorySandbox._old
226 9d889386 Olga Brani
                del DirectorySandbox._old
227 9d889386 Olga Brani
228 9d889386 Olga Brani
    return __no_sandbox
229 9d889386 Olga Brani
230 9d889386 Olga Brani
def _patch_file(path, content):
231 9d889386 Olga Brani
    """Will backup the file then patch it"""
232 9d889386 Olga Brani
    existing_content = open(path).read()
233 9d889386 Olga Brani
    if existing_content == content:
234 9d889386 Olga Brani
        # already patched
235 9d889386 Olga Brani
        log.warn('Already patched.')
236 9d889386 Olga Brani
        return False
237 9d889386 Olga Brani
    log.warn('Patching...')
238 9d889386 Olga Brani
    _rename_path(path)
239 9d889386 Olga Brani
    f = open(path, 'w')
240 9d889386 Olga Brani
    try:
241 9d889386 Olga Brani
        f.write(content)
242 9d889386 Olga Brani
    finally:
243 9d889386 Olga Brani
        f.close()
244 9d889386 Olga Brani
    return True
245 9d889386 Olga Brani
246 9d889386 Olga Brani
_patch_file = _no_sandbox(_patch_file)
247 9d889386 Olga Brani
248 9d889386 Olga Brani
def _same_content(path, content):
249 9d889386 Olga Brani
    return open(path).read() == content
250 9d889386 Olga Brani
251 9d889386 Olga Brani
def _rename_path(path):
252 9d889386 Olga Brani
    new_name = path + '.OLD.%s' % time.time()
253 9d889386 Olga Brani
    log.warn('Renaming %s into %s', path, new_name)
254 9d889386 Olga Brani
    os.rename(path, new_name)
255 9d889386 Olga Brani
    return new_name
256 9d889386 Olga Brani
257 9d889386 Olga Brani
def _remove_flat_installation(placeholder):
258 9d889386 Olga Brani
    if not os.path.isdir(placeholder):
259 9d889386 Olga Brani
        log.warn('Unkown installation at %s', placeholder)
260 9d889386 Olga Brani
        return False
261 9d889386 Olga Brani
    found = False
262 9d889386 Olga Brani
    for file in os.listdir(placeholder):
263 9d889386 Olga Brani
        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
264 9d889386 Olga Brani
            found = True
265 9d889386 Olga Brani
            break
266 9d889386 Olga Brani
    if not found:
267 9d889386 Olga Brani
        log.warn('Could not locate setuptools*.egg-info')
268 9d889386 Olga Brani
        return
269 9d889386 Olga Brani
270 9d889386 Olga Brani
    log.warn('Removing elements out of the way...')
271 9d889386 Olga Brani
    pkg_info = os.path.join(placeholder, file)
272 9d889386 Olga Brani
    if os.path.isdir(pkg_info):
273 9d889386 Olga Brani
        patched = _patch_egg_dir(pkg_info)
274 9d889386 Olga Brani
    else:
275 9d889386 Olga Brani
        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
276 9d889386 Olga Brani
277 9d889386 Olga Brani
    if not patched:
278 9d889386 Olga Brani
        log.warn('%s already patched.', pkg_info)
279 9d889386 Olga Brani
        return False
280 9d889386 Olga Brani
    # now let's move the files out of the way
281 9d889386 Olga Brani
    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
282 9d889386 Olga Brani
        element = os.path.join(placeholder, element)
283 9d889386 Olga Brani
        if os.path.exists(element):
284 9d889386 Olga Brani
            _rename_path(element)
285 9d889386 Olga Brani
        else:
286 9d889386 Olga Brani
            log.warn('Could not find the %s element of the '
287 9d889386 Olga Brani
                     'Setuptools distribution', element)
288 9d889386 Olga Brani
    return True
289 9d889386 Olga Brani
290 9d889386 Olga Brani
_remove_flat_installation = _no_sandbox(_remove_flat_installation)
291 9d889386 Olga Brani
292 9d889386 Olga Brani
def _after_install(dist):
293 9d889386 Olga Brani
    log.warn('After install bootstrap.')
294 9d889386 Olga Brani
    placeholder = dist.get_command_obj('install').install_purelib
295 9d889386 Olga Brani
    _create_fake_setuptools_pkg_info(placeholder)
296 9d889386 Olga Brani
297 9d889386 Olga Brani
def _create_fake_setuptools_pkg_info(placeholder):
298 9d889386 Olga Brani
    if not placeholder or not os.path.exists(placeholder):
299 9d889386 Olga Brani
        log.warn('Could not find the install location')
300 9d889386 Olga Brani
        return
301 9d889386 Olga Brani
    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
302 9d889386 Olga Brani
    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
303 9d889386 Olga Brani
            (SETUPTOOLS_FAKED_VERSION, pyver)
304 9d889386 Olga Brani
    pkg_info = os.path.join(placeholder, setuptools_file)
305 9d889386 Olga Brani
    if os.path.exists(pkg_info):
306 9d889386 Olga Brani
        log.warn('%s already exists', pkg_info)
307 9d889386 Olga Brani
        return
308 9d889386 Olga Brani
309 9d889386 Olga Brani
    log.warn('Creating %s', pkg_info)
310 9d889386 Olga Brani
    f = open(pkg_info, 'w')
311 9d889386 Olga Brani
    try:
312 9d889386 Olga Brani
        f.write(SETUPTOOLS_PKG_INFO)
313 9d889386 Olga Brani
    finally:
314 9d889386 Olga Brani
        f.close()
315 9d889386 Olga Brani
316 9d889386 Olga Brani
    pth_file = os.path.join(placeholder, 'setuptools.pth')
317 9d889386 Olga Brani
    log.warn('Creating %s', pth_file)
318 9d889386 Olga Brani
    f = open(pth_file, 'w')
319 9d889386 Olga Brani
    try:
320 9d889386 Olga Brani
        f.write(os.path.join(os.curdir, setuptools_file))
321 9d889386 Olga Brani
    finally:
322 9d889386 Olga Brani
        f.close()
323 9d889386 Olga Brani
324 9d889386 Olga Brani
_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
325 9d889386 Olga Brani
326 9d889386 Olga Brani
def _patch_egg_dir(path):
327 9d889386 Olga Brani
    # let's check if it's already patched
328 9d889386 Olga Brani
    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
329 9d889386 Olga Brani
    if os.path.exists(pkg_info):
330 9d889386 Olga Brani
        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
331 9d889386 Olga Brani
            log.warn('%s already patched.', pkg_info)
332 9d889386 Olga Brani
            return False
333 9d889386 Olga Brani
    _rename_path(path)
334 9d889386 Olga Brani
    os.mkdir(path)
335 9d889386 Olga Brani
    os.mkdir(os.path.join(path, 'EGG-INFO'))
336 9d889386 Olga Brani
    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
337 9d889386 Olga Brani
    f = open(pkg_info, 'w')
338 9d889386 Olga Brani
    try:
339 9d889386 Olga Brani
        f.write(SETUPTOOLS_PKG_INFO)
340 9d889386 Olga Brani
    finally:
341 9d889386 Olga Brani
        f.close()
342 9d889386 Olga Brani
    return True
343 9d889386 Olga Brani
344 9d889386 Olga Brani
_patch_egg_dir = _no_sandbox(_patch_egg_dir)
345 9d889386 Olga Brani
346 9d889386 Olga Brani
def _before_install():
347 9d889386 Olga Brani
    log.warn('Before install bootstrap.')
348 9d889386 Olga Brani
    _fake_setuptools()
349 9d889386 Olga Brani
350 9d889386 Olga Brani
351 9d889386 Olga Brani
def _under_prefix(location):
352 9d889386 Olga Brani
    if 'install' not in sys.argv:
353 9d889386 Olga Brani
        return True
354 9d889386 Olga Brani
    args = sys.argv[sys.argv.index('install')+1:]
355 9d889386 Olga Brani
    for index, arg in enumerate(args):
356 9d889386 Olga Brani
        for option in ('--root', '--prefix'):
357 9d889386 Olga Brani
            if arg.startswith('%s=' % option):
358 9d889386 Olga Brani
                top_dir = arg.split('root=')[-1]
359 9d889386 Olga Brani
                return location.startswith(top_dir)
360 9d889386 Olga Brani
            elif arg == option:
361 9d889386 Olga Brani
                if len(args) > index:
362 9d889386 Olga Brani
                    top_dir = args[index+1]
363 9d889386 Olga Brani
                    return location.startswith(top_dir)
364 9d889386 Olga Brani
        if arg == '--user' and USER_SITE is not None:
365 9d889386 Olga Brani
            return location.startswith(USER_SITE)
366 9d889386 Olga Brani
    return True
367 9d889386 Olga Brani
368 9d889386 Olga Brani
369 9d889386 Olga Brani
def _fake_setuptools():
370 9d889386 Olga Brani
    log.warn('Scanning installed packages')
371 9d889386 Olga Brani
    try:
372 9d889386 Olga Brani
        import pkg_resources
373 9d889386 Olga Brani
    except ImportError:
374 9d889386 Olga Brani
        # we're cool
375 9d889386 Olga Brani
        log.warn('Setuptools or Distribute does not seem to be installed.')
376 9d889386 Olga Brani
        return
377 9d889386 Olga Brani
    ws = pkg_resources.working_set
378 9d889386 Olga Brani
    try:
379 9d889386 Olga Brani
        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
380 9d889386 Olga Brani
                                  replacement=False))
381 9d889386 Olga Brani
    except TypeError:
382 9d889386 Olga Brani
        # old distribute API
383 9d889386 Olga Brani
        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
384 9d889386 Olga Brani
385 9d889386 Olga Brani
    if setuptools_dist is None:
386 9d889386 Olga Brani
        log.warn('No setuptools distribution found')
387 9d889386 Olga Brani
        return
388 9d889386 Olga Brani
    # detecting if it was already faked
389 9d889386 Olga Brani
    setuptools_location = setuptools_dist.location
390 9d889386 Olga Brani
    log.warn('Setuptools installation detected at %s', setuptools_location)
391 9d889386 Olga Brani
392 9d889386 Olga Brani
    # if --root or --preix was provided, and if
393 9d889386 Olga Brani
    # setuptools is not located in them, we don't patch it
394 9d889386 Olga Brani
    if not _under_prefix(setuptools_location):
395 9d889386 Olga Brani
        log.warn('Not patching, --root or --prefix is installing Distribute'
396 9d889386 Olga Brani
                 ' in another location')
397 9d889386 Olga Brani
        return
398 9d889386 Olga Brani
399 9d889386 Olga Brani
    # let's see if its an egg
400 9d889386 Olga Brani
    if not setuptools_location.endswith('.egg'):
401 9d889386 Olga Brani
        log.warn('Non-egg installation')
402 9d889386 Olga Brani
        res = _remove_flat_installation(setuptools_location)
403 9d889386 Olga Brani
        if not res:
404 9d889386 Olga Brani
            return
405 9d889386 Olga Brani
    else:
406 9d889386 Olga Brani
        log.warn('Egg installation')
407 9d889386 Olga Brani
        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
408 9d889386 Olga Brani
        if (os.path.exists(pkg_info) and
409 9d889386 Olga Brani
            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
410 9d889386 Olga Brani
            log.warn('Already patched.')
411 9d889386 Olga Brani
            return
412 9d889386 Olga Brani
        log.warn('Patching...')
413 9d889386 Olga Brani
        # let's create a fake egg replacing setuptools one
414 9d889386 Olga Brani
        res = _patch_egg_dir(setuptools_location)
415 9d889386 Olga Brani
        if not res:
416 9d889386 Olga Brani
            return
417 9d889386 Olga Brani
    log.warn('Patched done.')
418 9d889386 Olga Brani
    _relaunch()
419 9d889386 Olga Brani
420 9d889386 Olga Brani
421 9d889386 Olga Brani
def _relaunch():
422 9d889386 Olga Brani
    log.warn('Relaunching...')
423 9d889386 Olga Brani
    # we have to relaunch the process
424 9d889386 Olga Brani
    # pip marker to avoid a relaunch bug
425 9d889386 Olga Brani
    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
426 9d889386 Olga Brani
        sys.argv[0] = 'setup.py'
427 9d889386 Olga Brani
    args = [sys.executable] + sys.argv
428 9d889386 Olga Brani
    sys.exit(subprocess.call(args))
429 9d889386 Olga Brani
430 9d889386 Olga Brani
431 9d889386 Olga Brani
def _extractall(self, path=".", members=None):
432 9d889386 Olga Brani
    """Extract all members from the archive to the current working
433 9d889386 Olga Brani
       directory and set owner, modification time and permissions on
434 9d889386 Olga Brani
       directories afterwards. `path' specifies a different directory
435 9d889386 Olga Brani
       to extract to. `members' is optional and must be a subset of the
436 9d889386 Olga Brani
       list returned by getmembers().
437 9d889386 Olga Brani
    """
438 9d889386 Olga Brani
    import copy
439 9d889386 Olga Brani
    import operator
440 9d889386 Olga Brani
    from tarfile import ExtractError
441 9d889386 Olga Brani
    directories = []
442 9d889386 Olga Brani
443 9d889386 Olga Brani
    if members is None:
444 9d889386 Olga Brani
        members = self
445 9d889386 Olga Brani
446 9d889386 Olga Brani
    for tarinfo in members:
447 9d889386 Olga Brani
        if tarinfo.isdir():
448 9d889386 Olga Brani
            # Extract directories with a safe mode.
449 9d889386 Olga Brani
            directories.append(tarinfo)
450 9d889386 Olga Brani
            tarinfo = copy.copy(tarinfo)
451 9d889386 Olga Brani
            tarinfo.mode = 448 # decimal for oct 0700
452 9d889386 Olga Brani
        self.extract(tarinfo, path)
453 9d889386 Olga Brani
454 9d889386 Olga Brani
    # Reverse sort directories.
455 9d889386 Olga Brani
    if sys.version_info < (2, 4):
456 9d889386 Olga Brani
        def sorter(dir1, dir2):
457 9d889386 Olga Brani
            return cmp(dir1.name, dir2.name)
458 9d889386 Olga Brani
        directories.sort(sorter)
459 9d889386 Olga Brani
        directories.reverse()
460 9d889386 Olga Brani
    else:
461 9d889386 Olga Brani
        directories.sort(key=operator.attrgetter('name'), reverse=True)
462 9d889386 Olga Brani
463 9d889386 Olga Brani
    # Set correct owner, mtime and filemode on directories.
464 9d889386 Olga Brani
    for tarinfo in directories:
465 9d889386 Olga Brani
        dirpath = os.path.join(path, tarinfo.name)
466 9d889386 Olga Brani
        try:
467 9d889386 Olga Brani
            self.chown(tarinfo, dirpath)
468 9d889386 Olga Brani
            self.utime(tarinfo, dirpath)
469 9d889386 Olga Brani
            self.chmod(tarinfo, dirpath)
470 9d889386 Olga Brani
        except ExtractError:
471 9d889386 Olga Brani
            e = sys.exc_info()[1]
472 9d889386 Olga Brani
            if self.errorlevel > 1:
473 9d889386 Olga Brani
                raise
474 9d889386 Olga Brani
            else:
475 9d889386 Olga Brani
                self._dbg(1, "tarfile: %s" % e)
476 9d889386 Olga Brani
477 9d889386 Olga Brani
478 9d889386 Olga Brani
def main(argv, version=DEFAULT_VERSION):
479 9d889386 Olga Brani
    """Install or upgrade setuptools and EasyInstall"""
480 9d889386 Olga Brani
    tarball = download_setuptools()
481 9d889386 Olga Brani
    _install(tarball)
482 9d889386 Olga Brani
483 9d889386 Olga Brani
484 9d889386 Olga Brani
if __name__ == '__main__':
485 9d889386 Olga Brani
    main(sys.argv[1:])