0.7.10 release changes
[buildbot.git] / buildbot / buildset.py
blobfe59f74ace2ca35ed68a4b9170671409deacc087
1 from buildbot.process import base
2 from buildbot.status import builder
3 from buildbot.process.properties import Properties
6 class BuildSet:
7 """I represent a set of potential Builds, all of the same source tree,
8 across a specified list of Builders. I can represent a build of a
9 specific version of the source tree (named by source.branch and
10 source.revision), or a build of a certain set of Changes
11 (source.changes=list)."""
13 def __init__(self, builderNames, source, reason=None, bsid=None,
14 properties=None):
15 """
16 @param source: a L{buildbot.sourcestamp.SourceStamp}
17 """
18 self.builderNames = builderNames
19 self.source = source
20 self.reason = reason
22 self.properties = Properties()
23 if properties: self.properties.updateFromProperties(properties)
25 self.stillHopeful = True
26 self.status = bss = builder.BuildSetStatus(source, reason,
27 builderNames, bsid)
29 def waitUntilSuccess(self):
30 return self.status.waitUntilSuccess()
31 def waitUntilFinished(self):
32 return self.status.waitUntilFinished()
34 def start(self, builders):
35 """This is called by the BuildMaster to actually create and submit
36 the BuildRequests."""
37 self.requests = []
38 reqs = []
40 # create the requests
41 for b in builders:
42 req = base.BuildRequest(self.reason, self.source, b.name,
43 properties=self.properties)
44 reqs.append((b, req))
45 self.requests.append(req)
46 d = req.waitUntilFinished()
47 d.addCallback(self.requestFinished, req)
49 # tell our status about them
50 req_statuses = [req.status for req in self.requests]
51 self.status.setBuildRequestStatuses(req_statuses)
53 # now submit them
54 for b,req in reqs:
55 b.submitBuildRequest(req)
57 def requestFinished(self, buildstatus, req):
58 # TODO: this is where individual build status results are aggregated
59 # into a BuildSet-wide status. Consider making a rule that says one
60 # WARNINGS results in the overall status being WARNINGS too. The
61 # current rule is that any FAILURE means FAILURE, otherwise you get
62 # SUCCESS.
63 self.requests.remove(req)
64 results = buildstatus.getResults()
65 if results == builder.FAILURE:
66 self.status.setResults(results)
67 if self.stillHopeful:
68 # oh, cruel reality cuts deep. no joy for you. This is the
69 # first failure. This flunks the overall BuildSet, so we can
70 # notify success watchers that they aren't going to be happy.
71 self.stillHopeful = False
72 self.status.giveUpHope()
73 self.status.notifySuccessWatchers()
74 if not self.requests:
75 # that was the last build, so we can notify finished watchers. If
76 # we haven't failed by now, we can claim success.
77 if self.stillHopeful:
78 self.status.setResults(builder.SUCCESS)
79 self.status.notifySuccessWatchers()
80 self.status.notifyFinishedWatchers()