diff options
author | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2012-04-16 16:27:14 +0100 |
---|---|---|
committer | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2012-04-18 18:27:19 +0100 |
commit | 3e8797ff2318c8d19828d869f16daba297f423a1 (patch) | |
tree | 9846aa4a62190cbc797d1a37ecd3024367862519 /morphlib | |
parent | 86e53431fceb8433dd5290a91f6864770de5c0eb (diff) | |
download | morph-3e8797ff2318c8d19828d869f16daba297f423a1.tar.gz |
Make StagingArea create build and install directories, run commands
Diffstat (limited to 'morphlib')
-rw-r--r-- | morphlib/stagingarea.py | 60 | ||||
-rw-r--r-- | morphlib/stagingarea_tests.py | 32 |
2 files changed, 90 insertions, 2 deletions
diff --git a/morphlib/stagingarea.py b/morphlib/stagingarea.py index 126d7d91..848dbc3a 100644 --- a/morphlib/stagingarea.py +++ b/morphlib/stagingarea.py @@ -14,9 +14,13 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import logging +import os import shutil import tarfile +import morphlib + class StagingArea(object): @@ -35,6 +39,46 @@ class StagingArea(object): def __init__(self, dirname): self.dirname = dirname + self._chroot = 'chroot' if os.getuid() == 0 else 'echo' + + # Wrapper to be overridden by unit tests. + def _mkdir(self, dirname): # pragma: no cover + os.mkdir(dirname) + + def _dir_for_source(self, source, suffix): + dirname = os.path.join(self.dirname, + '%s.%s' % (source.morphology['name'], suffix)) + self._mkdir(dirname) + return dirname + + def builddir(self, source): + '''Create a build directory for a given source project. + + Return path to directory. + + ''' + + return self._dir_for_source(source, 'build') + + def destdir(self, source): + '''Create an installation target directory for a given source project. + + This is meant to be used as $DESTDIR when installing chunks. + Return path to directory. + + ''' + + return self._dir_for_source(source, 'inst') + + def relative(self, filename): + '''Return a filename relative to the staging area.''' + + dirname = self.dirname + if not dirname.endswith('/'): + dirname += '/' + + assert filename.startswith(dirname) + return filename[len(dirname)-1:] # include leading slash def install_artifact(self, handle): '''Install a build artifact into the staging area. @@ -44,7 +88,7 @@ class StagingArea(object): ''' - tf = tarfile.TarFile(fileobj=handle) + tf = tarfile.open(fileobj=handle) tf.extractall(path=self.dirname) def remove(self): @@ -58,3 +102,17 @@ class StagingArea(object): shutil.rmtree(self.dirname) + def runcmd(self, argv, **kwargs): # pragma: no cover + '''Run a command in a chroot in the staging area.''' + ex = morphlib.execute.Execute('/', logging.debug) + cwd = kwargs.get('cwd') or '/' + if 'cwd' in kwargs: + cwd = kwargs['cwd'] + del kwargs['cwd'] + else: + cwd = '/' + real_argv = [self._chroot, self.dirname, + 'sh', '-c', 'cd "$1" && shift && eval "$@"', '--', + cwd] + argv + return ex.runv(real_argv, **kwargs) + diff --git a/morphlib/stagingarea_tests.py b/morphlib/stagingarea_tests.py index c6b17610..96d00890 100644 --- a/morphlib/stagingarea_tests.py +++ b/morphlib/stagingarea_tests.py @@ -23,11 +23,20 @@ import unittest import morphlib +class FakeSource(object): + + def __init__(self): + self.morphology = { + 'name': 'le-name', + } + + class StagingAreaTests(unittest.TestCase): def setUp(self): self.tempdir = tempfile.mkdtemp() self.staging = os.path.join(self.tempdir, 'staging') + self.created_dirs = [] self.sa = morphlib.stagingarea.StagingArea(self.staging) def tearDown(self): @@ -53,13 +62,34 @@ class StagingAreaTests(unittest.TestCase): files.append(x[len(root):] or '/') return files + def fake_mkdir(self, dirname): + self.created_dirs.append(dirname) + def test_remembers_specified_directory(self): self.assertEqual(self.sa.dirname, self.staging) def test_accepts_root_directory(self): sa = morphlib.stagingarea.StagingArea('/') self.assertEqual(sa.dirname, '/') - + + def test_creates_build_directory(self): + source = FakeSource() + self.sa._mkdir = self.fake_mkdir + dirname = self.sa.builddir(source) + self.assertEqual(self.created_dirs, [dirname]) + self.assertTrue(dirname.startswith(self.staging)) + + def test_creates_install_directory(self): + source = FakeSource() + self.sa._mkdir = self.fake_mkdir + dirname = self.sa.destdir(source) + self.assertEqual(self.created_dirs, [dirname]) + self.assertTrue(dirname.startswith(self.staging)) + + def test_makes_relative_name(self): + filename = os.path.join(self.staging, 'foobar') + self.assertEqual(self.sa.relative(filename), '/foobar') + def test_installs_artifact(self): chunk_tar = self.create_chunk() with open(chunk_tar, 'rb') as f: |