Please clarify "pending" reporting at build.webkit.org/dashboard
[WebKit-https.git] / Tools / BuildSlaveSupport / build.webkit.org-config / public_html / dashboard / Scripts / Trac.js
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 Trac = function(baseURL)
27 {
28     BaseObject.call(this);
29
30     console.assert(baseURL);
31
32     this.baseURL = baseURL;
33     this.recordedCommits = []; // Will be sorted in ascending order.
34
35     this.update();
36     this.updateTimer = setInterval(this.update.bind(this), Trac.UpdateInterval);
37 };
38
39 BaseObject.addConstructorFunctions(Trac);
40
41 Trac.UpdateInterval = 45000; // 45 seconds
42
43 Trac.Event = {
44     NewCommitsRecorded: "new-commits-recorded"
45 };
46
47 Trac.prototype = {
48     constructor: Trac,
49     __proto__: BaseObject.prototype,
50
51     get latestRecordedRevisionNumber()
52     {
53         if (!this.recordedCommits.length)
54             return undefined;
55         return this.recordedCommits[this.recordedCommits.length - 1].revisionNumber;
56     },
57
58     revisionURL: function(revision)
59     {
60         return this.baseURL + "changeset/" + encodeURIComponent(revision);
61     },
62
63     _xmlTimelineURL: function()
64     {
65         return this.baseURL + "timeline?changeset=on&max=50&format=rss";
66     },
67
68     _convertCommitInfoElementToObject: function(doc, commitElement)
69     {
70         var link = doc.evaluate("./link", commitElement, null, XPathResult.STRING_TYPE).stringValue;
71         var revisionNumber = parseInt(/\d+$/.exec(link))
72
73         var title = doc.evaluate("./title", commitElement, null, XPathResult.STRING_TYPE).stringValue;
74         title = title.replace(/^Changeset \[\d+\]: /, "");
75         var author = doc.evaluate("./author", commitElement, null, XPathResult.STRING_TYPE).stringValue;
76         var date = doc.evaluate("./pubDate", commitElement, null, XPathResult.STRING_TYPE).stringValue;
77         date = new Date(Date.parse(date));
78         var description = doc.evaluate("./description", commitElement, null, XPathResult.STRING_TYPE).stringValue;
79
80         return {
81             revisionNumber: revisionNumber,
82             link: link,
83             title: title,
84             author: author,
85             date: date,
86             description: description
87         };
88     },
89
90     update: function()
91     {
92         loadXML(this._xmlTimelineURL(), function(dataDocument) {
93             var latestKnownRevision = 0;
94             if (this.recordedCommits.length)
95                 latestKnownRevision = this.recordedCommits[this.recordedCommits.length - 1].revisionNumber;
96
97             var newCommits = [];
98
99             var commitInfoElements = dataDocument.evaluate("/rss/channel/item", dataDocument, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
100             var commitInfoElement = undefined;
101             while (commitInfoElement = commitInfoElements.iterateNext()) {
102                 var commit = this._convertCommitInfoElementToObject(dataDocument, commitInfoElement);
103                 if (commit.revisionNumber == latestKnownRevision)
104                     break;
105                 newCommits.push(commit);
106             }
107             
108             if (!newCommits.length)
109                 return;
110
111             this.recordedCommits = this.recordedCommits.concat(newCommits.reverse());
112
113             this.dispatchEventToListeners(Trac.Event.NewCommitsRecorded, {newCommits: newCommits});
114         }.bind(this));
115     }
116 };