summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2013-02-19 15:59:20 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2013-02-19 17:17:19 +0000
commit46d42eb7f183ac37c2f1209c3c733fc3bc348e1a (patch)
treee2f72f54731288b545a28dc7f3e363b38287a92d
parent24866984ce4c1e2e444ea4aaf2d4860c60ac617f (diff)
downloadmorph-46d42eb7f183ac37c2f1209c3c733fc3bc348e1a.tar.gz
Replace builder order graph with just a single artifact
The artifact's build dependencies replace the build order graph from previously.
-rw-r--r--morphlib/artifact.py23
-rw-r--r--morphlib/buildcommand.py34
-rw-r--r--morphlib/plugins/deploy_plugin.py3
-rw-r--r--morphlib/plugins/graphing_plugin.py30
4 files changed, 54 insertions, 36 deletions
diff --git a/morphlib/artifact.py b/morphlib/artifact.py
index ccde11d4..3bb2a520 100644
--- a/morphlib/artifact.py
+++ b/morphlib/artifact.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
@@ -63,3 +63,24 @@ class Artifact(object):
def __str__(self): # pragma: no cover
return '%s|%s' % (self.source, self.name)
+
+ def walk(self): # pragma: no cover
+ '''Return list of an artifact and its build dependencies.
+
+ The artifacts are returned in depth-first order: an artifact
+ is returned only after all of its dependencies.
+
+ '''
+
+ done = set()
+
+ def depth_first(a):
+ for dep in a.dependencies:
+ for ret in depth_first(dep):
+ yield ret
+ if a not in done:
+ done.add(a)
+ yield a
+
+ return list(depth_first(self))
+
diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py
index 907676fa..c12735bb 100644
--- a/morphlib/buildcommand.py
+++ b/morphlib/buildcommand.py
@@ -48,8 +48,8 @@ class BuildCommand(object):
for repo_name, ref, filename in self.app.itertriplets(args):
self.app.status(msg='Building %(repo_name)s %(ref)s %(filename)s',
repo_name=repo_name, ref=ref, filename=filename)
- order = self.compute_build_order(repo_name, ref, filename)
- self.build_in_order(order)
+ artifact = self.get_artifact_object(repo_name, ref, filename)
+ self.build_in_order(artifact)
self.app.status(msg='Build ends successfully', chatty=True)
@@ -72,7 +72,14 @@ class BuildCommand(object):
def new_repo_caches(self):
return morphlib.util.new_repo_caches(self.app)
- def compute_build_order(self, repo_name, ref, filename):
+ def get_artifact_object(self, repo_name, ref, filename):
+ '''Create an Artifact object representing the given triplet.'''
+
+ order = self._compute_build_order(repo_name, ref, filename)
+ artifact = order.groups[-1][-1]
+ return artifact
+
+ def _compute_build_order(self, repo_name, ref, filename):
'''Compute build order for a triplet.'''
self.app.status(msg='Figuring out the right build order')
@@ -158,24 +165,13 @@ class BuildCommand(object):
other.morphology['kind'],
wanted))
- def build_in_order(self, order):
+ def build_in_order(self, artifact):
'''Build everything specified in a build order.'''
self.app.status(msg='Building according to build ordering',
chatty=True)
- for group in order.groups:
- self.build_artifacts(group)
-
- def build_artifacts(self, artifacts):
- '''Build a set of artifact.
-
- Typically, this would be a build group, but might be anything.
- At this level of abstraction we don't care.
- '''
-
- self.app.status(msg='Building a set of artifacts', chatty=True)
- for artifact in artifacts:
- self.build_artifact(artifact)
+ for a in artifact.walk():
+ self.build_artifact(a)
def build_artifact(self, artifact):
'''Build one artifact.
@@ -287,7 +283,9 @@ class BuildCommand(object):
self.app.status(msg='Fetching to local cache: '
'artifact %(name)s',
name=artifact.name)
- copy(self.rac.get(artifact), self.lac.put(artifact))
+ rac_file = self.rac.get(artifact)
+ lac_file = self.lac.put(artifact)
+ copy(rac_file, lac_file)
if artifact.source.morphology.needs_artifact_metadata_cached:
if not self.lac.has_artifact_metadata(artifact, 'meta'):
diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py
index 79715e13..f9a345ff 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -100,11 +100,10 @@ class DeployPlugin(cliapp.Plugin):
# Run the build.
build_ref = build_repos[branch_root]['build-ref']
- order = build_command.compute_build_order(
+ artifact = build_command.get_artifact_object(
build_branch_root,
build_ref,
system_name + '.morph')
- artifact = order.groups[-1][-1]
if push:
self.other.delete_remote_build_refs(build_repos)
diff --git a/morphlib/plugins/graphing_plugin.py b/morphlib/plugins/graphing_plugin.py
index c719f6e4..8c4ea2ef 100644
--- a/morphlib/plugins/graphing_plugin.py
+++ b/morphlib/plugins/graphing_plugin.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
@@ -37,7 +37,7 @@ class GraphingPlugin(cliapp.Plugin):
'%(repo_name)s %(ref)s %(filename)s',
repo_name=repo_name, ref=ref, filename=filename)
builder = morphlib.buildcommand.BuildCommand(self.app)
- order = builder.compute_build_order(repo_name, ref, filename)
+ artifact = builder.get_artifact_object(repo_name, ref, filename)
basename, ext = os.path.splitext(filename)
dot_filename = basename + '.gv'
@@ -53,17 +53,17 @@ class GraphingPlugin(cliapp.Plugin):
with open(dot_filename, 'w') as f:
f.write('digraph "%s" {\n' % basename)
- for i, group in enumerate(order.groups):
- for artifact in group:
- f.write(
- ' "%s" [shape=%s];\n' %
- (artifact.name,
- shape_name[artifact.source.morphology['kind']]))
- for dep in artifact.dependencies:
- if artifact.source.morphology['kind'] == 'stratum':
- if dep.dependents == [artifact]:
- f.write(dep_fmt %
- (artifact.name, dep.name))
- else:
- f.write(dep_fmt % (artifact.name, dep.name))
+ for a in artifact.walk():
+ f.write(
+ ' "%s" [shape=%s];\n' %
+ (a.name,
+ shape_name[a.source.morphology['kind']]))
+ for dep in a.dependencies:
+ if a.source.morphology['kind'] == 'stratum':
+ if dep.dependents == [a]:
+ f.write(dep_fmt %
+ (a.name, dep.name))
+ else:
+ f.write(dep_fmt % (a.name, dep.name))
f.write('}\n')
+