summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2013-02-19 18:58:00 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2013-02-19 18:58:00 +0000
commit29b8977ac03ac9ce0c178ce6febd0a5f27288001 (patch)
tree523a32e1d5f4a373051d9272120d8a9c289da873
parent24866984ce4c1e2e444ea4aaf2d4860c60ac617f (diff)
parenteda18665e3fc652f95e9961a4edc46ec797aa4a9 (diff)
downloadmorph-29b8977ac03ac9ce0c178ce6febd0a5f27288001.tar.gz
Merge branch 'liw/build-ordering'
-rw-r--r--morphlib/__init__.py1
-rw-r--r--morphlib/artifact.py23
-rw-r--r--morphlib/buildcommand.py51
-rw-r--r--morphlib/buildorder.py117
-rw-r--r--morphlib/buildorder_tests.py141
-rw-r--r--morphlib/plugins/deploy_plugin.py3
-rw-r--r--morphlib/plugins/graphing_plugin.py30
-rw-r--r--morphlib/plugins/show_dependencies_plugin.py22
-rw-r--r--tests/show-dependencies.stdout153
9 files changed, 134 insertions, 407 deletions
diff --git a/morphlib/__init__.py b/morphlib/__init__.py
index 4446720e..271fa977 100644
--- a/morphlib/__init__.py
+++ b/morphlib/__init__.py
@@ -48,7 +48,6 @@ import artifactresolver
import bins
import buildcommand
import buildenvironment
-import buildorder
import buildsystem
import builder2
import cachedir
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..27fec4da 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,8 +72,9 @@ 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):
- '''Compute build order for a triplet.'''
+ def get_artifact_object(self, repo_name, ref, filename):
+ '''Create an Artifact object representing the given triplet.'''
+
self.app.status(msg='Figuring out the right build order')
self.app.status(msg='Creating source pool', chatty=True)
@@ -96,9 +97,9 @@ class BuildCommand(object):
artifact.cache_id = self.ckc.get_cache_id(artifact)
self.app.status(msg='Computing build order', chatty=True)
- order = morphlib.buildorder.BuildOrder(artifacts)
+ root_artifact = self._find_root_artifact(artifacts)
- return order
+ return root_artifact
def _validate_cross_morphology_references(self, srcpool):
'''Perform validation across all morphologies involved in the build'''
@@ -158,24 +159,30 @@ class BuildCommand(object):
other.morphology['kind'],
wanted))
- def build_in_order(self, order):
+ def _find_root_artifact(self, artifacts):
+ '''Find the root artifact among a set of artifacts in a DAG.
+
+ It would be nice if the ArtifactResolver would return its results in a
+ more useful order to save us from needing to do this -- the root object
+ is known already since that's the one the user asked us to build.
+
+ '''
+
+ maybe = set(artifacts)
+ for a in artifacts:
+ for dep in a.dependencies:
+ if dep in maybe:
+ maybe.remove(dep)
+ assert len(maybe) == 1
+ return maybe.pop()
+
+ 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 +294,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/buildorder.py b/morphlib/buildorder.py
deleted file mode 100644
index 39b53f05..00000000
--- a/morphlib/buildorder.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (C) 2012 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
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-import cliapp
-import collections
-
-
-class CyclicDependencyChainError(cliapp.AppException):
-
- def __init__(self):
- cliapp.AppException.__init__(
- self, 'Cyclic dependency chain detected')
-
-
-class BuildOrder:
-
- def __init__(self, artifacts):
- self.artifacts = artifacts
-
- if artifacts:
- sorting = self._compute_reverse_topological_sorting(artifacts)
- self.groups = self._create_build_groups(sorting)
- else:
- self.groups = []
-
- def _compute_reverse_topological_sorting(self, artifacts):
- '''Computes a reverse topological sorting of the build graph.
-
- A reverse topological sorting basically is the result of a series of
- breadth-first searches starting at each leaf node (artifacts with no
- dependents). Artifacts are added to the sorting as soon as all their
- dependents have been added.
-
- For more information, see
- http://en.wikipedia.org/wiki/Topological_sorting.
-
- '''
-
- # map artifacts to sets of satisfied dependents. this is to detect
- # when we can actually add artifacts to the BFS queue. rather than
- # dropping links between nodes, like most topological sorting
- # algorithms do, we simply remember all satisfied dependents and
- # check if all of them are met repeatedly
- satisfied_dependents = {}
-
- # create an empty sorting
- sorting = collections.deque()
-
- # create a set of leafs to start the DFS from
- leafs = collections.deque()
- for artifact in artifacts:
- satisfied_dependents[artifact] = set()
- if len(artifact.dependents) == 0:
- leafs.append(artifact)
-
- while len(leafs) > 0:
- # fetch a leaf artifact from the DFS queue
- artifact = leafs.popleft()
-
- # add it to the sorting
- sorting.append(artifact)
-
- # mark this dependency as resolved in dependent artifacts
- for dependency in artifact.dependencies:
- satisfied_dependents[dependency].add(artifact)
-
- # add the dependent blob as a leaf if all
- # its dependents have been resolved
- has = len(satisfied_dependents[dependency])
- needs = len(dependency.dependents)
- if has == needs:
- leafs.append(dependency)
-
- # if not all dependencies were resolved on the way, we
- # have found at least one cyclic dependency
- if len(sorting) < len(artifacts):
- raise CyclicDependencyChainError()
-
- return sorting
-
- def _create_build_groups(self, sorting):
- groups = collections.deque()
-
- if sorting:
- # create the last group
- group = []
- groups.append(group)
-
- # traverse the build graph in reverse topological order
- for artifact in sorting:
- # add artifact to a group that comes as late in the build order
- # as possible; if the first group contains any dependents,
- # add the artifact to a new group at the beginning of the order
- for group in groups:
- if not any([x in group for x in artifact.dependents]):
- group.append(artifact)
- break
- else:
- group = []
- group.append(artifact)
- groups.appendleft(group)
- break
-
- return groups
diff --git a/morphlib/buildorder_tests.py b/morphlib/buildorder_tests.py
deleted file mode 100644
index ab1a7e1c..00000000
--- a/morphlib/buildorder_tests.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Copyright (C) 2012 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
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-import unittest
-
-import morphlib
-
-
-class FakeSource(object):
- pass
-
-
-class BuildOrderTests(unittest.TestCase):
-
- def test_empty_list_results_in_no_groups_at_all(self):
- order = morphlib.buildorder.BuildOrder([])
- self.assertEqual(len(order.groups), 0)
-
- def test_list_with_one_artifact_results_in_one_group(self):
- chunk = FakeSource()
- artifact = morphlib.artifact.Artifact(chunk, 'chunk')
-
- order = morphlib.buildorder.BuildOrder([artifact])
-
- self.assertEqual(len(order.groups), 1)
- self.assertEqual(order.groups[0], [artifact])
-
- def test_list_with_two_unrelated_artifacts_results_in_one_group(self):
- chunk1 = FakeSource()
- artifact1 = morphlib.artifact.Artifact(chunk1, 'chunk1')
-
- chunk2 = FakeSource()
- artifact2 = morphlib.artifact.Artifact(chunk2, 'chunk2')
-
- order = morphlib.buildorder.BuildOrder([artifact1, artifact2])
-
- self.assertEqual(len(order.groups), 1)
- self.assertEqual(order.groups[0], [artifact1, artifact2])
-
- def test_list_with_two_dependent_artifacts_results_in_two_groups(self):
- chunk1 = FakeSource()
- artifact1 = morphlib.artifact.Artifact(chunk1, 'chunk1')
-
- chunk2 = FakeSource()
- artifact2 = morphlib.artifact.Artifact(chunk2, 'chunk2')
- artifact2.add_dependency(artifact1)
-
- order = morphlib.buildorder.BuildOrder([artifact1, artifact2])
-
- self.assertEqual(len(order.groups), 2)
- self.assertEqual(order.groups[0], [artifact1])
- self.assertEqual(order.groups[1], [artifact2])
-
- def test_chain_of_three_dependent_artifacts_results_in_three_groups(self):
- chunk1 = FakeSource()
- artifact1 = morphlib.artifact.Artifact(chunk1, 'chunk1')
-
- chunk2 = FakeSource()
- artifact2 = morphlib.artifact.Artifact(chunk2, 'chunk2')
- artifact2.add_dependency(artifact1)
-
- chunk3 = FakeSource()
- artifact3 = morphlib.artifact.Artifact(chunk3, 'chunk3')
- artifact3.add_dependency(artifact2)
-
- order = morphlib.buildorder.BuildOrder(
- [artifact1, artifact2, artifact3])
-
- self.assertEqual(len(order.groups), 3)
- self.assertEqual(order.groups[0], [artifact1])
- self.assertEqual(order.groups[1], [artifact2])
- self.assertEqual(order.groups[2], [artifact3])
-
- def test_two_artifacts_depending_on_another_results_in_two_groups(self):
- chunk1 = FakeSource()
- artifact1 = morphlib.artifact.Artifact(chunk1, 'chunk1')
-
- chunk2 = FakeSource()
- artifact2 = morphlib.artifact.Artifact(chunk2, 'chunk2')
- artifact2.add_dependency(artifact1)
-
- chunk3 = FakeSource()
- artifact3 = morphlib.artifact.Artifact(chunk3, 'chunk3')
- artifact3.add_dependency(artifact1)
-
- order = morphlib.buildorder.BuildOrder(
- [artifact1, artifact2, artifact3])
-
- self.assertEqual(len(order.groups), 2)
- self.assertEqual(order.groups[0], [artifact1])
- self.assertEqual(order.groups[1], [artifact2, artifact3])
-
- def test_one_artifact_depending_on_two_others_results_in_two_groups(self):
- chunk1 = FakeSource()
- artifact1 = morphlib.artifact.Artifact(chunk1, 'chunk1')
-
- chunk2 = FakeSource()
- artifact2 = morphlib.artifact.Artifact(chunk2, 'chunk2')
-
- chunk3 = FakeSource()
- artifact3 = morphlib.artifact.Artifact(chunk3, 'chunk3')
- artifact3.add_dependency(artifact1)
- artifact3.add_dependency(artifact2)
-
- order = morphlib.buildorder.BuildOrder(
- [artifact1, artifact2, artifact3])
-
- self.assertEqual(len(order.groups), 2)
- self.assertEqual(order.groups[0], [artifact1, artifact2])
- self.assertEqual(order.groups[1], [artifact3])
-
- def test_detection_of_cyclic_dependency_chain(self):
- chunk1 = FakeSource()
- artifact1 = morphlib.artifact.Artifact(chunk1, 'chunk1')
-
- chunk2 = FakeSource()
- artifact2 = morphlib.artifact.Artifact(chunk2, 'chunk2')
-
- chunk3 = FakeSource()
- artifact3 = morphlib.artifact.Artifact(chunk3, 'chunk3')
-
- artifact1.add_dependency(artifact3)
- artifact2.add_dependency(artifact1)
- artifact3.add_dependency(artifact2)
-
- self.assertRaises(morphlib.buildorder.CyclicDependencyChainError,
- morphlib.buildorder.BuildOrder,
- [artifact1, artifact2, artifact3])
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')
+
diff --git a/morphlib/plugins/show_dependencies_plugin.py b/morphlib/plugins/show_dependencies_plugin.py
index 13ec512a..e4e40311 100644
--- a/morphlib/plugins/show_dependencies_plugin.py
+++ b/morphlib/plugins/show_dependencies_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
@@ -46,27 +46,19 @@ class ShowDependenciesPlugin(cliapp.Plugin):
self.app.settings['cache-server'], repo_resolver)
else:
rrc = None
+
+ build_command = morphlib.buildcommand.BuildCommand(self.app)
# traverse the morphs to list all the sources
for repo, ref, filename in self.app.itertriplets(args):
morph = filename[:-len('.morph')]
- pool = self.app.create_source_pool(
- lrc, rrc, (repo, ref, filename))
-
- resolver = morphlib.artifactresolver.ArtifactResolver()
- artifacts = resolver.resolve_artifacts(pool)
-
self.app.output.write('dependency graph for %s|%s|%s:\n' %
(repo, ref, morph))
- for artifact in sorted(artifacts, key=str):
+
+ artifact = build_command.get_artifact_object(repo, ref, filename)
+
+ for artifact in reversed(artifact.walk()):
self.app.output.write(' %s\n' % artifact)
for dependency in sorted(artifact.dependencies, key=str):
self.app.output.write(' -> %s\n' % dependency)
- order = morphlib.buildorder.BuildOrder(artifacts)
- self.app.output.write('build order for %s|%s|%s:\n' %
- (repo, ref, morph))
- for group in order.groups:
- self.app.output.write(' group:\n')
- for artifact in group:
- self.app.output.write(' %s\n' % artifact)
diff --git a/tests/show-dependencies.stdout b/tests/show-dependencies.stdout
index e58f5285..84ed3ba6 100644
--- a/tests/show-dependencies.stdout
+++ b/tests/show-dependencies.stdout
@@ -1,54 +1,4 @@
dependency graph for test-repo|master|xfce-core:
- test-repo|master|cairo|cairo
- test-repo|master|dbus-glib|dbus-glib
- -> test-repo|master|dbus|dbus
- -> test-repo|master|glib|glib
- test-repo|master|dbus|dbus
- test-repo|master|exo|exo
- -> test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|libxfce4util|libxfce4util
- test-repo|master|fontconfig|fontconfig
- test-repo|master|freetype|freetype
- test-repo|master|garcon|garcon
- -> test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|libxfce4util|libxfce4util
- test-repo|master|gdk-pixbuf|gdk-pixbuf
- -> test-repo|master|glib|glib
- test-repo|master|glib|glib
- test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|cairo|cairo
- -> test-repo|master|dbus-glib|dbus-glib
- -> test-repo|master|dbus|dbus
- -> test-repo|master|fontconfig|fontconfig
- -> test-repo|master|freetype|freetype
- -> test-repo|master|gdk-pixbuf|gdk-pixbuf
- -> test-repo|master|glib|glib
- -> test-repo|master|gtk|gtk
- -> test-repo|master|pango|pango
- test-repo|master|gtk-xfce-engine|gtk-xfce-engine
- -> test-repo|master|garcon|garcon
- -> test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|libxfce4ui|libxfce4ui
- -> test-repo|master|xfconf|xfconf
- test-repo|master|gtk|gtk
- -> test-repo|master|cairo|cairo
- -> test-repo|master|gdk-pixbuf|gdk-pixbuf
- -> test-repo|master|glib|glib
- -> test-repo|master|pango|pango
- test-repo|master|libxfce4ui|libxfce4ui
- -> test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|xfconf|xfconf
- test-repo|master|libxfce4util|libxfce4util
- -> test-repo|master|gtk-stack|gtk-stack
- test-repo|master|pango|pango
- -> test-repo|master|fontconfig|fontconfig
- -> test-repo|master|freetype|freetype
- test-repo|master|thunar|thunar
- -> test-repo|master|exo|exo
- -> test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|libxfce4ui|libxfce4ui
- test-repo|master|tumbler|tumbler
- -> test-repo|master|gtk-stack|gtk-stack
test-repo|master|xfce-core|xfce-core
-> test-repo|master|exo|exo
-> test-repo|master|garcon|garcon
@@ -65,16 +15,24 @@ dependency graph for test-repo|master|xfce-core:
-> test-repo|master|xfconf|xfconf
-> test-repo|master|xfdesktop|xfdesktop
-> test-repo|master|xfwm4|xfwm4
- test-repo|master|xfce4-appfinder|xfce4-appfinder
+ test-repo|master|gtk-xfce-engine|gtk-xfce-engine
-> test-repo|master|garcon|garcon
-> test-repo|master|gtk-stack|gtk-stack
-> test-repo|master|libxfce4ui|libxfce4ui
-> test-repo|master|xfconf|xfconf
- test-repo|master|xfce4-panel|xfce4-panel
- -> test-repo|master|exo|exo
+ test-repo|master|xfce4-appfinder|xfce4-appfinder
-> test-repo|master|garcon|garcon
-> test-repo|master|gtk-stack|gtk-stack
-> test-repo|master|libxfce4ui|libxfce4ui
+ -> test-repo|master|xfconf|xfconf
+ test-repo|master|xfdesktop|xfdesktop
+ -> test-repo|master|gtk-stack|gtk-stack
+ -> test-repo|master|libxfce4ui|libxfce4ui
+ -> test-repo|master|xfconf|xfconf
+ test-repo|master|xfwm4|xfwm4
+ -> test-repo|master|gtk-stack|gtk-stack
+ -> test-repo|master|libxfce4ui|libxfce4ui
+ -> test-repo|master|xfconf|xfconf
test-repo|master|xfce4-session|xfce4-session
-> test-repo|master|exo|exo
-> test-repo|master|gtk-stack|gtk-stack
@@ -85,49 +43,56 @@ dependency graph for test-repo|master|xfce-core:
-> test-repo|master|gtk-stack|gtk-stack
-> test-repo|master|libxfce4ui|libxfce4ui
-> test-repo|master|xfconf|xfconf
- test-repo|master|xfconf|xfconf
- -> test-repo|master|gtk-stack|gtk-stack
- -> test-repo|master|libxfce4util|libxfce4util
- test-repo|master|xfdesktop|xfdesktop
+ test-repo|master|xfce4-panel|xfce4-panel
+ -> test-repo|master|exo|exo
+ -> test-repo|master|garcon|garcon
-> test-repo|master|gtk-stack|gtk-stack
-> test-repo|master|libxfce4ui|libxfce4ui
- -> test-repo|master|xfconf|xfconf
- test-repo|master|xfwm4|xfwm4
+ test-repo|master|tumbler|tumbler
+ -> test-repo|master|gtk-stack|gtk-stack
+ test-repo|master|thunar|thunar
+ -> test-repo|master|exo|exo
-> test-repo|master|gtk-stack|gtk-stack
-> test-repo|master|libxfce4ui|libxfce4ui
+ test-repo|master|garcon|garcon
+ -> test-repo|master|gtk-stack|gtk-stack
+ -> test-repo|master|libxfce4util|libxfce4util
+ test-repo|master|exo|exo
+ -> test-repo|master|gtk-stack|gtk-stack
+ -> test-repo|master|libxfce4util|libxfce4util
+ test-repo|master|libxfce4ui|libxfce4ui
+ -> test-repo|master|gtk-stack|gtk-stack
-> test-repo|master|xfconf|xfconf
-build order for test-repo|master|xfce-core:
- group:
- test-repo|master|glib|glib
- test-repo|master|freetype|freetype
- test-repo|master|fontconfig|fontconfig
- group:
- test-repo|master|cairo|cairo
- test-repo|master|gdk-pixbuf|gdk-pixbuf
- test-repo|master|pango|pango
- test-repo|master|dbus|dbus
- group:
- test-repo|master|gtk|gtk
- test-repo|master|dbus-glib|dbus-glib
- group:
- test-repo|master|gtk-stack|gtk-stack
- group:
- test-repo|master|libxfce4util|libxfce4util
- group:
- test-repo|master|xfconf|xfconf
- group:
- test-repo|master|exo|exo
- test-repo|master|libxfce4ui|libxfce4ui
- test-repo|master|garcon|garcon
- group:
- test-repo|master|thunar|thunar
- test-repo|master|tumbler|tumbler
- test-repo|master|xfce4-panel|xfce4-panel
- test-repo|master|xfce4-settings|xfce4-settings
- test-repo|master|xfce4-session|xfce4-session
- test-repo|master|xfwm4|xfwm4
- test-repo|master|xfdesktop|xfdesktop
- test-repo|master|xfce4-appfinder|xfce4-appfinder
- test-repo|master|gtk-xfce-engine|gtk-xfce-engine
- group:
- test-repo|master|xfce-core|xfce-core
+ test-repo|master|xfconf|xfconf
+ -> test-repo|master|gtk-stack|gtk-stack
+ -> test-repo|master|libxfce4util|libxfce4util
+ test-repo|master|libxfce4util|libxfce4util
+ -> test-repo|master|gtk-stack|gtk-stack
+ test-repo|master|gtk-stack|gtk-stack
+ -> test-repo|master|cairo|cairo
+ -> test-repo|master|dbus-glib|dbus-glib
+ -> test-repo|master|dbus|dbus
+ -> test-repo|master|fontconfig|fontconfig
+ -> test-repo|master|freetype|freetype
+ -> test-repo|master|gdk-pixbuf|gdk-pixbuf
+ -> test-repo|master|glib|glib
+ -> test-repo|master|gtk|gtk
+ -> test-repo|master|pango|pango
+ test-repo|master|dbus-glib|dbus-glib
+ -> test-repo|master|dbus|dbus
+ -> test-repo|master|glib|glib
+ test-repo|master|dbus|dbus
+ test-repo|master|gtk|gtk
+ -> test-repo|master|cairo|cairo
+ -> test-repo|master|gdk-pixbuf|gdk-pixbuf
+ -> test-repo|master|glib|glib
+ -> test-repo|master|pango|pango
+ test-repo|master|gdk-pixbuf|gdk-pixbuf
+ -> test-repo|master|glib|glib
+ test-repo|master|glib|glib
+ test-repo|master|pango|pango
+ -> test-repo|master|fontconfig|fontconfig
+ -> test-repo|master|freetype|freetype
+ test-repo|master|cairo|cairo
+ test-repo|master|fontconfig|fontconfig
+ test-repo|master|freetype|freetype