Commit 1d2bdcc8 authored by Reinout van Rees's avatar Reinout van Rees

Detecting if the installer is being run to install buildout itself.

A working_set passed into install() is the sign that we're called from
buildout.py to install buildout, setuptools, an extension or a recipe.
Those need the global pkg_resources.working_set, for instance to load entry
points.

So... conflicts with global packages are possible, but they should be ignored
so that we can grab the right versions ourselves. The paths that end up in the
bin scripts that we generate are OK.
parent 0a036f0a
...@@ -465,8 +465,7 @@ class Installer: ...@@ -465,8 +465,7 @@ class Installer:
return dist.clone(location=new_location) return dist.clone(location=new_location)
def _get_dist(self, requirement, ws): def _get_dist(self, requirement, ws, for_buildout_run=False):
__doing__ = 'Getting distribution for %r.', str(requirement) __doing__ = 'Getting distribution for %r.', str(requirement)
# Maybe an existing dist is already the best dist that satisfies the # Maybe an existing dist is already the best dist that satisfies the
...@@ -513,8 +512,6 @@ class Installer: ...@@ -513,8 +512,6 @@ class Installer:
# obtained locally. Just copy it. # obtained locally. Just copy it.
shutil.copytree(dist.location, newloc) shutil.copytree(dist.location, newloc)
else: else:
setuptools.archive_util.unpack_archive( setuptools.archive_util.unpack_archive(
dist.location, newloc) dist.location, newloc)
...@@ -532,6 +529,13 @@ class Installer: ...@@ -532,6 +529,13 @@ class Installer:
dist.location, ws, self._dest, dist) dist.location, ws, self._dest, dist)
for dist in dists: for dist in dists:
redo_pyc(dist.location) redo_pyc(dist.location)
if for_buildout_run:
# ws is the global working set and we're
# installing buildout, setuptools, extensions or
# recipes. Make sure that whatever correct version
# we've just installed is the active version,
# hence the ``replace=True``.
ws.add(dist, replace=True)
finally: finally:
if tmp != self._download_cache: if tmp != self._download_cache:
...@@ -608,6 +612,7 @@ class Installer: ...@@ -608,6 +612,7 @@ class Installer:
logger.debug('Installing %s.', repr(specs)[1:-1]) logger.debug('Installing %s.', repr(specs)[1:-1])
for_buildout_run = bool(working_set)
path = self._path path = self._path
dest = self._dest dest = self._dest
if dest is not None and dest not in path: if dest is not None and dest not in path:
...@@ -622,7 +627,8 @@ class Installer: ...@@ -622,7 +627,8 @@ class Installer:
ws = working_set ws = working_set
for requirement in requirements: for requirement in requirements:
for dist in self._get_dist(requirement, ws): for dist in self._get_dist(requirement, ws,
for_buildout_run=for_buildout_run):
ws.add(dist) ws.add(dist)
self._maybe_add_setuptools(ws, dist) self._maybe_add_setuptools(ws, dist)
...@@ -640,6 +646,7 @@ class Installer: ...@@ -640,6 +646,7 @@ class Installer:
# to look for new eggs unless what we have is the best that # to look for new eggs unless what we have is the best that
# matches the requirement. # matches the requirement.
env = pkg_resources.Environment(ws.entries) env = pkg_resources.Environment(ws.entries)
while requirements: while requirements:
# Process dependencies breadth-first. # Process dependencies breadth-first.
current_requirement = requirements.pop(0) current_requirement = requirements.pop(0)
...@@ -656,12 +663,13 @@ class Installer: ...@@ -656,12 +663,13 @@ class Installer:
"Version conflict while processing requirement %s " "Version conflict while processing requirement %s "
"(constrained to %s)", "(constrained to %s)",
current_requirement, req) current_requirement, req)
# When bootstrapping zc.buildout, we might be doing it # Installing buildout itself and its extensions and
# with a different version than the one we specified in # recipes requires the global
# our versions list. Reason: the bootstrap grabs the # ``pkg_resources.working_set`` to be active, which also
# latest buildout. Same with setuptools. # includes all system packages. So there might be
# So ignore the version conflict for those two packages. # conflicts, which are fine to ignore. We'll grab the
if req.key not in ['zc.buildout', 'setuptools']: # correct version a few lines down.
if not for_buildout_run:
raise VersionConflict(err, ws) raise VersionConflict(err, ws)
if dist is None: if dist is None:
if dest: if dest:
...@@ -669,7 +677,8 @@ class Installer: ...@@ -669,7 +677,8 @@ class Installer:
else: else:
logger.debug('Adding required %r', str(req)) logger.debug('Adding required %r', str(req))
_log_requirement(ws, req) _log_requirement(ws, req)
for dist in self._get_dist(req, ws,): for dist in self._get_dist(req, ws,
for_buildout_run=for_buildout_run):
ws.add(dist) ws.add(dist)
self._maybe_add_setuptools(ws, dist) self._maybe_add_setuptools(ws, dist)
if dist not in req: if dist not in req:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment