We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix bug: GitPoller is never activated on nine
 a851083 is not a part of this PR. 
I merge upstream/nine in my branch and this commit was added to this PR.

Fix bug: GitPoller is never activated on nine
 a851083 is not a part of this PR. 
I merge upstream/nine in my branch and this commit was added to this PR.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `master/buildbot/steps/trigger.py`
Content:
```
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
3 # License as published by the Free Software Foundation, version 2.
4 #
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
7 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
8 # details.
9 #
10 # You should have received a copy of the GNU General Public License along with
11 # this program; if not, write to the Free Software Foundation, Inc., 51
12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
13 #
14 # Copyright Buildbot Team Members
15 
16 from buildbot.process.buildstep import LoggingBuildStep, SUCCESS, FAILURE, EXCEPTION
17 from buildbot.process.properties import Properties
18 from buildbot.schedulers.triggerable import Triggerable
19 from twisted.python import log
20 from twisted.internet import defer
21 
22 class Trigger(LoggingBuildStep):
23     """I trigger a scheduler.Triggerable, to use one or more Builders as if
24     they were a single buildstep (like a subroutine call).
25     """
26     name = "trigger"
27 
28     renderables = [ 'set_properties', 'schedulerNames', 'sourceStamp' ]
29 
30     flunkOnFailure = True
31 
32     def __init__(self, schedulerNames=[], sourceStamp=None, updateSourceStamp=None, alwaysUseLatest=False,
33                  waitForFinish=False, set_properties={}, copy_properties=[], **kwargs):
34         """
35         Trigger the given schedulers when this step is executed.
36 
37         @param schedulerNames: A list of scheduler names that should be
38                                triggered. Schedulers can be specified using
39                                WithProperties, if desired.
40 
41         @param sourceStamp: A dict containing the source stamp to use for the
42                             build. Keys must include branch, revision, repository and
43                             project. In addition, patch_body, patch_level, and
44                             patch_subdir can be specified. Only one of
45                             sourceStamp, updateSourceStamp and alwaysUseLatest
46                             can be specified. Any of these can be specified using
47                             WithProperties, if desired.
48 
49         @param updateSourceStamp: If True (the default), I will try to give
50                                   the schedulers an absolute SourceStamp for
51                                   their builds, so that a HEAD build will use
52                                   the same revision even if more changes have
53                                   occurred since my build's update step was
54                                   run. If False, I will use the original
55                                   SourceStamp unmodified.
56 
57         @param alwaysUseLatest: If False (the default), I will give the
58                                 SourceStamp of the current build to the
59                                 schedulers (as controled by updateSourceStamp).
60                                 If True, I will give the schedulers  an empty
61                                 SourceStamp, corresponding to the latest
62                                 revision.
63 
64         @param waitForFinish: If False (the default), this step will finish
65                               as soon as I've started the triggered
66                               schedulers. If True, I will wait until all of
67                               the triggered schedulers have finished their
68                               builds.
69 
70         @param set_properties: A dictionary of properties to set for any
71                                builds resulting from this trigger.  These
72                                properties will override properties set in the
73                                Triggered scheduler's constructor.
74 
75         @param copy_properties: a list of property names to copy verbatim
76                                 into any builds resulting from this trigger.
77 
78         """
79         assert schedulerNames, "You must specify a scheduler to trigger"
80         if sourceStamp and updateSourceStamp:
81             raise ValueError("You can't specify both sourceStamp and updateSourceStamp")
82         if sourceStamp and alwaysUseLatest:
83             raise ValueError("You can't specify both sourceStamp and alwaysUseLatest")
84         if alwaysUseLatest and updateSourceStamp:
85             raise ValueError("You can't specify both alwaysUseLatest and updateSourceStamp")
86         self.schedulerNames = schedulerNames
87         self.sourceStamp = sourceStamp
88         self.updateSourceStamp = updateSourceStamp or not (alwaysUseLatest or sourceStamp)
89         self.alwaysUseLatest = alwaysUseLatest
90         self.waitForFinish = waitForFinish
91         self.set_properties = set_properties
92         self.copy_properties = copy_properties
93         self.running = False
94         self.ended = False
95         LoggingBuildStep.__init__(self, **kwargs)
96         self.addFactoryArguments(schedulerNames=schedulerNames,
97                                  sourceStamp=sourceStamp,
98                                  updateSourceStamp=updateSourceStamp,
99                                  alwaysUseLatest=alwaysUseLatest,
100                                  waitForFinish=waitForFinish,
101                                  set_properties=set_properties,
102                                  copy_properties=copy_properties)
103 
104     def interrupt(self, reason):
105         if self.running:
106             self.step_status.setText(["interrupted"])
107             return self.end(EXCEPTION)
108 
109     def end(self, result):
110         if not self.ended:
111             self.ended = True
112             return self.finished(result)
113 
114     def start(self):
115         properties = self.build.getProperties()
116 
117         # make a new properties object from a dict rendered by the old 
118         # properties object
119         props_to_set = Properties()
120         props_to_set.update(self.set_properties, "Trigger")
121         for p in self.copy_properties:
122             if p not in properties:
123                 continue
124             props_to_set.setProperty(p, properties[p],
125                         "%s (in triggering build)" % properties.getPropertySource(p))
126 
127         self.running = True
128 
129         # (is there an easier way to find the BuildMaster?)
130         all_schedulers = self.build.builder.botmaster.parent.allSchedulers()
131         all_schedulers = dict([(sch.name, sch) for sch in all_schedulers])
132         unknown_schedulers = []
133         triggered_schedulers = []
134 
135         # TODO: don't fire any schedulers if we discover an unknown one
136         for scheduler in self.schedulerNames:
137             scheduler = scheduler
138             if all_schedulers.has_key(scheduler):
139                 sch = all_schedulers[scheduler]
140                 if isinstance(sch, Triggerable):
141                     triggered_schedulers.append(scheduler)
142                 else:
143                     unknown_schedulers.append(scheduler)
144             else:
145                 unknown_schedulers.append(scheduler)
146 
147         if unknown_schedulers:
148             self.step_status.setText(['no scheduler:'] + unknown_schedulers)
149             return self.end(FAILURE)
150 
151         master = self.build.builder.botmaster.parent # seriously?!
152         if self.sourceStamp:
153             d = master.db.sourcestamps.addSourceStamp(**self.sourceStamp)
154         elif self.alwaysUseLatest:
155             d = defer.succeed(None)
156         else:
157             ss = self.build.getSourceStamp()
158             if self.updateSourceStamp:
159                 got = properties.getProperty('got_revision')
160                 if got:
161                     ss = ss.getAbsoluteSourceStamp(got)
162             d = ss.getSourceStampId(master)
163         def start_builds(ssid):
164             dl = []
165             for scheduler in triggered_schedulers:
166                 sch = all_schedulers[scheduler]
167                 dl.append(sch.trigger(ssid, set_props=props_to_set))
168             self.step_status.setText(['triggered'] + triggered_schedulers)
169 
170             d = defer.DeferredList(dl, consumeErrors=1)
171             if self.waitForFinish:
172                 return d
173             else:
174                 # do something to handle errors
175                 d.addErrback(log.err,
176                         '(ignored) while invoking Triggerable schedulers:')
177                 self.end(SUCCESS)
178                 return None
179         d.addCallback(start_builds)
180 
181         def cb(rclist):
182             rc = SUCCESS # (this rc is not the same variable as that above)
183             for was_cb, results in rclist:
184                 # TODO: make this algo more configurable
185                 if not was_cb:
186                     rc = EXCEPTION
187                     log.err(results)
188                     break
189                 if results == FAILURE:
190                     rc = FAILURE
191             return self.end(rc)
192         def eb(why):
193             return self.end(FAILURE)
194 
195         if self.waitForFinish:
196             d.addCallbacks(cb, eb)
197 
198         d.addErrback(log.err, '(ignored) while triggering builds:')
199
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/master/buildbot/steps/trigger.py b/master/buildbot/steps/trigger.py
--- a/master/buildbot/steps/trigger.py
+++ b/master/buildbot/steps/trigger.py
@@ -77,15 +77,18 @@
 
         """
         assert schedulerNames, "You must specify a scheduler to trigger"
-        if sourceStamp and updateSourceStamp:
+        if sourceStamp and (updateSourceStamp is not None):
             raise ValueError("You can't specify both sourceStamp and updateSourceStamp")
         if sourceStamp and alwaysUseLatest:
             raise ValueError("You can't specify both sourceStamp and alwaysUseLatest")
-        if alwaysUseLatest and updateSourceStamp:
+        if alwaysUseLatest and (updateSourceStamp is not None):
             raise ValueError("You can't specify both alwaysUseLatest and updateSourceStamp")
         self.schedulerNames = schedulerNames
         self.sourceStamp = sourceStamp
-        self.updateSourceStamp = updateSourceStamp or not (alwaysUseLatest or sourceStamp)
+        if updateSourceStamp is not None:
+            self.updateSourceStamp = updateSourceStamp
+        else:
+            self.updateSourceStamp = not (alwaysUseLatest or sourceStamp)
         self.alwaysUseLatest = alwaysUseLatest
         self.waitForFinish = waitForFinish
         self.set_properties = set_properties

{"golden_diff": "diff --git a/master/buildbot/steps/trigger.py b/master/buildbot/steps/trigger.py\n--- a/master/buildbot/steps/trigger.py\n+++ b/master/buildbot/steps/trigger.py\n@@ -77,15 +77,18 @@\n \n         \"\"\"\n         assert schedulerNames, \"You must specify a scheduler to trigger\"\n-        if sourceStamp and updateSourceStamp:\n+        if sourceStamp and (updateSourceStamp is not None):\n             raise ValueError(\"You can't specify both sourceStamp and updateSourceStamp\")\n         if sourceStamp and alwaysUseLatest:\n             raise ValueError(\"You can't specify both sourceStamp and alwaysUseLatest\")\n-        if alwaysUseLatest and updateSourceStamp:\n+        if alwaysUseLatest and (updateSourceStamp is not None):\n             raise ValueError(\"You can't specify both alwaysUseLatest and updateSourceStamp\")\n         self.schedulerNames = schedulerNames\n         self.sourceStamp = sourceStamp\n-        self.updateSourceStamp = updateSourceStamp or not (alwaysUseLatest or sourceStamp)\n+        if updateSourceStamp is not None:\n+            self.updateSourceStamp = updateSourceStamp\n+        else:\n+            self.updateSourceStamp = not (alwaysUseLatest or sourceStamp)\n         self.alwaysUseLatest = alwaysUseLatest\n         self.waitForFinish = waitForFinish\n         self.set_properties = set_properties\n", "issue": "Fix bug: GitPoller is never activated on nine\n a851083 is not a part of this PR. \nI merge upstream/nine in my branch and this commit was added to this PR.\n\nFix bug: GitPoller is never activated on nine\n a851083 is not a part of this PR. \nI merge upstream/nine in my branch and this commit was added to this PR.\n\n", "before_files": [{"content": "# This file is part of Buildbot.  Buildbot is free software: you can\n# redistribute it and/or modify it under the terms of the GNU General Public\n# License as published by the Free Software Foundation, version 2.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\n# details.\n#\n# You should have received a copy of the GNU General Public License along with\n# this program; if not, write to the Free Software Foundation, Inc., 51\n# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Copyright Buildbot Team Members\n\nfrom buildbot.process.buildstep import LoggingBuildStep, SUCCESS, FAILURE, EXCEPTION\nfrom buildbot.process.properties import Properties\nfrom buildbot.schedulers.triggerable import Triggerable\nfrom twisted.python import log\nfrom twisted.internet import defer\n\nclass Trigger(LoggingBuildStep):\n    \"\"\"I trigger a scheduler.Triggerable, to use one or more Builders as if\n    they were a single buildstep (like a subroutine call).\n    \"\"\"\n    name = \"trigger\"\n\n    renderables = [ 'set_properties', 'schedulerNames', 'sourceStamp' ]\n\n    flunkOnFailure = True\n\n    def __init__(self, schedulerNames=[], sourceStamp=None, updateSourceStamp=None, alwaysUseLatest=False,\n                 waitForFinish=False, set_properties={}, copy_properties=[], **kwargs):\n        \"\"\"\n        Trigger the given schedulers when this step is executed.\n\n        @param schedulerNames: A list of scheduler names that should be\n                               triggered. Schedulers can be specified using\n                               WithProperties, if desired.\n\n        @param sourceStamp: A dict containing the source stamp to use for the\n                            build. Keys must include branch, revision, repository and\n                            project. In addition, patch_body, patch_level, and\n                            patch_subdir can be specified. Only one of\n                            sourceStamp, updateSourceStamp and alwaysUseLatest\n                            can be specified. Any of these can be specified using\n                            WithProperties, if desired.\n\n        @param updateSourceStamp: If True (the default), I will try to give\n                                  the schedulers an absolute SourceStamp for\n                                  their builds, so that a HEAD build will use\n                                  the same revision even if more changes have\n                                  occurred since my build's update step was\n                                  run. If False, I will use the original\n                                  SourceStamp unmodified.\n\n        @param alwaysUseLatest: If False (the default), I will give the\n                                SourceStamp of the current build to the\n                                schedulers (as controled by updateSourceStamp).\n                                If True, I will give the schedulers  an empty\n                                SourceStamp, corresponding to the latest\n                                revision.\n\n        @param waitForFinish: If False (the default), this step will finish\n                              as soon as I've started the triggered\n                              schedulers. If True, I will wait until all of\n                              the triggered schedulers have finished their\n                              builds.\n\n        @param set_properties: A dictionary of properties to set for any\n                               builds resulting from this trigger.  These\n                               properties will override properties set in the\n                               Triggered scheduler's constructor.\n\n        @param copy_properties: a list of property names to copy verbatim\n                                into any builds resulting from this trigger.\n\n        \"\"\"\n        assert schedulerNames, \"You must specify a scheduler to trigger\"\n        if sourceStamp and updateSourceStamp:\n            raise ValueError(\"You can't specify both sourceStamp and updateSourceStamp\")\n        if sourceStamp and alwaysUseLatest:\n            raise ValueError(\"You can't specify both sourceStamp and alwaysUseLatest\")\n        if alwaysUseLatest and updateSourceStamp:\n            raise ValueError(\"You can't specify both alwaysUseLatest and updateSourceStamp\")\n        self.schedulerNames = schedulerNames\n        self.sourceStamp = sourceStamp\n        self.updateSourceStamp = updateSourceStamp or not (alwaysUseLatest or sourceStamp)\n        self.alwaysUseLatest = alwaysUseLatest\n        self.waitForFinish = waitForFinish\n        self.set_properties = set_properties\n        self.copy_properties = copy_properties\n        self.running = False\n        self.ended = False\n        LoggingBuildStep.__init__(self, **kwargs)\n        self.addFactoryArguments(schedulerNames=schedulerNames,\n                                 sourceStamp=sourceStamp,\n                                 updateSourceStamp=updateSourceStamp,\n                                 alwaysUseLatest=alwaysUseLatest,\n                                 waitForFinish=waitForFinish,\n                                 set_properties=set_properties,\n                                 copy_properties=copy_properties)\n\n    def interrupt(self, reason):\n        if self.running:\n            self.step_status.setText([\"interrupted\"])\n            return self.end(EXCEPTION)\n\n    def end(self, result):\n        if not self.ended:\n            self.ended = True\n            return self.finished(result)\n\n    def start(self):\n        properties = self.build.getProperties()\n\n        # make a new properties object from a dict rendered by the old \n        # properties object\n        props_to_set = Properties()\n        props_to_set.update(self.set_properties, \"Trigger\")\n        for p in self.copy_properties:\n            if p not in properties:\n                continue\n            props_to_set.setProperty(p, properties[p],\n                        \"%s (in triggering build)\" % properties.getPropertySource(p))\n\n        self.running = True\n\n        # (is there an easier way to find the BuildMaster?)\n        all_schedulers = self.build.builder.botmaster.parent.allSchedulers()\n        all_schedulers = dict([(sch.name, sch) for sch in all_schedulers])\n        unknown_schedulers = []\n        triggered_schedulers = []\n\n        # TODO: don't fire any schedulers if we discover an unknown one\n        for scheduler in self.schedulerNames:\n            scheduler = scheduler\n            if all_schedulers.has_key(scheduler):\n                sch = all_schedulers[scheduler]\n                if isinstance(sch, Triggerable):\n                    triggered_schedulers.append(scheduler)\n                else:\n                    unknown_schedulers.append(scheduler)\n            else:\n                unknown_schedulers.append(scheduler)\n\n        if unknown_schedulers:\n            self.step_status.setText(['no scheduler:'] + unknown_schedulers)\n            return self.end(FAILURE)\n\n        master = self.build.builder.botmaster.parent # seriously?!\n        if self.sourceStamp:\n            d = master.db.sourcestamps.addSourceStamp(**self.sourceStamp)\n        elif self.alwaysUseLatest:\n            d = defer.succeed(None)\n        else:\n            ss = self.build.getSourceStamp()\n            if self.updateSourceStamp:\n                got = properties.getProperty('got_revision')\n                if got:\n                    ss = ss.getAbsoluteSourceStamp(got)\n            d = ss.getSourceStampId(master)\n        def start_builds(ssid):\n            dl = []\n            for scheduler in triggered_schedulers:\n                sch = all_schedulers[scheduler]\n                dl.append(sch.trigger(ssid, set_props=props_to_set))\n            self.step_status.setText(['triggered'] + triggered_schedulers)\n\n            d = defer.DeferredList(dl, consumeErrors=1)\n            if self.waitForFinish:\n                return d\n            else:\n                # do something to handle errors\n                d.addErrback(log.err,\n                        '(ignored) while invoking Triggerable schedulers:')\n                self.end(SUCCESS)\n                return None\n        d.addCallback(start_builds)\n\n        def cb(rclist):\n            rc = SUCCESS # (this rc is not the same variable as that above)\n            for was_cb, results in rclist:\n                # TODO: make this algo more configurable\n                if not was_cb:\n                    rc = EXCEPTION\n                    log.err(results)\n                    break\n                if results == FAILURE:\n                    rc = FAILURE\n            return self.end(rc)\n        def eb(why):\n            return self.end(FAILURE)\n\n        if self.waitForFinish:\n            d.addCallbacks(cb, eb)\n\n        d.addErrback(log.err, '(ignored) while triggering builds:')\n", "path": "master/buildbot/steps/trigger.py"}], "after_files": [{"content": "# This file is part of Buildbot.  Buildbot is free software: you can\n# redistribute it and/or modify it under the terms of the GNU General Public\n# License as published by the Free Software Foundation, version 2.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\n# details.\n#\n# You should have received a copy of the GNU General Public License along with\n# this program; if not, write to the Free Software Foundation, Inc., 51\n# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Copyright Buildbot Team Members\n\nfrom buildbot.process.buildstep import LoggingBuildStep, SUCCESS, FAILURE, EXCEPTION\nfrom buildbot.process.properties import Properties\nfrom buildbot.schedulers.triggerable import Triggerable\nfrom twisted.python import log\nfrom twisted.internet import defer\n\nclass Trigger(LoggingBuildStep):\n    \"\"\"I trigger a scheduler.Triggerable, to use one or more Builders as if\n    they were a single buildstep (like a subroutine call).\n    \"\"\"\n    name = \"trigger\"\n\n    renderables = [ 'set_properties', 'schedulerNames', 'sourceStamp' ]\n\n    flunkOnFailure = True\n\n    def __init__(self, schedulerNames=[], sourceStamp=None, updateSourceStamp=None, alwaysUseLatest=False,\n                 waitForFinish=False, set_properties={}, copy_properties=[], **kwargs):\n        \"\"\"\n        Trigger the given schedulers when this step is executed.\n\n        @param schedulerNames: A list of scheduler names that should be\n                               triggered. Schedulers can be specified using\n                               WithProperties, if desired.\n\n        @param sourceStamp: A dict containing the source stamp to use for the\n                            build. Keys must include branch, revision, repository and\n                            project. In addition, patch_body, patch_level, and\n                            patch_subdir can be specified. Only one of\n                            sourceStamp, updateSourceStamp and alwaysUseLatest\n                            can be specified. Any of these can be specified using\n                            WithProperties, if desired.\n\n        @param updateSourceStamp: If True (the default), I will try to give\n                                  the schedulers an absolute SourceStamp for\n                                  their builds, so that a HEAD build will use\n                                  the same revision even if more changes have\n                                  occurred since my build's update step was\n                                  run. If False, I will use the original\n                                  SourceStamp unmodified.\n\n        @param alwaysUseLatest: If False (the default), I will give the\n                                SourceStamp of the current build to the\n                                schedulers (as controled by updateSourceStamp).\n                                If True, I will give the schedulers  an empty\n                                SourceStamp, corresponding to the latest\n                                revision.\n\n        @param waitForFinish: If False (the default), this step will finish\n                              as soon as I've started the triggered\n                              schedulers. If True, I will wait until all of\n                              the triggered schedulers have finished their\n                              builds.\n\n        @param set_properties: A dictionary of properties to set for any\n                               builds resulting from this trigger.  These\n                               properties will override properties set in the\n                               Triggered scheduler's constructor.\n\n        @param copy_properties: a list of property names to copy verbatim\n                                into any builds resulting from this trigger.\n\n        \"\"\"\n        assert schedulerNames, \"You must specify a scheduler to trigger\"\n        if sourceStamp and (updateSourceStamp is not None):\n            raise ValueError(\"You can't specify both sourceStamp and updateSourceStamp\")\n        if sourceStamp and alwaysUseLatest:\n            raise ValueError(\"You can't specify both sourceStamp and alwaysUseLatest\")\n        if alwaysUseLatest and (updateSourceStamp is not None):\n            raise ValueError(\"You can't specify both alwaysUseLatest and updateSourceStamp\")\n        self.schedulerNames = schedulerNames\n        self.sourceStamp = sourceStamp\n        if updateSourceStamp is not None:\n            self.updateSourceStamp = updateSourceStamp\n        else:\n            self.updateSourceStamp = not (alwaysUseLatest or sourceStamp)\n        self.alwaysUseLatest = alwaysUseLatest\n        self.waitForFinish = waitForFinish\n        self.set_properties = set_properties\n        self.copy_properties = copy_properties\n        self.running = False\n        self.ended = False\n        LoggingBuildStep.__init__(self, **kwargs)\n        self.addFactoryArguments(schedulerNames=schedulerNames,\n                                 sourceStamp=sourceStamp,\n                                 updateSourceStamp=updateSourceStamp,\n                                 alwaysUseLatest=alwaysUseLatest,\n                                 waitForFinish=waitForFinish,\n                                 set_properties=set_properties,\n                                 copy_properties=copy_properties)\n\n    def interrupt(self, reason):\n        if self.running:\n            self.step_status.setText([\"interrupted\"])\n            return self.end(EXCEPTION)\n\n    def end(self, result):\n        if not self.ended:\n            self.ended = True\n            return self.finished(result)\n\n    def start(self):\n        properties = self.build.getProperties()\n\n        # make a new properties object from a dict rendered by the old \n        # properties object\n        props_to_set = Properties()\n        props_to_set.update(self.set_properties, \"Trigger\")\n        for p in self.copy_properties:\n            if p not in properties:\n                continue\n            props_to_set.setProperty(p, properties[p],\n                        \"%s (in triggering build)\" % properties.getPropertySource(p))\n\n        self.running = True\n\n        # (is there an easier way to find the BuildMaster?)\n        all_schedulers = self.build.builder.botmaster.parent.allSchedulers()\n        all_schedulers = dict([(sch.name, sch) for sch in all_schedulers])\n        unknown_schedulers = []\n        triggered_schedulers = []\n\n        # TODO: don't fire any schedulers if we discover an unknown one\n        for scheduler in self.schedulerNames:\n            scheduler = scheduler\n            if all_schedulers.has_key(scheduler):\n                sch = all_schedulers[scheduler]\n                if isinstance(sch, Triggerable):\n                    triggered_schedulers.append(scheduler)\n                else:\n                    unknown_schedulers.append(scheduler)\n            else:\n                unknown_schedulers.append(scheduler)\n\n        if unknown_schedulers:\n            self.step_status.setText(['no scheduler:'] + unknown_schedulers)\n            return self.end(FAILURE)\n\n        master = self.build.builder.botmaster.parent # seriously?!\n        if self.sourceStamp:\n            d = master.db.sourcestamps.addSourceStamp(**self.sourceStamp)\n        elif self.alwaysUseLatest:\n            d = defer.succeed(None)\n        else:\n            ss = self.build.getSourceStamp()\n            if self.updateSourceStamp:\n                got = properties.getProperty('got_revision')\n                if got:\n                    ss = ss.getAbsoluteSourceStamp(got)\n            d = ss.getSourceStampId(master)\n        def start_builds(ssid):\n            dl = []\n            for scheduler in triggered_schedulers:\n                sch = all_schedulers[scheduler]\n                dl.append(sch.trigger(ssid, set_props=props_to_set))\n            self.step_status.setText(['triggered'] + triggered_schedulers)\n\n            d = defer.DeferredList(dl, consumeErrors=1)\n            if self.waitForFinish:\n                return d\n            else:\n                # do something to handle errors\n                d.addErrback(log.err,\n                        '(ignored) while invoking Triggerable schedulers:')\n                self.end(SUCCESS)\n                return None\n        d.addCallback(start_builds)\n\n        def cb(rclist):\n            rc = SUCCESS # (this rc is not the same variable as that above)\n            for was_cb, results in rclist:\n                # TODO: make this algo more configurable\n                if not was_cb:\n                    rc = EXCEPTION\n                    log.err(results)\n                    break\n                if results == FAILURE:\n                    rc = FAILURE\n            return self.end(rc)\n        def eb(why):\n            return self.end(FAILURE)\n\n        if self.waitForFinish:\n            d.addCallbacks(cb, eb)\n\n        d.addErrback(log.err, '(ignored) while triggering builds:')\n", "path": "master/buildbot/steps/trigger.py"}]}