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