Commit 3df95d0f authored by Kirill Smelkov's avatar Kirill Smelkov Committed by Kazuhiko Shiozaki

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 d853d6e3
......@@ -30,11 +30,47 @@ class Base:
options['_d'] = buildout['buildout']['develop-eggs-directory']
environment_section = options.get('environment')
if environment_section:
self.environment = buildout[environment_section]
else:
self.environment = {}
environment_data = list(self.environment.items())
environment_data.sort()
options['_environment-data'] = repr(environment_data)
self.build_ext = build_ext(buildout, options)
def install(self):
self._set_environment()
try:
return self._install()
finally:
self._restore_environment()
def update(self):
return self.install()
def _set_environment(self):
self._saved_environment = {}
for key, value in list(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):
patch_dict = {}
global_patch_binary = options.get('patch-binary', 'patch')
......@@ -77,23 +113,14 @@ class Custom(Base):
options['index'] = index
self.index = index
environment_section = options.get('environment')
if environment_section:
self.environment = buildout[environment_section]
else:
self.environment = {}
environment_data = list(self.environment.items())
environment_data.sort()
options['_environment-data'] = repr(environment_data)
options['_e'] = buildout['buildout']['eggs-directory']
if buildout['buildout'].get('offline') == 'true':
self.install = lambda: ()
self._install = lambda: ()
self.newest = buildout['buildout'].get('newest') == 'true'
def install(self):
def _install(self):
options = self.options
distribution = options.get('egg')
if distribution is None:
......@@ -123,37 +150,12 @@ class Custom(Base):
extra_path = os.pathsep.join(ws.entries)
self.environment['PYTHONEXTRAPATH'] = os.environ['PYTHONEXTRAPATH'] = extra_path
self._set_environment()
try:
patch_dict = self._get_patch_dict(options, distribution)
return zc.buildout.easy_install.build(
distribution, options['_d'], self.build_ext,
self.links, self.index, sys.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 list(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):
......@@ -163,7 +165,7 @@ class Develop(Base):
options['setup'] = os.path.join(buildout['buildout']['directory'],
options['setup'])
def install(self):
def _install(self):
options = self.options
return zc.buildout.easy_install.develop(
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