| 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 |