summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Coldrick <adam.coldrick@codethink.co.uk>2015-03-13 15:34:44 +0000
committerAdam Coldrick <adam.coldrick@codethink.co.uk>2015-03-13 15:34:44 +0000
commite41070a4cd9252796bae03a7551df5af659a33da (patch)
tree4142aa201ac88f1e46ef18602f7c0804a993de7a
parentcd857ff295574589fb4cb61e7dbda16387c974e4 (diff)
downloadmorph-e41070a4cd9252796bae03a7551df5af659a33da.tar.gz
fixup: Tidy up partial builds
-rw-r--r--morphlib/buildcommand.py3
-rw-r--r--morphlib/plugins/build_plugin.py82
2 files changed, 59 insertions, 26 deletions
diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py
index 8572450d..4e63b211 100644
--- a/morphlib/buildcommand.py
+++ b/morphlib/buildcommand.py
@@ -272,7 +272,8 @@ class BuildCommand(object):
def build_in_order(self, root_artifact):
'''Build everything specified in a build order.'''
- self.app.status(msg='Building a set of sources')
+ self.app.status(msg='Starting build of %(name)s',
+ name=root_artifact.source.name)
build_env = root_artifact.build_env
ordered_sources = list(self.get_ordered_sources(root_artifact.walk()))
old_prefix = self.app.status_prefix
diff --git a/morphlib/plugins/build_plugin.py b/morphlib/plugins/build_plugin.py
index b4c9900e..15ae962a 100644
--- a/morphlib/plugins/build_plugin.py
+++ b/morphlib/plugins/build_plugin.py
@@ -24,13 +24,21 @@ import cliapp
import morphlib
+class ComponentNotInSystemError(morphlib.Error):
+
+ def __init__(self, components, system):
+ components = ', '.join(components)
+ self.msg = 'Components %s are not in %s' % (components, system)
+
+
class BuildPlugin(cliapp.Plugin):
def enable(self):
self.app.add_subcommand('build-morphology', self.build_morphology,
- arg_synopsis='(REPO REF FILENAME)...')
+ arg_synopsis='REPO REF FILENAME '
+ '[COMPONENT...]')
self.app.add_subcommand('build', self.build,
- arg_synopsis='SYSTEM')
+ arg_synopsis='SYSTEM [COMPONENT...]')
self.app.add_subcommand('distbuild-morphology',
self.distbuild_morphology,
arg_synopsis='SYSTEM')
@@ -95,6 +103,8 @@ class BuildPlugin(cliapp.Plugin):
* `REPO` is a git repository URL.
* `REF` is a branch or other commit reference in that repository.
* `FILENAME` is a morphology filename at that ref.
+ * `COMPONENT...` is one or more chunks or strata to build. This
+ is only used if `--partial` is set.
You probably want `morph build` instead. However, in some
cases it is more convenient to not have to create a Morph
@@ -107,8 +117,14 @@ class BuildPlugin(cliapp.Plugin):
Example:
- morph build-morphology baserock:baserock/definitions \
- master devel-system-x86_64-generic.morph
+ morph build-morphology baserock:baserock/definitions \\
+ master systems/devel-system-x86_64-generic.morph
+
+ Partial build example:
+
+ morph build-morphology --partial baserock:baserock/definitions \\
+ master systems/devel-system-x86_64-generic.morph \\
+ strata/build-essential.morph
'''
@@ -120,8 +136,12 @@ class BuildPlugin(cliapp.Plugin):
self.app.settings['cachedir-min-space'])
build_command = morphlib.buildcommand.BuildCommand(self.app)
- for repo_name, ref, filename in self.app.itertriplets(args):
- build_command.build(repo_name, ref, filename)
+ repo, ref, filename = args[0:3]
+ filename = morphlib.util.sanitise_morphology_path(filename)
+ component_filenames = [morphlib.util.sanitise_morphology_path(name)
+ for name in args[3:]]
+ self.start_build(repo, ref, build_command, filename,
+ component_filenames)
def build(self, args):
'''Build a system image in the current system branch
@@ -129,6 +149,8 @@ class BuildPlugin(cliapp.Plugin):
Command line arguments:
* `SYSTEM` is the name of the system to build.
+ * `COMPONENT...` is one or more chunks or strata to build. This
+ is only used if `--partial` is set.
This builds a system image, and any of its components that
need building. The system name is the basename of the system
@@ -148,7 +170,12 @@ class BuildPlugin(cliapp.Plugin):
Example:
- morph build devel-system-x86_64-generic.morph
+ morph build systems/devel-system-x86_64-generic.morph
+
+ Partial build example:
+
+ morph build --partial systems/devel-system-x86_64-generic.morph \\
+ strata/build-essential.morph
'''
@@ -169,9 +196,9 @@ class BuildPlugin(cliapp.Plugin):
system_filename = morphlib.util.sanitise_morphology_path(args[0])
system_filename = sb.relative_to_root_repo(system_filename)
if self.app.settings['partial']:
- chunk_filenames = self._sanitise_morphology_paths(args[1:], sb)
+ component_filenames = self._sanitise_morphology_paths(args[1:], sb)
else:
- chunk_filenames = []
+ component_filenames = []
logging.debug('System branch is %s' % sb.root_directory)
@@ -186,13 +213,13 @@ class BuildPlugin(cliapp.Plugin):
if self.app.settings['local-changes'] == 'include':
self._build_with_local_changes(build_command, sb, system_filename,
- chunk_filenames)
+ component_filenames)
else:
self._build_local_commit(build_command, sb, system_filename,
- chunk_filenames)
+ component_filenames)
def _build_with_local_changes(self, build_command, sb, system_filename,
- chunk_filenames):
+ component_filenames):
'''Construct a branch including user's local changes, and build that.
It is often a slow process to check all repos in the system branch for
@@ -222,10 +249,10 @@ class BuildPlugin(cliapp.Plugin):
status=self.app.status)
with pbb as (repo, commit, original_ref):
self.start_build(repo, commit, build_command, system_filename,
- chunk_filenames, original_ref=original_ref)
+ component_filenames, original_ref=original_ref)
def _build_local_commit(self, build_command, sb, system_filename,
- chunk_filenames):
+ component_filenames):
'''Build whatever commit the user has checked-out locally.
This ignores any uncommitted changes. Also, if the user has a commit
@@ -254,7 +281,7 @@ class BuildPlugin(cliapp.Plugin):
commit = definitions_repo.resolve_ref_to_commit(ref)
self.start_build(root_repo_url, commit, build_command,
- system_filename, chunk_filenames)
+ system_filename, component_filenames)
def _sanitise_morphology_paths(self, paths, sb):
sanitised_paths = []
@@ -265,13 +292,15 @@ class BuildPlugin(cliapp.Plugin):
def _find_artifacts(self, filenames, root_artifact):
found = collections.OrderedDict()
+ not_found = filenames
for a in root_artifact.walk():
if a.source.filename in filenames and a.source.name not in found:
found[a.source.name] = a
- return found
+ not_found.remove(a.source.filename)
+ return found, not_found
def start_build(self, repo, commit, bc, system_filename,
- chunk_filenames, original_ref=None):
+ component_filenames, original_ref=None):
'''Actually run the build.
If --partial was set on the command line, we expect that there is a
@@ -290,11 +319,14 @@ class BuildPlugin(cliapp.Plugin):
self.app.status(msg='Deciding on task order')
srcpool = bc.create_source_pool(repo, commit, system_filename)
root = bc.resolve_artifacts(srcpool)
- chunks = self._find_artifacts(chunk_filenames, root)
- if not chunks:
- raise ChunksNotInSystemError(chunk_filenames, system_filename)
-
- for name, chunk in chunks.iteritems():
- self.app.status(msg='Starting build of %s' % name)
- chunk.build_env = root.build_env
- bc.build_in_order(chunk)
+ components, not_found = self._find_artifacts(component_filenames, root)
+ if not_found:
+ raise ComponentNotInSystemError(not_found, system_filename)
+
+ for name, component in components.iteritems():
+ component.build_env = root.build_env
+ bc.build_in_order(component)
+ self.app.status(msg='%(kind)s %(name)s is cached at %(path)s',
+ kind=component.source.morphology['kind'],
+ name=name,
+ path=bc.lac.artifact_filename(component))