OLD | NEW |
1 # This file is part of Buildbot. Buildbot is free software: you can | 1 # This file is part of Buildbot. Buildbot is free software: you can |
2 # redistribute it and/or modify it under the terms of the GNU General Public | 2 # redistribute it and/or modify it under the terms of the GNU General Public |
3 # License as published by the Free Software Foundation, version 2. | 3 # License as published by the Free Software Foundation, version 2. |
4 # | 4 # |
5 # This program is distributed in the hope that it will be useful, but WITHOUT | 5 # This program is distributed in the hope that it will be useful, but WITHOUT |
6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | 7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
8 # details. | 8 # details. |
9 # | 9 # |
10 # You should have received a copy of the GNU General Public License along with | 10 # You should have received a copy of the GNU General Public License along with |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 self.date = change.getTime() | 151 self.date = change.getTime() |
152 self.revlink = getattr(change, 'revlink', None) | 152 self.revlink = getattr(change, 'revlink', None) |
153 self.when = change.when | 153 self.when = change.when |
154 self.repository = change.repository | 154 self.repository = change.repository |
155 self.project = change.project | 155 self.project = change.project |
156 | 156 |
157 | 157 |
158 class DevBuild: | 158 class DevBuild: |
159 """Helper class that contains all the information we need for a build.""" | 159 """Helper class that contains all the information we need for a build.""" |
160 | 160 |
161 def __init__(self, revision, build, details, inProgressResults=None, | 161 def __init__(self, revision, build, details, inProgressResults=None): |
162 revisions=[]): | |
163 self.revision = revision | 162 self.revision = revision |
164 self.results = build.getResults() | 163 self.results = build.getResults() |
165 self.number = build.getNumber() | 164 self.number = build.getNumber() |
166 self.isFinished = build.isFinished() | 165 self.isFinished = build.isFinished() |
167 self.text = build.getText() | 166 self.text = build.getText() |
168 self.eta = build.getETA() | 167 self.eta = build.getETA() |
169 self.details = details | 168 self.details = details |
170 self.when = build.getTimes()[0] | 169 self.when = build.getTimes()[0] |
171 self.source = build.getSourceStamp() | 170 self.source = build.getSourceStamp() |
172 self.inProgressResults = inProgressResults | 171 self.inProgressResults = inProgressResults |
173 for rev in revisions: | |
174 if rev.revision == revision: | |
175 self.when = rev.when | |
176 break | |
177 | 172 |
178 | 173 |
179 class ConsoleStatusResource(HtmlResource): | 174 class ConsoleStatusResource(HtmlResource): |
180 """Main console class. It displays a user-oriented status page. | 175 """Main console class. It displays a user-oriented status page. |
181 Every change is a line in the page, and it shows the result of the first | 176 Every change is a line in the page, and it shows the result of the first |
182 build with this change for each slave.""" | 177 build with this change for each slave.""" |
183 | 178 |
184 def __init__(self, orderByTime=False, repository=None, | 179 def __init__(self, orderByTime=False, repository=None, |
185 builder_filter_fn=lambda builderName: True): | 180 builder_filter_fn=lambda builderName: True): |
186 HtmlResource.__init__(self) | 181 HtmlResource.__init__(self) |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 logurl = request.childLink( | 309 logurl = request.childLink( |
315 "../builders/%s/builds/%s/steps/%s/logs/%s" % | 310 "../builders/%s/builds/%s/steps/%s/logs/%s" % |
316 (urllib.quote(builderName, safe=''), | 311 (urllib.quote(builderName, safe=''), |
317 build.getNumber(), | 312 build.getNumber(), |
318 urllib.quote(name, safe=''), | 313 urllib.quote(name, safe=''), |
319 urllib.quote(logname, safe=''))) | 314 urllib.quote(logname, safe=''))) |
320 logs.append(dict(url=logurl, name=logname)) | 315 logs.append(dict(url=logurl, name=logname)) |
321 return details | 316 return details |
322 | 317 |
323 def getBuildsForRevision(self, request, builder, builderName, lastRevision, | 318 def getBuildsForRevision(self, request, builder, builderName, lastRevision, |
324 numBuilds, debugInfo, revisions): | 319 numBuilds, debugInfo): |
325 """Return the list of all the builds for a given builder that we will | 320 """Return the list of all the builds for a given builder that we will |
326 need to be able to display the console page. We start by the most recent | 321 need to be able to display the console page. We start by the most recent |
327 build, and we go down until we find a build that was built prior to the | 322 build, and we go down until we find a build that was built prior to the |
328 last change we are interested in.""" | 323 last change we are interested in.""" |
329 | 324 |
330 revision = lastRevision | 325 revision = lastRevision |
331 | 326 |
332 builds = [] | 327 builds = [] |
333 build = self.getHeadBuild(builder) | 328 build = self.getHeadBuild(builder) |
334 number = 0 | 329 number = 0 |
(...skipping 20 matching lines...) Expand all Loading... |
355 except: | 350 except: |
356 pass | 351 pass |
357 | 352 |
358 # We ignore all builds that don't have last revisions. | 353 # We ignore all builds that don't have last revisions. |
359 # TODO(nsylvain): If the build is over, maybe it was a problem | 354 # TODO(nsylvain): If the build is over, maybe it was a problem |
360 # with the update source step. We need to find a way to tell the | 355 # with the update source step. We need to find a way to tell the |
361 # user that his change might have broken the source update. | 356 # user that his change might have broken the source update. |
362 if got_rev and got_rev != -1: | 357 if got_rev and got_rev != -1: |
363 details = self.getBuildDetails(request, builderName, build) | 358 details = self.getBuildDetails(request, builderName, build) |
364 devBuild = DevBuild(got_rev, build, details, | 359 devBuild = DevBuild(got_rev, build, details, |
365 getInProgressResults(build), revisions) | 360 getInProgressResults(build)) |
366 builds.append(devBuild) | 361 builds.append(devBuild) |
367 | 362 |
368 # Now break if we have enough builds. | 363 # Now break if we have enough builds. |
369 current_revision = self.getChangeForBuild( | 364 current_revision = self.getChangeForBuild( |
370 build, revision) | 365 build, revision) |
371 if self.comparator.isRevisionEarlier( | 366 if self.comparator.isRevisionEarlier( |
372 devBuild, current_revision): | 367 devBuild, current_revision): |
373 break | 368 break |
374 | 369 |
375 build = build.getPreviousBuild() | 370 build = build.getPreviousBuild() |
376 | 371 |
377 return builds | 372 return builds |
378 | 373 |
379 def getChangeForBuild(self, build, revision): | 374 def getChangeForBuild(self, build, revision): |
380 if not build or not build.getChanges(): # Forced build | 375 if not build or not build.getChanges(): # Forced build |
381 return DevBuild(revision, build, None) | 376 return DevBuild(revision, build, None) |
382 | 377 |
383 for change in build.getChanges(): | 378 for change in build.getChanges(): |
384 if change.revision == revision: | 379 if change.revision == revision: |
385 return change | 380 return change |
386 | 381 |
387 # No matching change, return the last change in build. | 382 # No matching change, return the last change in build. |
388 changes = list(build.getChanges()) | 383 changes = list(build.getChanges()) |
389 changes.sort(key=self.comparator.getSortingKey()) | 384 changes.sort(key=self.comparator.getSortingKey()) |
390 return changes[-1] | 385 return changes[-1] |
391 | 386 |
392 def getAllBuildsForRevision(self, status, request, lastRevision, numBuilds, | 387 def getAllBuildsForRevision(self, status, request, lastRevision, numBuilds, |
393 categories, builders, debugInfo, revisions): | 388 categories, builders, debugInfo): |
394 """Returns a dictionary of builds we need to inspect to be able to | 389 """Returns a dictionary of builds we need to inspect to be able to |
395 display the console page. The key is the builder name, and the value is | 390 display the console page. The key is the builder name, and the value is |
396 an array of build we care about. We also returns a dictionary of | 391 an array of build we care about. We also returns a dictionary of |
397 builders we care about. The key is it's category. | 392 builders we care about. The key is it's category. |
398 | 393 |
399 lastRevision is the last revision we want to display in the page. | 394 lastRevision is the last revision we want to display in the page. |
400 categories is a list of categories to display. It is coming from the | 395 categories is a list of categories to display. It is coming from the |
401 HTTP GET parameters. | 396 HTTP GET parameters. |
402 builders is a list of builders to display. It is coming from the HTTP | 397 builders is a list of builders to display. It is coming from the HTTP |
403 GET parameters. | 398 GET parameters. |
(...skipping 30 matching lines...) Expand all Loading... |
434 builderList[category] = [] | 429 builderList[category] = [] |
435 | 430 |
436 # Append this builder to the dictionary of builders. | 431 # Append this builder to the dictionary of builders. |
437 builderList[category].append(builderName) | 432 builderList[category].append(builderName) |
438 # Set the list of builds for this builder. | 433 # Set the list of builds for this builder. |
439 allBuilds[builderName] = self.getBuildsForRevision(request, | 434 allBuilds[builderName] = self.getBuildsForRevision(request, |
440 builder, | 435 builder, |
441 builderName, | 436 builderName, |
442 lastRevision, | 437 lastRevision, |
443 numBuilds, | 438 numBuilds, |
444 debugInfo, | 439 debugInfo) |
445 revisions) | |
446 | 440 |
447 return (builderList, allBuilds) | 441 return (builderList, allBuilds) |
448 | 442 |
449 | 443 |
450 ## | 444 ## |
451 ## Display functions | 445 ## Display functions |
452 ## | 446 ## |
453 | 447 |
454 def displayCategories(self, builderList, debugInfo): | 448 def displayCategories(self, builderList, debugInfo): |
455 """Display the top category line.""" | 449 """Display the top category line.""" |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 if revisions: | 793 if revisions: |
800 lastRevision = revisions[len(revisions) - 1].revision | 794 lastRevision = revisions[len(revisions) - 1].revision |
801 debugInfo["last_revision"] = lastRevision | 795 debugInfo["last_revision"] = lastRevision |
802 | 796 |
803 (builderList, allBuilds) = self.getAllBuildsForRevision(status, | 797 (builderList, allBuilds) = self.getAllBuildsForRevision(status, |
804 request, | 798 request, |
805 lastRevision, | 799 lastRevision, |
806 numBuilds, | 800 numBuilds, |
807 categories, | 801 categories, |
808 builders, | 802 builders, |
809 debugInfo, | 803 debugInfo) |
810 revisions) | |
811 | 804 |
812 debugInfo["added_blocks"] = 0 | 805 debugInfo["added_blocks"] = 0 |
813 debugInfo["from_cache"] = 0 | 806 debugInfo["from_cache"] = 0 |
814 | 807 |
815 if request.args.get("display_cache", None): | 808 if request.args.get("display_cache", None): |
816 data = "" | 809 data = "" |
817 data += "\nGlobal Cache\n" | 810 data += "\nGlobal Cache\n" |
818 data += self.cache.display() | 811 data += self.cache.display() |
819 return data | 812 return data |
820 | 813 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 | 867 |
875 def isValidRevision(self, revision): | 868 def isValidRevision(self, revision): |
876 try: | 869 try: |
877 int(revision) | 870 int(revision) |
878 return True | 871 return True |
879 except: | 872 except: |
880 return False | 873 return False |
881 | 874 |
882 def getSortingKey(self): | 875 def getSortingKey(self): |
883 return operator.attrgetter('revision') | 876 return operator.attrgetter('revision') |
OLD | NEW |