~ubuntu-branches/ubuntu/lucid/jhbuild/lucid

« back to all changes in this revision

Viewing changes to jhbuild/buildbot/status/web/__init__.py

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort, Loic Minier, Emilio Pozuelo Monfort
  • Date: 2009-11-09 20:28:48 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20091109202848-m9ec7dmzptqtchtj
Tags: 2.28.0-1
[ Loic Minier ]
* Cleanups.
* Ship scripts.
* Don't set GNOME_MODULE as it equals the name of the source package.

[ Emilio Pozuelo Monfort ]
* New upstream release. Closes: #524504.
  - Use 'git rev-parse' rather than 'git-rev-parse'. Closes: #544642.
* Ship install-check. Closes: #441008.
* Uploaders list regenerated. Closes: #523542, #554071.
* debian/control.in,
  debian/rules:
  - Stop shipping a copy of subprocess.py. Require python >= 2.4.
  - Switch to python-support.
* debian/control.in:
  - Bump Standards-Version to 3.8.3, no changes needed.
  - Build depend on intltool >= 0.35.0.
  - Build depend on pkg-config, gnome-doc-utils and rarian-compat to build
    the documentation.
  - Make jhbuild arch any since install-check is a binary. Depend on
    ${shlibs:Depends}.
  - Recommend, and not suggest, git-core. Also recommend mercurial.
* debian/watch:
  - Added.
* debian/patches/01_import_from_pkgdatadir.patch:
  - Added, import jhbuild from pkgdatadir if everything else fails.
    This way we can ship the jhbuild private modules in /usr/sharejhbuild.
* debian/jhbuild.docs:
  - Removed, the necessary docs are now installed by the upstream Makefile.
* debian/rules:
  - Include autotools.mk and gnome.mk.
  - Remove all the manual build process, autotools.mk does everything now.
  - Install the jhbuild modules in /usr/share/jhbuild.
* debian/install:
  - Install the modulesets and patches from here since the upstream build
    system doesn't install them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# jhbuild - a build script for GNOME 1.x and 2.x
 
2
# Copyright (C) 2008  apinheiro@igalia.com, John Carr, Frederic Peters
 
3
#
 
4
#   __init__.py: custom buildbot web pages
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2 of the License, or
 
9
# (at your option) any later version.
 
10
#
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with this program; if not, write to the Free Software
 
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
 
20
import os
 
21
 
 
22
from twisted.web import server, static, resource
 
23
from buildbot.status.web.base import HtmlResource, ITopBox, build_get_class
 
24
from buildbot import interfaces, util
 
25
from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, EXCEPTION
 
26
from buildbot.status.web.baseweb import WebStatus
 
27
 
 
28
from waterfall import JhWaterfallStatusResource
 
29
from changes import  ChangesResource
 
30
from builder import JhBuildersResource
 
31
from bot import JhBuildbotsResource
 
32
 
 
33
 
 
34
def content(self, request):
 
35
    """
 
36
    We want to give /all/ HTMLResource objects this replacement content method
 
37
    Monkey patch :)
 
38
    """
 
39
    s = request.site.buildbot_service
 
40
    data = s.template
 
41
    data = data.replace('@@GNOME_BUILDBOT_TITLE@@', self.getTitle(request))
 
42
    data = data.replace('@@GNOME_BUILDBOT_BODY@@', self.body(request))
 
43
    return data
 
44
HtmlResource.content = content
 
45
 
 
46
class ProjectsSummary(HtmlResource):
 
47
 
 
48
    MAX_PROJECT_NAME = 25
 
49
 
 
50
    def getTitle(self, request):
 
51
        status = self.getStatus(request)
 
52
        p = status.getProjectName()
 
53
        return p
 
54
 
 
55
    def body(self, request):
 
56
        parent = request.site.buildbot_service
 
57
        status = self.getStatus(request)
 
58
 
 
59
        result = ''
 
60
        result += '<table class="ProjectSummary">\n'
 
61
 
 
62
        # Headers
 
63
        slave_status = {}
 
64
        for slave in parent.slaves:
 
65
            for module in parent.modules:
 
66
                builder = status.getBuilder("%s-%s" % (module, slave))
 
67
                state, builds = builder.getState()
 
68
                if state == 'offline':
 
69
                    slave_status[slave] = ('offline', [])
 
70
                    break
 
71
                elif state == 'building':
 
72
                    if slave in slave_status:
 
73
                        modules = slave_status[slave][1] or []
 
74
                        slave_status[slave] = (state, modules + [module])
 
75
                    else:
 
76
                        slave_status[slave] = (state, [module])
 
77
            else:
 
78
                if not slave in slave_status:
 
79
                    slave_status[slave] = ('idle', None)
 
80
 
 
81
        result += '<thead><tr><td>&nbsp;</td><td>&nbsp;</td><th>' + parent.moduleset + '</td>'
 
82
        for name in parent.slaves:
 
83
            if len(name) > 25:
 
84
                name = name[:25] + '(...)'
 
85
            klass, modules = slave_status.get(name)
 
86
            if klass == 'building':
 
87
                title = 'Building %s' % ', '.join(modules)
 
88
            else:
 
89
                title = klass
 
90
            result += '<th class="%s" title="%s"><a href="bots/%s">%s</a></th>' % (
 
91
                    klass, title, name, name)
 
92
        result += '</tr>'
 
93
        thead = result
 
94
        # stop it here as a row with totals will be added here once every rows
 
95
        # have been handled
 
96
 
 
97
        # Contents
 
98
        result = '<tbody>'
 
99
 
 
100
        slave_results = {}
 
101
        for slave in parent.slaves:
 
102
            slave_results[slave] = [0, 0, 0]
 
103
 
 
104
        for module in parent.modules:
 
105
            result += '<tr>'
 
106
            result += '<td class="feed"><a href="%s/atom">' % module
 
107
            result += '<img src="/feed-atom.png" alt="Atom"></a></td>'
 
108
            result += '<td class="feed"><a href="%s/rss">' % module
 
109
            result += '<img src="/feed.png" alt="RSS"></a></td>\n'
 
110
            result += '<th><a href="%s">%s</a></td>' % (module, module)
 
111
 
 
112
            for slave in parent.slaves:
 
113
                builder = status.getBuilder("%s-%s" % (module, slave))
 
114
                box = ITopBox(builder).getBox(request)
 
115
                lastbuild = ''
 
116
                for bt in box.text:
 
117
                    if bt == 'successful' or bt == 'failed':
 
118
                        lastbuild = bt
 
119
 
 
120
                if lastbuild == 'successful':
 
121
                    last_build = builder.getLastFinishedBuild()
 
122
                    if last_build:
 
123
                        class_ = build_get_class(last_build)
 
124
                    else:
 
125
                        class_ = 'success'
 
126
                    lastbuild_label = 'Success'
 
127
                    if last_build and class_:
 
128
                        # use a different class/label if make check failed
 
129
                        steps = last_build.getSteps()
 
130
                        for step in reversed(steps):
 
131
                            if step.name.split()[-1] == 'check':
 
132
                                if step.results == WARNINGS:
 
133
                                    # make check failed
 
134
                                    class_ = 'failedchecks'
 
135
                                    lastbuild_label = 'Failed Checks'
 
136
                                break
 
137
                elif lastbuild == 'failed':
 
138
                    lastbuild_label = 'Failed'
 
139
                    last_build = builder.getLastFinishedBuild()
 
140
                    if last_build:
 
141
                        class_ = build_get_class(last_build)
 
142
                    else:
 
143
                        class_ = 'failure'
 
144
                else:
 
145
                    class_ = ''
 
146
                    lastbuild_label = lastbuild
 
147
                state, builds = builder.getState()
 
148
                if state == 'building':
 
149
                    result += '<td class="%s">%s</td>' % (state, state)
 
150
                else:
 
151
                    result += '<td class="%s">%s</td>' % (class_, lastbuild_label)
 
152
                
 
153
                if lastbuild in ('failed', 'successful'):
 
154
                    slave_results[slave][2] += 1
 
155
                    if class_ == 'failedchecks':
 
156
                        slave_results[slave][1] += 1
 
157
                    elif lastbuild == 'successful':
 
158
                        slave_results[slave][0] += 1
 
159
                        slave_results[slave][1] += 1
 
160
 
 
161
            result += '</tr>\n'
 
162
        result += '</tbody>\n'
 
163
        result += '<tfoot><tr class="totals"><td colspan="3"></td>'
 
164
        thead += '<tr class="totals"><td colspan="3"></td>'
 
165
        for slave in parent.slaves:
 
166
            td = '<td><span title="Successful builds">%s</span> '\
 
167
                      '<span title="(ignoring test suites failures)">(%s)</span> / '\
 
168
                      '<span title="Total">%s</span></td>' % tuple(slave_results[slave])
 
169
            thead += td
 
170
            result += td
 
171
        thead += '</tr>\n</thead>\n'
 
172
        result += '</tr></tfoot>\n'
 
173
        result += '</table>'
 
174
 
 
175
        return thead+result
 
176
 
 
177
class JHBuildWebStatus(WebStatus):
 
178
 
 
179
    def __init__(self, moduleset, modules, slaves, *args, **kwargs):
 
180
        WebStatus.__init__(self, *args, **kwargs)
 
181
        self.moduleset = moduleset
 
182
        self.modules = modules
 
183
        self.slaves = slaves
 
184
 
 
185
        # set up the per-module waterfalls
 
186
        for module in self.modules:
 
187
            self.putChild(module, JhWaterfallStatusResource(categories=[module]))
 
188
 
 
189
        # set the summary homepage
 
190
        self.putChild("", ProjectsSummary())
 
191
 
 
192
        # set custom changes pages
 
193
        self.putChild('changes', ChangesResource())
 
194
        self.putChild('builders', JhBuildersResource())
 
195
        self.putChild('bots', JhBuildbotsResource())
 
196
 
 
197
    def setupSite(self):
 
198
        WebStatus.setupSite(self)
 
199
 
 
200
        # load the template into memory
 
201
        self.template = open(os.path.join(self.parent.basedir, "template.html")).read()