summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2013-03-11 14:10:53 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2013-03-11 14:10:53 +0000
commit0ad15d6122bc62a2964bc0fd9b23fa2318321304 (patch)
treec49d86487c7b2d9b044e39474cbc5dc9e32723a4
parentab90f3561ce43dba089686c743ecf0c4d6f33d31 (diff)
parent177405915072deebff194e5ed20182a641416155 (diff)
downloadmorph-0ad15d6122bc62a2964bc0fd9b23fa2318321304.tar.gz
Merge remote-tracking branch 'origin/baserock/richardholland/environment-logging' into staging
Added a "pragma: no cover" to make the test suite pass.
-rw-r--r--README32
-rwxr-xr-xmorphlib/app.py5
-rw-r--r--morphlib/builder2.py18
-rw-r--r--morphlib/buildsystem.py14
-rw-r--r--morphlib/morph2.py8
-rw-r--r--morphlib/morph2_tests.py16
-rw-r--r--morphlib/util.py17
7 files changed, 102 insertions, 8 deletions
diff --git a/README b/README
index 9ed92845..36d33a43 100644
--- a/README
+++ b/README
@@ -80,15 +80,44 @@ For chunks, use the following fields:
`*-commands` fields; only `autotools` is currently known; the commands
that the build system specifies can be overridden;
optional
+
+* `pre-configure-commands`: a list of shell commands to run at
+ the configuration phase of a build, before the list in `configure-commands`;
+ optional
* `configure-commands`: a list of shell commands to run at the configuraiton
phase of a build; optional
+* `post-configure-commands`: a list of shell commands to run at
+ the configuration phase of a build, after the list in `configure-commands`;
+ optional
+
+* `pre-build-commands`: a list of shell commands to run at
+ the build phase of a build, before the list in `build-commands`;
+ optional
* `build-commands`: a list of shell commands to run to build (compile) the
project; optional
+* `post-build-commands`: a list of shell commands to run at
+ the build phase of a build, after the list in `build-commands`;
+ optional
+
+* `pre-test-commands`: a list of shell commands to run at
+ the test phase of a build, before the list in `test-commands`;
+ optional
* `test-commands`: a list of shell commands to run unit tests and other
non-interactive tests on the built but un-installed project; optional
+* `post-test-commands`: a list of shell commands to run at
+ the test phase of a build, after the list in `test-commands`;
+ optional
+
+* `pre-install-commands`: a list of shell commands to run at
+ the install phase of a build, before the list in `install-commands`;
+ optional
* `install-commands`: a list of shell commands to install the built project;
the install should go into the directory named in the `DESTDIR` environment
variable, not the actual system; optional
+* `post-install-commands`: a list of shell commands to run at
+ the install phase of a build, after the list in `install-commands`;
+ optional
+
* `max-jobs`: a string to be given to `make` as the argument to the `-j`
option to specify the maximum number of parallel jobs; the only sensible
value is `"1"` (including the quotes), to prevent parallel jobs to run
@@ -96,6 +125,7 @@ For chunks, use the following fields:
since the other phases are often not safe when run in parallel; `morph`
picks a default value based on the number of CPUs on the host system;
optional
+
* `chunks`: a key/value map of lists of regular expressions;
the key is the name
of a binary chunk, the regexps match the pathnames that will be
@@ -332,7 +362,7 @@ uses the strata that were build in stage 2.
Legalese
--------
-Copyright (C) 2011, 2012 Codethink Limited
+Copyright (C) 2011-2013 Codethink Limited
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/morphlib/app.py b/morphlib/app.py
index 21e18e32..87710ee5 100755
--- a/morphlib/app.py
+++ b/morphlib/app.py
@@ -395,8 +395,9 @@ class Morph(cliapp.Application):
chatty=True)
# Log the environment.
- for name in kwargs['env']:
- logging.debug('environment: %s=%s' % (name, kwargs['env'][name]))
+ prev = getattr(self, 'prev_env', {})
+ morphlib.util.log_dict_diff(kwargs['env'], prev)
+ self.prev_env = kwargs['env']
# run the command line
return cliapp.Application.runcmd(self, argv, *args, **kwargs)
diff --git a/morphlib/builder2.py b/morphlib/builder2.py
index 82a95820..73745d66 100644
--- a/morphlib/builder2.py
+++ b/morphlib/builder2.py
@@ -377,10 +377,20 @@ class ChunkBuilder(BuilderBase):
relative_destdir = self.staging_area.relative(destdir)
self.build_env.env['DESTDIR'] = relative_destdir
- steps = [('configure', False),
- ('build', True),
- ('test', False),
- ('install', False)]
+ steps = [
+ ('pre-configure', False),
+ ('configure', False),
+ ('post-configure', False),
+ ('pre-build', True),
+ ('build', True),
+ ('post-build', True),
+ ('pre-test', False),
+ ('test', False),
+ ('post-test', False),
+ ('pre-install', False),
+ ('install', False),
+ ('post-install', False),
+ ]
for step, in_parallel in steps:
with self.build_watch(step):
key = '%s-commands' % step
diff --git a/morphlib/buildsystem.py b/morphlib/buildsystem.py
index 6287063a..a6645eb2 100644
--- a/morphlib/buildsystem.py
+++ b/morphlib/buildsystem.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 Codethink Limited
+# Copyright (C) 2012-2013 Codethink Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,10 +32,18 @@ class BuildSystem(object):
'''
def __init__(self):
+ self.pre_configure_commands = []
self.configure_commands = []
+ self.post_configure_commands = []
+ self.pre_build_commands = []
self.build_commands = []
+ self.post_build_commands = []
+ self.pre_test_commands = []
self.test_commands = []
+ self.post_test_commands = []
+ self.pre_install_commands = []
self.install_commands = []
+ self.post_install_commands = []
def __getitem__(self, key):
key = '_'.join(key.split('-'))
@@ -82,6 +90,7 @@ class DummyBuildSystem(BuildSystem):
name = 'dummy'
def __init__(self):
+ BuildSystem.__init__(self)
self.configure_commands = ['echo dummy configure']
self.build_commands = ['echo dummy build']
self.test_commands = ['echo dummy test']
@@ -98,6 +107,7 @@ class AutotoolsBuildSystem(BuildSystem):
name = 'autotools'
def __init__(self):
+ BuildSystem.__init__(self)
self.configure_commands = [
'export NOCONFIGURE=1; ' +
'if [ -e autogen ]; then ./autogen; ' +
@@ -134,6 +144,7 @@ class PythonDistutilsBuildSystem(BuildSystem):
name = 'python-distutils'
def __init__(self):
+ BuildSystem.__init__(self)
self.configure_commands = [
]
self.build_commands = [
@@ -160,6 +171,7 @@ class CPANBuildSystem(BuildSystem):
name = 'cpan'
def __init__(self):
+ BuildSystem.__init__(self)
self.configure_commands = [
'perl Makefile.PL INSTALLDIRS=perl '
'INSTALLARCHLIB="$PREFIX/lib/perl" '
diff --git a/morphlib/morph2.py b/morphlib/morph2.py
index ee58ecdc..3cdf49a9 100644
--- a/morphlib/morph2.py
+++ b/morphlib/morph2.py
@@ -32,10 +32,18 @@ class Morphology(object):
static_defaults = {
'chunk': [
('description', ''),
+ ('pre-configure-commands', None),
('configure-commands', None),
+ ('post-configure-commands', None),
+ ('pre-build-commands', None),
('build-commands', None),
+ ('post-build-commands', None),
+ ('pre-test-commands', None),
('test-commands', None),
+ ('post-test-commands', None),
+ ('pre-install-commands', None),
('install-commands', None),
+ ('post-install-commands', None),
('devices', None),
('chunks', []),
('max-jobs', None),
diff --git a/morphlib/morph2_tests.py b/morphlib/morph2_tests.py
index d2973d5c..49be9c8c 100644
--- a/morphlib/morph2_tests.py
+++ b/morphlib/morph2_tests.py
@@ -37,10 +37,18 @@ class MorphologyTests(unittest.TestCase):
self.assertEqual(m['name'], 'foo')
self.assertEqual(m['kind'], 'chunk')
self.assertEqual(m['build-system'], 'manual')
+ self.assertEqual(m['pre-configure-commands'], None)
self.assertEqual(m['configure-commands'], None)
+ self.assertEqual(m['post-configure-commands'], None)
+ self.assertEqual(m['pre-build-commands'], None)
self.assertEqual(m['build-commands'], None)
+ self.assertEqual(m['post-build-commands'], None)
+ self.assertEqual(m['pre-test-commands'], None)
self.assertEqual(m['test-commands'], None)
+ self.assertEqual(m['post-test-commands'], None)
+ self.assertEqual(m['pre-install-commands'], None)
self.assertEqual(m['install-commands'], None)
+ self.assertEqual(m['post-install-commands'], None)
self.assertEqual(m['max-jobs'], None)
self.assertEqual(m['chunks'], [])
@@ -55,10 +63,18 @@ class MorphologyTests(unittest.TestCase):
self.assertEqual(m['name'], 'foo')
self.assertEqual(m['kind'], 'chunk')
self.assertEqual(m['build-system'], 'manual')
+ self.assertEqual(m['pre-configure-commands'], None)
self.assertEqual(m['configure-commands'], None)
+ self.assertEqual(m['post-configure-commands'], None)
+ self.assertEqual(m['pre-build-commands'], None)
self.assertEqual(m['build-commands'], None)
+ self.assertEqual(m['post-build-commands'], None)
+ self.assertEqual(m['pre-test-commands'], None)
self.assertEqual(m['test-commands'], None)
+ self.assertEqual(m['post-test-commands'], None)
+ self.assertEqual(m['pre-install-commands'], None)
self.assertEqual(m['install-commands'], None)
+ self.assertEqual(m['post-install-commands'], None)
self.assertEqual(m['max-jobs'], None)
self.assertEqual(m['chunks'], [])
diff --git a/morphlib/util.py b/morphlib/util.py
index c832a141..b4e06092 100644
--- a/morphlib/util.py
+++ b/morphlib/util.py
@@ -16,6 +16,7 @@
import re
import morphlib
+import logging
'''Utility functions for morph.'''
@@ -170,6 +171,22 @@ def new_repo_caches(app): # pragma: no cover
return lrc, rrc
+def log_dict_diff(cur, pre): # pragma: no cover
+ '''Log the differences between two dicts to debug log'''
+ dictA = cur
+ dictB = pre
+ for key in dictA.keys():
+ if key not in dictB:
+ logging.debug("New environment: %s = %s" % (key, dictA[key]))
+ elif dictA[key] != dictB[key]:
+ logging.debug(
+ "Environment changed: %(key)s = %(valA)s to %(key)s = %(valB)s"
+ % {"key": key, "valA": dictA[key], "valB": dictB[key]})
+ for key in dictB.keys():
+ if key not in dictA:
+ logging.debug("Environment removed: %s = %s" % (key, dictB[key]))
+
+
# This acquired from rdiff-backup which is GPLv2+ and a patch from 2011
# which has not yet been merged, combined with a tad of tidying from us.
def copyfileobj(inputfp, outputfp, blocksize=1024*1024): # pragma: no cover