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"""Interface documentation. 17 18Define the interfaces that are implemented by various buildbot classes. 19""" 20 21# disable pylint warnings triggered by interface definitions 22# pylint: disable=no-self-argument 23# pylint: disable=no-method-argument 24# pylint: disable=inherit-non-class 25 26from twisted.python.deprecate import deprecatedModuleAttribute 27from twisted.python.versions import Version 28from zope.interface import Attribute 29from zope.interface import Interface 30 31# exceptions that can be raised while trying to start a build 32 33 34class BuilderInUseError(Exception): 35 pass 36 37 38class WorkerSetupError(Exception): 39 pass 40 41 42WorkerTooOldError = WorkerSetupError 43deprecatedModuleAttribute( 44 Version("buildbot", 2, 9, 0), 45 message="Use WorkerSetupError instead.", 46 moduleName="buildbot.interfaces", 47 name="WorkerTooOldError", 48) 49 50 51class LatentWorkerFailedToSubstantiate(Exception): 52 pass 53 54 55class LatentWorkerCannotSubstantiate(Exception): 56 pass 57 58 59class LatentWorkerSubstantiatiationCancelled(Exception): 60 pass 61 62 63class IPlugin(Interface): 64 65 """ 66 Base interface for all Buildbot plugins 67 """ 68 69 70class IChangeSource(IPlugin): 71 72 """ 73 Service which feeds Change objects to the changemaster. When files or 74 directories are changed in version control, this object should represent 75 the changes as a change dictionary and call:: 76 77 self.master.data.updates.addChange(who=.., rev=.., ..) 78 79 See 'Writing Change Sources' in the manual for more information. 80 """ 81 master = Attribute('master', 82 'Pointer to BuildMaster, automatically set when started.') 83 84 def describe(): 85 """Return a string which briefly describes this source.""" 86 87 88class ISourceStamp(Interface): 89 90 """ 91 @cvar branch: branch from which source was drawn 92 @type branch: string or None 93 94 @cvar revision: revision of the source, or None to use CHANGES 95 @type revision: varies depending on VC 96 97 @cvar patch: patch applied to the source, or None if no patch 98 @type patch: None or tuple (level diff) 99 100 @cvar changes: the source step should check out the latest revision 101 in the given changes 102 @type changes: tuple of L{buildbot.changes.changes.Change} instances, 103 all of which are on the same branch 104 105 @cvar project: project this source code represents 106 @type project: string 107 108 @cvar repository: repository from which source was drawn 109 @type repository: string 110 """ 111 112 def canBeMergedWith(self, other): 113 """ 114 Can this SourceStamp be merged with OTHER? 115 """ 116 117 def mergeWith(self, others): 118 """Generate a SourceStamp for the merger of me and all the other 119 SourceStamps. This is called by a Build when it starts, to figure 120 out what its sourceStamp should be.""" 121 122 def getAbsoluteSourceStamp(self, got_revision): 123 """Get a new SourceStamp object reflecting the actual revision found 124 by a Source step.""" 125 126 def getText(self): 127 """Returns a list of strings to describe the stamp. These are 128 intended to be displayed in a narrow column. If more space is 129 available, the caller should join them together with spaces before 130 presenting them to the user.""" 131 132 133class IEmailSender(Interface): 134 135 """I know how to send email, and can be used by other parts of the 136 Buildbot to contact developers.""" 137 138 139class IEmailLookup(Interface): 140 141 def getAddress(user): 142 """Turn a User-name string into a valid email address. Either return 143 a string (with an @ in it), None (to indicate that the user cannot 144 be reached by email), or a Deferred which will fire with the same.""" 145 146 147class ILogObserver(Interface): 148 149 """Objects which provide this interface can be used in a BuildStep to 150 watch the output of a LogFile and parse it incrementally. 151 """ 152 153 # internal methods 154 def setStep(step): 155 pass 156 157 def setLog(log): 158 pass 159 160 # methods called by the LogFile 161 def logChunk(build, step, log, channel, text): 162 pass 163 164 165class IWorker(IPlugin): 166 # callback methods from the manager 167 pass 168 169 170class ILatentWorker(IWorker): 171 172 """A worker that is not always running, but can run when requested. 173 """ 174 substantiated = Attribute('Substantiated', 175 'Whether the latent worker is currently ' 176 'substantiated with a real instance.') 177 178 def substantiate(): 179 """Request that the worker substantiate with a real instance. 180 181 Returns a deferred that will callback when a real instance has 182 attached.""" 183 184 # there is an insubstantiate too, but that is not used externally ATM. 185 186 def buildStarted(wfb): 187 """Inform the latent worker that a build has started. 188 189 @param wfb: a L{LatentWorkerForBuilder}. The wfb is the one for whom the 190 build finished. 191 """ 192 193 def buildFinished(wfb): 194 """Inform the latent worker that a build has finished. 195 196 @param wfb: a L{LatentWorkerForBuilder}. The wfb is the one for whom the 197 build finished. 198 """ 199 200 201class IMachine(Interface): 202 pass 203 204 205class IMachineAction(Interface): 206 def perform(self, manager): 207 """ Perform an action on the machine managed by manager. Returns a 208 deferred evaluating to True if it was possible to execute the 209 action. 210 """ 211 212 213class ILatentMachine(IMachine): 214 """ A machine that is not always running, but can be started when requested. 215 """ 216 217 218class IRenderable(Interface): 219 220 """An object that can be interpolated with properties from a build. 221 """ 222 223 def getRenderingFor(iprops): 224 """Return a deferred that fires with interpolation with the given properties 225 226 @param iprops: the L{IProperties} provider supplying the properties. 227 """ 228 229 230class IProperties(Interface): 231 232 """ 233 An object providing access to build properties 234 """ 235 236 def getProperty(name, default=None): 237 """Get the named property, returning the default if the property does 238 not exist. 239 240 @param name: property name 241 @type name: string 242 243 @param default: default value (default: @code{None}) 244 245 @returns: property value 246 """ 247 248 def hasProperty(name): 249 """Return true if the named property exists. 250 251 @param name: property name 252 @type name: string 253 @returns: boolean 254 """ 255 256 def has_key(name): 257 """Deprecated name for L{hasProperty}.""" 258 259 def setProperty(name, value, source, runtime=False): 260 """Set the given property, overwriting any existing value. The source 261 describes the source of the value for human interpretation. 262 263 @param name: property name 264 @type name: string 265 266 @param value: property value 267 @type value: JSON-able value 268 269 @param source: property source 270 @type source: string 271 272 @param runtime: (optional) whether this property was set during the 273 build's runtime: usually left at its default value 274 @type runtime: boolean 275 """ 276 277 def getProperties(): 278 """Get the L{buildbot.process.properties.Properties} instance storing 279 these properties. Note that the interface for this class is not 280 stable, so where possible the other methods of this interface should be 281 used. 282 283 @returns: L{buildbot.process.properties.Properties} instance 284 """ 285 286 def getBuild(): 287 """Get the L{buildbot.process.build.Build} instance for the current 288 build. Note that this object is not available after the build is 289 complete, at which point this method will return None. 290 291 Try to avoid using this method, as the API of L{Build} instances is not 292 well-defined. 293 294 @returns L{buildbot.process.build.Build} instance 295 """ 296 297 def render(value): 298 """Render @code{value} as an L{IRenderable}. This essentially coerces 299 @code{value} to an L{IRenderable} and calls its @L{getRenderingFor} 300 method. 301 302 @name value: value to render 303 @returns: rendered value 304 """ 305 306 307class IScheduler(IPlugin): 308 pass 309 310 311class ITriggerableScheduler(Interface): 312 313 """ 314 A scheduler that can be triggered by buildsteps. 315 """ 316 317 def trigger(waited_for, sourcestamps=None, set_props=None, 318 parent_buildid=None, parent_relationship=None): 319 """Trigger a build with the given source stamp and properties. 320 """ 321 322 323class IBuildStepFactory(Interface): 324 325 def buildStep(): 326 pass 327 328 329class IBuildStep(IPlugin): 330 331 """ 332 A build step 333 """ 334 # Currently has nothing 335 336 337class IConfigured(Interface): 338 339 def getConfigDict(): 340 pass 341 342 343class IReportGenerator(Interface): 344 345 def generate(self, master, reporter, key, build): 346 pass 347 348 349class IConfigLoader(Interface): 350 351 def loadConfig(): 352 """ 353 Load the specified configuration. 354 355 :return MasterConfig: 356 """ 357 358 359class IHttpResponse(Interface): 360 361 def content(): 362 """ 363 :returns: raw (``bytes``) content of the response via deferred 364 """ 365 def json(): 366 """ 367 :returns: json decoded content of the response via deferred 368 """ 369 code = Attribute('code', 370 "http status code of the request's response (e.g 200)") 371 url = Attribute('url', 372 "request's url (e.g https://api.github.com/endpoint')") 373 374 375class IConfigurator(Interface): 376 377 def configure(config_dict): 378 """ 379 Alter the buildbot config_dict, as defined in master.cfg 380 381 like the master.cfg, this is run out of the main reactor thread, so this can block, but 382 this can't call most Buildbot facilities. 383 384 :returns: None 385 """ 386