Commit 93d35f5d authored by Kirill Smelkov's avatar Kirill Smelkov

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 4989131a
1.3.2.post3
-----------
- Support environment in zc.recipe.egg:develop.
1.3.2.post2
-----------
......
......@@ -14,7 +14,7 @@
"""Setup for zc.recipe.egg package
"""
version = '1.3.2.post2'
version = '1.3.2.post3'
import os
from setuptools import setup, find_packages
......
......@@ -32,11 +32,47 @@ class Base:
python = options.get('python', buildout['buildout']['python'])
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)
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 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')
......@@ -79,25 +115,16 @@ 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 = self.environment.items()
environment_data.sort()
options['_environment-data'] = repr(environment_data)
options['_e'] = buildout['buildout']['eggs-directory']
assert options.get('unzip') in ('true', 'false', None)
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:
......@@ -127,36 +154,11 @@ class Custom(Base):
extra_path = os.pathsep.join(ws.entries)
self.environment['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, 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
patch_dict = self._get_patch_dict(options, distribution)
return zc.buildout.easy_install.build(
distribution, options['_d'], self.build_ext,
self.links, self.index, options['executable'], [options['_e']],
newest=self.newest, patch_dict=patch_dict)
class Develop(Base):
......@@ -166,7 +168,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