1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /** Information about a particular build. */
6 function BuildInfo(json
) {
7 // Parse out the status message for the build.
9 if (json
.currentStep
) {
10 statusText
= 'running ' + json
.currentStep
.name
;
12 statusText
= json
.text
.join(' ');
15 // Determine what state the build is in.
17 if (statusText
.indexOf('exception') != -1) {
19 } else if (statusText
.indexOf('running') != -1) {
21 } else if (statusText
.indexOf('successful') != -1) {
23 } else if (statusText
.indexOf('failed') != -1) {
25 } else if (statusText
.indexOf('offline') != -1) {
27 } else if (statusText
.indexOf('warnings') != -1) {
33 var failures
= (state
== 'failed') ? this.parseFailures(json
) : null;
35 this.number
= json
.number
;
37 this.failures
= failures
;
38 this.statusText
= statusText
;
39 this.truncatedStatusText
= truncateStatusText(statusText
);
42 /** Save data about failed tests to perform blamelist intersections. */
43 BuildInfo
.prototype.parseFailures = function(json
) {
44 var revisionRange
= this.getRevisionRange(json
);
45 if (revisionRange
== null) return null;
48 var botName
= json
.builderName
;
49 for (var i
= 0; i
< json
.steps
.length
; ++i
) {
50 var step
= json
.steps
[i
];
51 var binaryName
= step
.name
;
52 if (step
.results
[0] != 0) { // Failed.
53 for (var j
= 0; j
< step
.logs
.length
; ++j
) {
54 var log
= step
.logs
[j
];
55 if (log
[0] == 'stdio')
57 var testName
= log
[0];
58 failures
.push([botName
, binaryName
, testName
, revisionRange
]);
67 * Get the revisions involved in a build. Sadly, this only works on Chromium's
68 * main builders because downstream trees provide git revision SHA1s through
69 * JSON instead of SVN numbers.
71 BuildInfo
.prototype.getRevisionRange = function(json
) {
72 if (json
.sourceStamp
.changes
.length
== 0) {
76 var lowest
= parseInt(json
.sourceStamp
.changes
[0].revision
, 10);
77 var highest
= parseInt(json
.sourceStamp
.changes
[0].revision
, 10);
78 for (var i
= 1; i
< json
.sourceStamp
.changes
.length
; ++i
) {
79 var rev
= parseInt(json
.sourceStamp
.changes
[i
].revision
, 10);
85 return [lowest
, highest
];
88 /** Creates HTML to display info about this build. */
89 BuildInfo
.prototype.createHtml = function(buildNumberCell
,
92 var fullStatusText
= 'Build ' + this.number
+ ':\n' + this.statusText
;
93 createBuildHtml(buildNumberCell
,
94 botUrl
+ '/builds/' + this.number
,
95 showFullInfo
? this.number
: null,
97 showFullInfo
? this.truncatedStatusText
: null,
101 /** Creates a table cell for a particular build number. */
102 function createBuildHtml(cellElement
,
108 // Create a link to the build results.
109 var linkElement
= document
.createElement('a');
110 linkElement
.href
= url
;
112 // Display either the build number (for the last completed build), or show the
113 // status of the step.
114 var buildIdentifierElement
= document
.createElement('span');
116 buildIdentifierElement
.className
= 'build-identifier';
117 buildIdentifierElement
.innerHTML
= buildNumber
;
119 buildIdentifierElement
.className
= 'build-letter';
120 buildIdentifierElement
.innerHTML
= buildState
.toUpperCase()[0];
122 linkElement
.appendChild(buildIdentifierElement
);
124 // Show the status of the build in truncated form so it doesn't take up the
126 if (truncatedStatusText
) {
127 var statusElement
= document
.createElement('span');
128 statusElement
.className
= 'build-status';
129 statusElement
.innerHTML
= truncatedStatusText
;
130 linkElement
.appendChild(statusElement
);
133 // Tack the cell onto the end of the row.
134 cellElement
.className
= buildState
;
135 cellElement
.title
= fullStatusText
;
136 cellElement
.appendChild(linkElement
);