summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2013-11-22 15:37:17 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2013-11-29 16:11:44 +0000
commit93c77a63f13b7197ee623603a8b7abbf2893a3e8 (patch)
tree7a6a26dd1edf02c9477d636728bfa2e744a938a0
parent198b59056058be476cb95e44fbe839f09258527c (diff)
downloadmorph-93c77a63f13b7197ee623603a8b7abbf2893a3e8.tar.gz
plugins: Add new build command
This uses all the new APIs, so the code is shared across morphlib and unit tested rather than everything being in one massive plugin that is only black-box tested.
-rw-r--r--morphlib/plugins/build_plugin.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/morphlib/plugins/build_plugin.py b/morphlib/plugins/build_plugin.py
index e9555888..f304e59a 100644
--- a/morphlib/plugins/build_plugin.py
+++ b/morphlib/plugins/build_plugin.py
@@ -15,6 +15,8 @@
import cliapp
+import contextlib
+import uuid
import morphlib
@@ -24,6 +26,8 @@ class BuildPlugin(cliapp.Plugin):
def enable(self):
self.app.add_subcommand('build-morphology', self.build_morphology,
arg_synopsis='(REPO REF FILENAME)...')
+ self.app.add_subcommand('new-build', self.build,
+ arg_synopsis='SYSTEM')
def disable(self):
pass
@@ -64,3 +68,91 @@ class BuildPlugin(cliapp.Plugin):
build_command = self.app.hookmgr.call('new-build-command',
build_command)
build_command.build(args)
+
+ def build(self, args):
+ '''Build a system image in the current system branch
+
+ Command line arguments:
+
+ * `SYSTEM` is the name of the system to build.
+
+ This builds a system image, and any of its components that
+ need building. The system name is the basename of the system
+ morphology, in the root repository of the current system branch,
+ without the `.morph` suffix in the filename.
+
+ The location of the resulting system image artifact is printed
+ at the end of the build output.
+
+ You do not need to commit your changes before building, Morph
+ does that for you, in a temporary branch for each build. However,
+ note that Morph does not untracked files to the temporary branch,
+ only uncommitted changes to files git already knows about. You
+ need to `git add` and commit each new file yourself.
+
+ Example:
+
+ morph build devel-system-x86_64-generic
+
+ '''
+
+ if len(args) != 1:
+ raise cliapp.AppException('morph build expects exactly one '
+ 'parameter: the system to build')
+
+ # Raise an exception if there is not enough space
+ morphlib.util.check_disk_available(
+ self.app.settings['tempdir'],
+ self.app.settings['tempdir-min-space'],
+ self.app.settings['cachedir'],
+ self.app.settings['cachedir-min-space'])
+
+ system_name = args[0]
+
+ ws = morphlib.workspace.open('.')
+ sb = morphlib.sysbranchdir.open_from_within('.')
+
+ build_uuid = uuid.uuid4().hex
+
+ build_command = morphlib.buildcommand.BuildCommand(self.app)
+ build_command = self.app.hookmgr.call('new-build-command',
+ build_command)
+ loader = morphlib.morphloader.MorphologyLoader()
+ push = self.app.settings['push-build-branches']
+ name = morphlib.git.get_user_name(self.app.runcmd)
+ email = morphlib.git.get_user_email(self.app.runcmd)
+ build_ref_prefix = self.app.settings['build-ref-prefix']
+
+ self.app.status(msg='Starting build %(uuid)s', uuid=build_uuid)
+ self.app.status(msg='Collecting morphologies involved in '
+ 'building %(system)s from %(branch)s',
+ system=system_name, branch=sb.system_branch_name)
+
+ bb = morphlib.buildbranch.BuildBranch(sb, build_ref_prefix,
+ push_temporary=push)
+ with contextlib.closing(bb) as bb:
+
+ for gd, build_ref in bb.add_uncommitted_changes():
+ self.app.status(msg='Adding uncommitted changes '\
+ 'in %(dirname)s to %(ref)s',
+ dirname=gd.dirname, ref=build_ref, chatty=True)
+
+ for gd in bb.inject_build_refs(loader):
+ self.app.status(msg='Injecting temporary build refs '\
+ 'into morphologies in %(dirname)s',
+ dirname=gd.dirname, chatty=True)
+
+ for gd, build_ref in bb.update_build_refs(name, email, build_uuid):
+ self.app.status(msg='Committing changes in %(dirname)s '\
+ 'to %(ref)s',
+ dirname=gd.dirname, ref=build_ref, chatty=True)
+
+ for gd, build_ref, remote in bb.push_build_branches():
+ self.app.status(msg='Pushing %(ref)s in %(dirname)s '\
+ 'to %(remote)s',
+ ref=build_ref, dirname=gd.dirname,
+ remote=remote.get_push_url(), chatty=True)
+
+ build_command.build([bb.root_repo_url,
+ bb.root_ref,
+ system_name])