Commit 97b6bc7f authored by Kai Lautaportti's avatar Kai Lautaportti

Pass the augmented environment to the hook scripts.

The call signature for the hook scripts was changed by adding a third
parameter which is a dictionary containing the environment variables copied
from ``os.environ`` and augmented with the environment overrides from the
part configuration.

Existing hook scripts that accept only two arguments continue to work but
reading ``os.environ`` directly will not contain the overridden values.
parent 8308537a
Change History Change History
************** **************
1.4.1 (XXXX-XX-XX) 1.5.0 (XXXX-XX-XX)
================== ==================
- Refactored the environment variable handling logic. Python versions prior - Refactored the environment variable handling logic. Python versions prior
...@@ -11,15 +11,19 @@ Change History ...@@ -11,15 +11,19 @@ Change History
Instead of modifying ``os.environ`` directly we use the ``subprocess`` Instead of modifying ``os.environ`` directly we use the ``subprocess``
module to run the commands in child processes which are given an explicit module to run the commands in child processes which are given an explicit
environment which is a copy of the current ``os.environ`` augmented with environment which is a copy of the current ``os.environ`` augmented with
the per-part overrides. the per-part overrides. As a result, ``os.environ`` is no longer modified
by this recipe.
The `Python hook scripts`_ are passed the augmented environment dictionary
as a third parameter.
.. warning:: Existing hook scripts accepting only two parameters
continue to work but they do not have access to the modified
environment variables. To fix this they should be refactored
to accept the third parameter.
See https://github.com/hexagonit/hexagonit.recipe.cmmi/issues/issue/1/#issue/1/comment/605362 See https://github.com/hexagonit/hexagonit.recipe.cmmi/issues/issue/1/#issue/1/comment/605362
for details. for details.
.. warning:: Due to this change the hook scripts no longer have the
augmented environment. They can still access the buildout
configuration to read the overrides but need to do this
manually.
1.4.0 (2010-08-27) 1.4.0 (2010-08-27)
================== ==================
...@@ -34,7 +38,7 @@ Change History ...@@ -34,7 +38,7 @@ Change History
- the ``configure-command`` is not used to specify a custom configure command and - the ``configure-command`` is not used to specify a custom configure command and
- ``--prefix`` is not given explicitly in the ``configure-options`` option. - ``--prefix`` is not given explicitly in the ``configure-options`` option.
[dokai] [dokai]
- Removed the ``is_build_dir()`` heuristic. - Removed the ``is_build_dir()`` heuristic.
...@@ -45,7 +49,7 @@ Change History ...@@ -45,7 +49,7 @@ Change History
an error message if they were missing. However, the recipe is useful for an error message if they were missing. However, the recipe is useful for
building many different kinds of software packages and checking for building many different kinds of software packages and checking for
particular files limited its use severely. particular files limited its use severely.
Now the recipe omits any checks for particular files in the downloaded Now the recipe omits any checks for particular files in the downloaded
package. It is recommended that you use the ``md5sum`` option in your part package. It is recommended that you use the ``md5sum`` option in your part
configuration to assert that you are downloading the package you expect configuration to assert that you are downloading the package you expect
......
This diff is collapsed.
...@@ -73,8 +73,15 @@ class Recipe(object): ...@@ -73,8 +73,15 @@ class Recipe(object):
filename, callable = script.split(':') filename, callable = script.split(':')
filename = os.path.abspath(filename) filename = os.path.abspath(filename)
module = imp.load_source('script', filename) module = imp.load_source('script', filename)
# Run the script with all options script = getattr(module, callable.strip())
getattr(module, callable.strip())(self.options, self.buildout)
try:
script(self.options, self.buildout, self.augmented_environment())
except TypeError:
# BBB: Support hook scripts that do not take the environment as
# the third parameter
script(self.options, self.buildout)
def run(self, cmd): def run(self, cmd):
"""Run the given ``cmd`` in a child process.""" """Run the given ``cmd`` in a child process."""
......
...@@ -29,6 +29,9 @@ class NonInformativeTests(unittest.TestCase): ...@@ -29,6 +29,9 @@ class NonInformativeTests(unittest.TestCase):
def tearDown(self): def tearDown(self):
shutil.rmtree(self.dir) shutil.rmtree(self.dir)
for var in os.environ.keys():
if var.startswith('HRC_'):
del os.environ[var]
def write_file(self, filename, contents, mode=stat.S_IREAD|stat.S_IWUSR): def write_file(self, filename, contents, mode=stat.S_IREAD|stat.S_IWUSR):
path = os.path.join(self.dir, filename) path = os.path.join(self.dir, filename)
...@@ -151,6 +154,48 @@ class NonInformativeTests(unittest.TestCase): ...@@ -151,6 +154,48 @@ class NonInformativeTests(unittest.TestCase):
'url' : 'file://%s/testdata/package-0.0.0.tar.gz' % os.path.dirname(__file__)}) 'url' : 'file://%s/testdata/package-0.0.0.tar.gz' % os.path.dirname(__file__)})
self.assertRaises(zc.buildout.UserError, lambda:recipe.run('this-command-does-not-exist')) self.assertRaises(zc.buildout.UserError, lambda:recipe.run('this-command-does-not-exist'))
def test_call_script__bbb_for_callable_with_two_parameters(self):
recipe = self.make_recipe({}, 'test', {
'url' : 'file://%s/testdata/package-0.0.0.tar.gz' % os.path.dirname(__file__),
})
# The hook script does not return anything so we (ab)use exceptions
# as a mechanism for asserting the function behaviour.
filename = os.path.join(self.dir, 'hooks.py')
script = open(filename, 'w')
script.write('def my_hook(options, buildout): raise ValueError("I got called")\n')
script.close()
try:
recipe.call_script('%s:my_hook' % filename)
self.fail("The hook script was not called.")
except ValueError, e:
self.assertEquals(str(e), 'I got called')
def test_call_script__augmented_environment_as_third_parameter(self):
os.environ['HRC_SENTINEL'] = 'sentinel'
os.environ['HRC_TESTVAR'] = 'foo'
recipe = self.make_recipe({}, 'test', {
'url' : 'file://%s/testdata/package-0.0.0.tar.gz' % os.path.dirname(__file__),
'environment' : 'HRC_TESTVAR=bar'
})
# The hook script does not return anything so we (ab)use exceptions
# as a mechanism for asserting the function behaviour.
filename = os.path.join(self.dir, 'hooks.py')
script = open(filename, 'w')
script.write('def my_hook(options, buildout, env): raise ValueError("%(HRC_SENTINEL)s %(HRC_TESTVAR)s" % env)\n')
script.close()
try:
recipe.call_script('%s:my_hook' % filename)
self.fail("The hook script was not called.")
except ValueError, e:
self.assertEquals(str(e), 'sentinel bar')
def test_suite(): def test_suite():
suite = unittest.TestSuite(( suite = unittest.TestSuite((
doctest.DocFileSuite( doctest.DocFileSuite(
......
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