Commit b3381ef0 authored by Kirill Smelkov's avatar Kirill Smelkov Committed by Julien Muchembled

zc.recipe.egg: Support environment in :develop

Currently only zc.recipe.egg:custom supports setting environment
variables, and zc.recipe.egg:develop does not.

My motivation for allowing setting environment in :develop is
wendelin.core

    https://lab.nexedi.cn/nexedi/slapos/blob/b5faab3b/component/wendelin.core/buildout.cfg

There we have [wendelin.core] part which installs released egg from
pypi, and [wendelin.core-dev] part which installs wendelin.core from
its latest git version via zc.recipe.egg:develop .

The problem is, wendelin.core for setup.py to work, needs git available,
and with slapos we usually don't have git available on base system, so
we build it by our own and do something like

    [wendelin.core-dev]
    recipe = zc.recipe.egg:develop
    environment = wendelin.core-dev-env

    [wendelin.core-dev-env]
    # wendelin.core-dev needs git to build
    PATH = ${git:location}/bin:%(PATH)s

and the problem is environment does not currently work for
zc.recipe.egg:develop, and thus git is not found -> build fails.

~~~~

In order to support environment in :develop, we just move environment
setting/restoring bits from Custom to Base, and provide Base.install() which
uses this bits. Custom & Develop .install() becomes ._install() which gets
hooked into Base.install() .

I've tested the patch only manually, because currently automated tests are
broken in a lot of places for slapos.buildout and zc.recipe.egg .

/cc @kazuhiko, @Tyagov
parent d0fb97d9
1.3.2.post3
-----------
- Support environment in zc.recipe.egg:develop.
1.3.2.post2 1.3.2.post2
----------- -----------
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
"""Setup for zc.recipe.egg package """Setup for zc.recipe.egg package
""" """
version = '1.3.2.post2' version = '1.3.2.post3'
import os import os
from setuptools import setup, find_packages from setuptools import setup, find_packages
......
...@@ -32,11 +32,47 @@ class Base: ...@@ -32,11 +32,47 @@ class Base:
python = options.get('python', buildout['buildout']['python']) python = options.get('python', buildout['buildout']['python'])
options['executable'] = buildout[python]['executable'] options['executable'] = buildout[python]['executable']
environment_section = options.get('environment')
if environment_section:
self.environment = buildout[environment_section]
else:
self.environment = {}
environment_data = self.environment.items()
environment_data.sort()
options['_environment-data'] = repr(environment_data)
self.build_ext = build_ext(buildout, options) self.build_ext = build_ext(buildout, options)
def install(self):
self._set_environment()
try:
return self._install()
finally:
self._restore_environment()
def update(self): def update(self):
return self.install() return self.install()
def _set_environment(self):
self._saved_environment = {}
for key, value in self.environment.items():
if key in os.environ:
self._saved_environment[key] = os.environ[key]
# Interpolate value with variables from environment. Maybe there
# should be a general way of doing this in buildout with something
# like ${environ:foo}:
os.environ[key] = value % os.environ
def _restore_environment(self):
for key in self.environment:
if key in self._saved_environment:
os.environ[key] = self._saved_environment[key]
else:
try:
del os.environ[key]
except KeyError:
pass
def _get_patch_dict(self, options, distribution): def _get_patch_dict(self, options, distribution):
patch_dict = {} patch_dict = {}
global_patch_binary = options.get('patch-binary', 'patch') global_patch_binary = options.get('patch-binary', 'patch')
...@@ -79,25 +115,16 @@ class Custom(Base): ...@@ -79,25 +115,16 @@ class Custom(Base):
options['index'] = index options['index'] = index
self.index = index self.index = index
environment_section = options.get('environment')
if environment_section:
self.environment = buildout[environment_section]
else:
self.environment = {}
environment_data = self.environment.items()
environment_data.sort()
options['_environment-data'] = repr(environment_data)
options['_e'] = buildout['buildout']['eggs-directory'] options['_e'] = buildout['buildout']['eggs-directory']
assert options.get('unzip') in ('true', 'false', None) assert options.get('unzip') in ('true', 'false', None)
if buildout['buildout'].get('offline') == 'true': if buildout['buildout'].get('offline') == 'true':
self.install = lambda: () self._install = lambda: ()
self.newest = buildout['buildout'].get('newest') == 'true' self.newest = buildout['buildout'].get('newest') == 'true'
def install(self): def _install(self):
options = self.options options = self.options
distribution = options.get('egg') distribution = options.get('egg')
if distribution is None: if distribution is None:
...@@ -127,36 +154,11 @@ class Custom(Base): ...@@ -127,36 +154,11 @@ class Custom(Base):
extra_path = os.pathsep.join(ws.entries) extra_path = os.pathsep.join(ws.entries)
self.environment['PYTHONEXTRAPATH'] = extra_path self.environment['PYTHONEXTRAPATH'] = extra_path
self._set_environment() patch_dict = self._get_patch_dict(options, distribution)
try: return zc.buildout.easy_install.build(
patch_dict = self._get_patch_dict(options, distribution) distribution, options['_d'], self.build_ext,
return zc.buildout.easy_install.build( self.links, self.index, options['executable'], [options['_e']],
distribution, options['_d'], self.build_ext, newest=self.newest, patch_dict=patch_dict)
self.links, self.index, options['executable'], [options['_e']],
newest=self.newest, patch_dict=patch_dict)
finally:
self._restore_environment()
def _set_environment(self):
self._saved_environment = {}
for key, value in self.environment.items():
if key in os.environ:
self._saved_environment[key] = os.environ[key]
# Interpolate value with variables from environment. Maybe there
# should be a general way of doing this in buildout with something
# like ${environ:foo}:
os.environ[key] = value % os.environ
def _restore_environment(self):
for key in self.environment:
if key in self._saved_environment:
os.environ[key] = self._saved_environment[key]
else:
try:
del os.environ[key]
except KeyError:
pass
class Develop(Base): class Develop(Base):
...@@ -166,7 +168,7 @@ class Develop(Base): ...@@ -166,7 +168,7 @@ class Develop(Base):
options['setup'] = os.path.join(buildout['buildout']['directory'], options['setup'] = os.path.join(buildout['buildout']['directory'],
options['setup']) options['setup'])
def install(self): def _install(self):
options = self.options options = self.options
return zc.buildout.easy_install.develop( return zc.buildout.easy_install.develop(
options['setup'], options['_d'], self.build_ext, options['setup'], options['_d'], self.build_ext,
......
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