[gnome-continuous] build.gnome.org: Add a dependency graph to the detailed view
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-continuous] build.gnome.org: Add a dependency graph to the detailed view
- Date: Tue, 13 Sep 2016 17:15:57 +0000 (UTC)
commit f4006a332797e134cf366879c10dd61e27f15c13
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Mon Sep 12 21:40:53 2016 -0400
build.gnome.org: Add a dependency graph to the detailed view
To someone new to build.gnome.org, the tasks and how they relate
to each other can be a bit obscure. Add a graph that shows how
the tasks relate to each other and the current state of the build
to the top of the detailed view.
.../DejaVuSansMono-graph-subset.woff | Bin 0 -> 12968 bytes
extras/build.gnome.org/README.DejaVu | 111 +++++++++++
extras/build.gnome.org/app.css | 48 +++++-
extras/build.gnome.org/app.js | 1 +
extras/build.gnome.org/controllers.js | 13 ++-
extras/build.gnome.org/depgraph.js | 200 ++++++++++++++++++++
extras/build.gnome.org/index.html | 1 +
.../partials/gnome-continuous-build.html | 2 +
8 files changed, 374 insertions(+), 2 deletions(-)
---
diff --git a/extras/build.gnome.org/DejaVuSansMono-graph-subset.woff
b/extras/build.gnome.org/DejaVuSansMono-graph-subset.woff
new file mode 100644
index 0000000..4a5ad36
Binary files /dev/null and b/extras/build.gnome.org/DejaVuSansMono-graph-subset.woff differ
diff --git a/extras/build.gnome.org/README.DejaVu b/extras/build.gnome.org/README.DejaVu
new file mode 100644
index 0000000..a4f32a8
--- /dev/null
+++ b/extras/build.gnome.org/README.DejaVu
@@ -0,0 +1,111 @@
+DejaVuSansMono-graph-subset.ttf is a subsetted version of DejaVuSansMono,
+with the license as below.
+
+The subsetting was done with:
+
+ pyftsubset DejaVuSansMono.ttf \
+ --output-file=DejaVuSansMono-graph-subset.woff --flavor=woff \
+ --unicodes=U+0020-007F,U+00A0,U+2501,U+2503,U+2517,U+2523,U+2533
+
+License
+=======
+
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
+
+Bitstream Vera Fonts Copyright
+------------------------------
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
+a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation files (the "Font Software"), to reproduce and distribute the
+Font Software, including without limitation the rights to use, copy, merge,
+publish, distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission notice shall
+be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional glyphs or characters may be added to the Fonts, only if the fonts
+are renamed to names not containing either the words "Bitstream" or the word
+"Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream
+Vera" names.
+
+The Font Software may be sold as part of a larger software package but no
+copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this Font Software
+without prior written authorization from the Gnome Foundation or Bitstream
+Inc., respectively. For further information, contact: fonts at gnome dot
+org.
+
+Arev Fonts Copyright
+------------------------------
+
+Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the fonts accompanying this license ("Fonts") and
+associated documentation files (the "Font Software"), to reproduce
+and distribute the modifications to the Bitstream Vera Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be included in all copies of one or more of the Font Software
+typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may be
+modified and additional glyphs or characters may be added to the
+Fonts, only if the fonts are renamed to names not containing either
+the words "Tavmjong Bah" or the word "Arev".
+
+This License becomes null and void to the extent applicable to Fonts
+or Font Software that has been modified and is distributed under the
+"Tavmjong Bah Arev" names.
+
+The Font Software may be sold as part of a larger software package but
+no copy of one or more of the Font Software typefaces may be sold by
+itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the name of Tavmjong Bah shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in this Font Software without prior written authorization
+from Tavmjong Bah. For further information, contact: tavmjong @ free
+. fr.
+
+$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
diff --git a/extras/build.gnome.org/app.css b/extras/build.gnome.org/app.css
index 6252eb6..7b1a6ca 100644
--- a/extras/build.gnome.org/app.css
+++ b/extras/build.gnome.org/app.css
@@ -55,4 +55,50 @@ body {
.app.bad .emblem {
background-image: url(images/app-bad.png);
-}
\ No newline at end of file
+}
+
+@font-face{
+ font-family: 'DepGraphSubsetFont';
+ src: url('DejaVuSansMono-graph-subset.woff');
+}
+
+.task-dep-graph {
+ white-space: pre;
+ font-family: DejaVu Sans Mono, DepGraphSubsetFont, monospace;
+ font-size: 10px;
+ line-height: 100%;
+ margin-top: 20px;
+ margin-bottom: 5px;
+}
+
+.graph-task, .graph-hidden {
+ border: 1px solid black;
+ border-radius: 3px;
+ font-size: 10px;
+ padding: 4px;
+ padding-bottom: 2px;
+ vertical-align: middle;
+ margin-left: 3px;
+ margin-right: 3px;
+}
+
+.graph-hidden {
+ visibility: hidden;
+}
+
+.graph-inter-row {
+ line-height: 10px;
+}
+
+.graph-pad {
+ font-size: 10px;
+ vertical-align: middle;
+}
+
+.graph-connector {
+ vertical-align: middle;
+}
+
+.graph-success { background: #dff0d8; }
+.graph-failed { background: #f2dede; }
+.graph-running { background: #c0d0f2; }
diff --git a/extras/build.gnome.org/app.js b/extras/build.gnome.org/app.js
index 5f7c1e9..7d28211 100644
--- a/extras/build.gnome.org/app.js
+++ b/extras/build.gnome.org/app.js
@@ -4,6 +4,7 @@
var bgo = angular.module('build.gnome.org', [
'ngRoute',
'bgoControllers',
+ 'bgoDepGraph',
]);
bgo.config(['$routeProvider', function($routeProvider) {
diff --git a/extras/build.gnome.org/controllers.js b/extras/build.gnome.org/controllers.js
index 4296725..61da460 100644
--- a/extras/build.gnome.org/controllers.js
+++ b/extras/build.gnome.org/controllers.js
@@ -3,7 +3,7 @@
var bgoControllers = angular.module('bgoControllers', []);
- var taskNames = ['resolve', 'bdiff', 'build', 'builddisks', 'smoketest', 'smoketest-classic',
'smoketest-wayland', 'smoketest-timed', 'integrationtest','applicationstest', ];
+ var taskNames = ['resolve', 'bdiff', 'build', 'builddisks', 'zdisks', 'smoketest', 'smoketest-classic',
'smoketest-wayland', 'smoketest-timed', 'integrationtest','applicationstest', ];
var ROOT = '/continuous/buildmaster/';
@@ -84,6 +84,7 @@
var stages = [];
var tasks = [];
+ var taskStates = {};
taskNames.forEach(function(taskName) {
$http.get(buildRoot + taskName + '/meta.json').success(function(data) {
@@ -155,6 +156,15 @@
});
}
tasks.push(data);
+
+ if (data['complete']) {
+ if (data['success'])
+ taskStates[taskName] = 'success';
+ else
+ taskStates[taskName] = 'failed';
+ } else {
+ taskStates[taskName] = 'running';
+ }
}).error(function(data, status, headers, config) {
data = {};
data['name'] = taskName;
@@ -167,6 +177,7 @@
return tasks.filter(function(item){ return item.name == name })
};
$scope.tasks = tasks;
+ $scope.taskStates = taskStates;
});
function reversedOrder(a, b) {return parseInt(b)-parseInt(a)}
diff --git a/extras/build.gnome.org/depgraph.js b/extras/build.gnome.org/depgraph.js
new file mode 100644
index 0000000..67b0b04
--- /dev/null
+++ b/extras/build.gnome.org/depgraph.js
@@ -0,0 +1,200 @@
+/* This module implements a graph that shows the dependencies between
+ * the components. Instead of using SVG or something like that, the
+ * graph is done as fixed-width text and box-drawing characters with
+ * CSS layered on top to make it look reasonable.
+ *
+ * Having this work depends on having a fixed-width font with bold
+ * box-drawing characters. 'DejaVu Sans Mono' is a freely available
+ * such font; an appropriate subset of it is included here and specified
+ * in the CSS as a fallback.
+ *
+ * Copyright: Red Hat, Inc. 2016
+ * Author: Owen Taylor <otaylor fishsoup net>
+ * License: MIT
+ */
+(function(exports) {
+ 'use strict';
+
+ var bgoDepGraph = angular.module('bgoDepGraph', []);
+
+ var CONN_RL = "\u2501\u2501\u2501";
+ var CONN_RL_SINGLE = "\u2501";
+ var CONN_RBL = "\u2501\u2533\u2501";
+ var CONN_TB = "\u00a0\u2503\u00a0";
+ var CONN_TR = "\u00a0\u2517\u2501";
+ var CONN_TRD = "\u00a0\u2523\u2501";
+ var CONN_NONE = "\u00a0\u00a0\u00a0";
+ var CONN_NONE_SINGLE = "\u00a0";
+
+ function DepGraph(taskRoots, taskChildren) {
+ this.taskRoots = taskRoots;
+ this.taskChildren = taskChildren;
+ this.connectors = [];
+ this.cells = [];
+ this.columnWidths = [];
+ this.nRows = 0;
+ this.nColumns = 0;
+
+ var i;
+ for (i = 0; i < this.taskRoots.length; i++)
+ this._findColumnWidth(this.taskRoots[i], 0);
+
+ this.columnHeights = new Array(this.nColumns);
+ for (i = 0; i < this.nColumns; i++)
+ this.columnHeights[i] = 0;
+
+ for (i = 0; i < this.taskRoots.length; i++)
+ this._place(this.taskRoots[i], 0, 0);
+ }
+
+ DepGraph.prototype._findColumnWidth = function(task, depth) {
+ if (depth >= this.nColumns) {
+ this.columnWidths.push(task.length);
+ this.nColumns++;
+ } else {
+ this.columnWidths[depth] = Math.max(this.columnWidths[depth], task.length);
+ }
+ var children = this.taskChildren[task];
+ for (var i = 0; i < children.length; i++)
+ this._findColumnWidth(children[i], depth + 1);
+ }
+
+ DepGraph.prototype._place = function(task, depth, parentY) {
+ var children = this.taskChildren[task];
+ var ypos = Math.max(parentY, this.columnHeights[depth]);
+ if (children.length > 0) {
+ ypos = this._place(children[0], depth + 1, ypos);
+ this.connectors[ypos][depth] = (children.length == 1) ? LR: CONN_RBL;
+ }
+
+ this.columnHeights[depth] = ypos + 1;
+ var connectorPos = ypos + 1;
+ for (var i = 1; i < children.length; i++) {
+ var newY = this._place(children[i], depth + 1, ypos);
+ while (connectorPos < newY)
+ this.connectors[connectorPos++][depth] = CONN_TB;
+ this.connectors[connectorPos++][depth] = (children.length == i + 1) ? CONN_TR : CONN_TRD;
+ }
+
+ if (ypos + 1 >= this.nRows) {
+ this.cells.push(new Array(this.nColumns));
+ this.connectors.push(new Array(this.nColumns));
+ this.nRows++;
+ }
+ this.cells[ypos][depth] = task;
+
+ return ypos;
+ }
+
+ function _repeat(str, width) {
+ var res = "";
+ for (var i = 0; i < width; i++)
+ res += str;
+ return res;
+ }
+
+ DepGraph.prototype.update = function(element, taskStates) {
+ // Not supported in angularjs-1.2 jqLite
+ // element.empty();
+ var e = element[0];
+ while (e.lastChild)
+ e.removeChild(e.lastChild);
+
+ var i, j;
+
+ var output = "";
+ for (j = 0; j < this.nRows; j++) {
+ var row = this.cells[j];
+ var rowConnectors = this.connectors[j];
+ for (i = 0; i < this.nColumns; i++) {
+ var pad;
+ var span = document.createElement("span");
+ if (row[i] !== undefined) {
+ span.appendChild(document.createTextNode(row[i]));
+ if (row[i] in taskStates)
+ span.className = "graph-task " + "graph-" + taskStates[row[i]];
+ else
+ span.className = "graph-task";
+ pad = this.columnWidths[i] - row[i].length;
+ } else {
+ span.appendChild(document.createTextNode(_repeat(" ", this.columnWidths[i])));
+ span.className = "graph-hidden";
+ pad = 0;
+ }
+ element.append(span);
+ if (pad > 0) {
+ var padSpan = document.createElement("span");
+ padSpan.className = "graph-pad";
+ if (rowConnectors[i] == CONN_RL || rowConnectors[i] == CONN_RBL)
+ padSpan.appendChild(document.createTextNode(_repeat(CONN_RL_SINGLE, pad)));
+ else
+ padSpan.appendChild(document.createTextNode(_repeat(CONN_NONE_SINGLE, pad)));
+ element.append(padSpan);
+ }
+ var connector = rowConnectors[i] !== undefined ? rowConnectors[i] : CONN_NONE;
+ var connectorSpan = document.createElement("span");
+ connectorSpan.className = 'graph-connector';
+ connectorSpan.appendChild(document.createTextNode(connector));
+ element.append(connectorSpan);
+ }
+ element.append(document.createTextNode("\n"));
+ if (j != this.nRows - 1) {
+ var rowSpan = document.createElement("span");
+ rowSpan.className = "graph-inter-row";
+ for (i = 0; i < this.nColumns; i++) {
+ var span = document.createElement("span");
+ span.appendChild(document.createTextNode(_repeat(CONN_NONE_SINGLE,
this.columnWidths[i])));
+ span.className = "graph-hidden";
+ rowSpan.appendChild(span);
+ var connector;
+ if (rowConnectors[i] == CONN_TB || rowConnectors[i] == CONN_RBL || rowConnectors[i] ==
CONN_TRD)
+ connector = CONN_TB;
+ else
+ connector = CONN_NONE;
+ var connectorSpan = document.createElement("span");
+ connectorSpan.className = 'graph-connector';
+ connectorSpan.appendChild(document.createTextNode(connector));
+ rowSpan.appendChild(connectorSpan);
+ }
+ rowSpan.appendChild(document.createTextNode("\n"));
+ element.append(rowSpan);
+ }
+ }
+ }
+
+ var graph = new DepGraph(["resolve"],
+ {
+ resolve: ["build", "bdiff"],
+ build: ["builddisks", "zdisks"],
+ bdiff: [],
+ builddisks: ["smoketest", "smoketest-classic", "smoketest-wayland",
"smoketest-timed"],
+ zdisks: [],
+ smoketest: ["applicationstest", "integrationtest", "memusage"],
+ 'smoketest-classic': [],
+ 'smoketest-wayland': [],
+ 'smoketest-timed': [],
+ applicationstest: [],
+ integrationtest: [],
+ memusage: []
+ });
+
+ bgoDepGraph.directive('depGraph', function() {
+ function link(scope, element, attrs) {
+ var taskStates;
+
+ function updateGraph() {
+ graph.update(element, taskStates);
+ }
+
+ scope.$watch(attrs.depGraph, function(value) {
+ taskStates = value;
+ updateGraph();
+ }, true);
+ }
+
+ return {
+ link: link
+ };
+ });
+})(window);
+
diff --git a/extras/build.gnome.org/index.html b/extras/build.gnome.org/index.html
index 55aba6a..d0ff40e 100644
--- a/extras/build.gnome.org/index.html
+++ b/extras/build.gnome.org/index.html
@@ -10,6 +10,7 @@
<script src="angular-route.min.js"></script>
<script src="app.js"></script>
<script src="controllers.js"></script>
+ <script src="depgraph.js"></script>
</head>
<body>
<div class='navbar-header container-fluid navbar navbar-inverse navbar-fixed-top'>
diff --git a/extras/build.gnome.org/partials/gnome-continuous-build.html
b/extras/build.gnome.org/partials/gnome-continuous-build.html
index 70f8c92..c8793da 100644
--- a/extras/build.gnome.org/partials/gnome-continuous-build.html
+++ b/extras/build.gnome.org/partials/gnome-continuous-build.html
@@ -1,5 +1,7 @@
<article>
<h2>Build {{ buildVersion }}</h2>
+ <div dep-graph="taskStates" class="task-dep-graph">
+ </div>
<ul class="list-group">
<li class='list-group-item ng-scope'>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]